INSTALL_FAILED_DUPLICATE_PERMISSION ... C2D_MESSAGE

时间:2014-11-20 15:57:31

标签: android google-cloud-messaging android-notifications android-5.0-lollipop

我在我的应用中使用Google通知,直到现在我在清单中完成了以下操作:

<!-- GCM -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Keeps the processor from sleeping when a message is received. --> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <!-- This app has permission to register and receive data message. --> 

<!-- Creates a custom permission so only this app can receive its messages. NOTE: APP_PACKAGE.permission.C2D_MESSAGE -->   
<permission android:name="com.myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.myapp.permission.C2D_MESSAGE" />    
<!-- END GCM -->

在我将Nexus 7更新到Android 5.0之前,它一直运行良好 现在,当我尝试使用Eclipse在此设备中安装应用程序时,出现此错误:

  

INSTALL_FAILED_DUPLICATE_PERMISSION perm = com.myapp.permission.C2D_MESSAGE pkg = com.myapp

我不明白有什么问题......它在Android 5.0之前完美运行 我知道我在两行C2D_MESSAGEpermission中使用uses-permission,但我已从原始Google GCM指南中复制了该代码,因此一定很好。

23 个答案:

答案 0 :(得分:223)

我找到了一个适合我的解决方案。

在我的设备(Nexus 7)Android 5.0中。棒棒糖我按照这些步骤。

卸载应用后您会在App Name标签的应用列表下找到Downloaded

  • 转到设置
  • 应用
  • 在列表底部,您会发现YourApp带有“未安装”标记
  • 打开
  • 点击OptionMenu并选择“为所有用户卸载”

在此过程之后,我成功安装了新应用,并且运行良好。

答案 1 :(得分:134)

删除

<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>

运行App ... 然后再次添加权限并运行App。

就绪!

答案 2 :(得分:47)

我在Android-21上的自定义签名权限遇到了同样的问题,并通过确保我完全卸载来解决它。

这是在以下情况下发生的边缘情况:

  1. 应用程序使用签名级别安全性
  2. 定义自定义权限
  3. 您尝试使用使用其他密钥签名的版本更新已安装的应用
  4. 测试设备运行的是Android 21或更高版本,支持多个用户
  5. 命令行示例

    这是一个命令行脚本,演示了该问题以及如何解决它。此时安装了调试版本,我正在尝试安装使用发布密钥签名的生产版本:

    # This fails because the debug version defines the custom permission signed with a different key:
    
    [root@localhost svn-android-apps]# . androidbuildscripts/my-adb-install Example release
    920 KB/s (2211982 bytes in 2.347s)
            pkg: /data/local/tmp/Example-release.apk
    Failure [INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.example.android.example.PERMISSION_EXAMPLE_PLUGIN pkg=com.example.android.example]
    
    # I use uninstall -k because apparently that is similar to uninstalling as a user
    # by dragging the app out of the app tray:
    
    [root@localhost svn-android-apps]# /android-sdk-linux/platform-tools/adb uninstall -k com.example.android.example
    The -k option uninstalls the application while retaining the data/cache.
    At the moment, there is no way to remove the remaining data.
    You will have to reinstall the application with the same signature, and fully uninstall it.
    If you truly wish to continue, execute 'adb shell pm uninstall -k com.example.android.example'
    
    # Let's go ahead and do that:
    
    [root@localhost svn-android-apps]# /android-sdk-linux/platform-tools/adb shell pm uninstall -k com.example.android.example
    Success
    
    # This fails again because the custom permission apparently is part of the data/cache
    # that was not uninstalled:
    
    [root@localhost svn-android-apps]# . androidbuildscripts/my-adb-install Example release
    912 KB/s (2211982 bytes in 2.367s)
            pkg: /data/local/tmp/Example-release.apk
    Failure [INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.example.android.example.PERMISSION_EXAMPLE_PLUGIN pkg=com.example.android.example]
    
    # In spite of the warning above, simply doing a full uninstall at this point turned out to 
    # work (for me):
    
    [root@localhost svn-android-apps]# /android-sdk-linux/platform-tools/adb uninstall com.example.android.example
    Success
    
    # Release version now successfully installs:
    
    [root@localhost svn-android-apps]# . androidbuildscripts/my-adb-install Example release
    898 KB/s (2211982 bytes in 2.405s)
            pkg: /data/local/tmp/Example-release.apk
    Success
    
    [root@localhost svn-android-apps]# 
    

    Eclipse示例

    反方向(尝试​​在安装版本构建时从Eclipse安装调试版本),我得到以下对话框:

    Eclipse reinstall dialog

    如果您此时只回答“是”,则安装将成功。

    设备示例

    正如另一个答案中所指出的,您还可以转到设备设置中的应用信息页面,单击溢出菜单,然后选择“为所有用户卸载”以防止出现此错误。

答案 3 :(得分:32)

我已经解决了这个问题,而不必首先卸载备用apk(多么痛苦,对吧?)。要成功安装apk的调试版和发行版,只需在AndroidManifest.xml中使用gradle的内置$ {applicationId}占位符,即可在编译时修改权限'android:name值。

build.gradle文件摘要:

buildTypes {
    debug {
        applicationIdSuffix ".debug"
        ...
    }
}

AndroidStudio.xml文件摘要:

<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>

您可以使用aapt l -a app-debug.apk检查apk中已修改的AndroidManifest.xml文件,以确保正确应用了占位符。如果您使用各种产品口味,我相信您可以应用此方法的变体来满足您的需求。

答案 4 :(得分:24)

删除任何&#34;硬编码&#34;从您的清单文件中引用您的包名称。

(即使您不使用productFlavors

,这是最佳做法

例如,如果您的清单包含:

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="com.yourpackage.name.permission.C2D_MESSAGE"/>

<permission
    android:name="com.yourpackage.name.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>
<permission
    android:name="com.yourpackage.name.permission.MAPS_RECEIVE"
    android:protectionLevel="signature"/>

将其更改为:

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>

<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>
<permission
    android:name="${applicationId}.permission.MAPS_RECEIVE"
    android:protectionLevel="signature"/>

然后,在您的模块gradle文件中,设置相关的applicationId

signingConfigs {
    stage {
        storeFile file('keystore/stage.keystore')
        storePassword 'android'
        keyAlias 'androiddebugkey'
        keyPassword 'android'
    }
    production {
        storeFile file('keystore/playstore.keystore')
        storePassword store_password
        keyAlias key_alias
        keyPassword key_password
    }
}

productFlavors {
    staging {
        signingConfig signingConfigs.staging
        applicationId defaultConfig.applicationId + ".staging"
        versionName defaultConfig.versionName + "-staging"
    }

    production {
        signingConfig signingConfigs.production
    }
}

You can follow this tutorial for more info

答案 5 :(得分:18)

尝试使用adb:

卸载应用
adb uninstall com.yourpackage

答案 6 :(得分:17)

在提供此错误时,它会清楚地提及应用程序的程序包名称,因为该权限被拒绝。只是卸载应用程序将无法解决问题。为了解决问题,我们需要执行以下步骤:

  1. 转到设置
  2. 转到应用
  3. 转到下载的应用列表
  4. 您可以在列表中看到已卸载的应用程序
  5. 点击该应用程序,转到更多选项
  6. 点击卸载所有用户选项
  7. 问题解决了:D

答案 7 :(得分:8)

在OS 5.0中安装应用程序我收到此消息:

INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.myapp.permission.C2D_MESSAGE pkg=com.myapp

没有重复的软件包,我们可以解决此问题,手动卸载旧应用程序或使用adb:

adb uninstall com.yourpackage

答案 8 :(得分:4)

在Android 5中,检查您的设置 - &gt;应用。而不是只删除活动用户(因为android 5可以有多个用户而我的手机有访客用户)点击操作/工具栏右上角的附件按钮,然后选择“为所有用户卸载”。在Android 5中,当您刚刚从启动器卸载时,您只需卸载活动用户的应用程序。

该应用程序仍然在设备上..这让我眼花缭乱,因为我试图安装发布版本,没有工作所以我认为正确必须是因为我仍然安装了调试版本,卸载了应用程序。但仍然无法安装..第一条线索是已卸载应用程序的应用程序列表中的记录,旁边显示已卸载的消息(图像)。

Uninstalled app still showing up in apps Uninstalled for all users

答案 9 :(得分:4)

CommonsWare是对的,但在我看来,这是一个(错误)糟糕的说法:“设备上安装的apk使用不同的证书进行签名,然后是您要安装的新证书”

这可能是一个新的错误,因为过去它曾经问过是否因为错误的证书而从设备上卸载应用程序。

尽可能痛苦的解决方案是手动卸载应用程序。

我们为了团队开发而做了什么,我们将调试密钥库添加到我们的存储库,并指向gradle以便像这样使用它:

android {
    ...
    signingConfigs {
        debug {
            storeFile file("../certificates/debug.keystore")
        }
    }

    ...

    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
    }

    ...
}

现在,当在团队成员之间传递设备时,我们都使用相同的调试证书,因此没有问题。 :)

答案 10 :(得分:4)

以上都不适合我。我的应用程序在Lollipop之前工作正常。但是当我在Lollipop上测试时,出现了上述错误。它拒绝安装。我没有安装任何以前的版本,所以上述所有解决方案都无效。但感谢this SO solution现在运行正常。就像大多数开发人员一样,我遵循Google的误导性教程,我通过复制和粘贴添加了权限,如下所示:

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.google.android.permission.C2D_MESSAGE" 
            android:protectionLevel="signature" />

这适用于旧版本&lt;棒糖。所以现在我改为:

<uses-permission android:name="com.mycompany.myappname.c2dm.permission.RECEIVE" />
<permission android:name="com.mycompany.myappname.permission.C2D_MESSAGE" 
            android:protectionLevel="signature" />

答案 11 :(得分:2)

看到这个link它说它们在用同一个密钥签名时会起作用。释放键和调试键不一样。

所以这样做:

buildTypes {
        release {
            minifyEnabled true
            signingConfig signingConfigs.release//signing by the same key
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-android.txt'

        }
        debug {
            applicationIdSuffix ".debug"
            debuggable true
            signingConfig signingConfigs.release//signing by the same key
        }

    }

 signingConfigs {
        release {
            storeFile file("***\\key_.jks")
            storePassword "key_***"
            keyAlias "key_***"
            keyPassword "key_"***"
        }


}

答案 12 :(得分:1)

对于我来说,我安装了几个应用程序,它们的包名中的域名都如下所示。

com.mypackage.app1
com.mypackage.app2
com.mypackage.app3 
...

我必须卸载所有具有相似软件包名称的应用程序,然后再次重新安装它们,以消除问题。

要从设备中查找所有软件包名称,我使用了以下内容。

adb shell pm list packages

然后,我抓取了与要查找的包裹名称匹配的包裹。

dumpsys | grep -A18 "Package \[com.mypackage\]"

然后卸载具有该域的所有应用程序。

uninstall com.mypackage.app1
uninstall com.mypackage.app2
uninstall com.mypackage.app3
...

您还可以使用Settings应用程序卸载应用程序。转到Settings -> Apps -> Find the app -> Uninstall

希望对与我有相同问题的人有所帮助。

答案 13 :(得分:0)

如果您的应用程序风格不同,请尝试首先将其卸载。当我遇到同样的问题时,这对我有帮助。

答案 14 :(得分:0)

我在卸载应用后重启了手机,

答案 15 :(得分:0)

为了制作应用程序及其多个实例,您可以直接添加此行,然后每次只需修改应用程序ID即可安装具有相同包名的多个应用程序:

示例:应用程序 ID:XXXX.123(旧的或安装在手机中的现有应用程序)

现在将应用程序 id 设为:XXX.1234 并安装应用程序。

格式:

<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature"/>

答案 16 :(得分:0)

我卸载了以前的版本。它对我有用。

答案 17 :(得分:0)

替换以下行:

<permission android:name="com.myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.myapp.permission.C2D_MESSAGE" 
android:protectionLevel="signature" /> 

答案 18 :(得分:0)

在我的情况下,我使用的是第三方库(即供应商),该库附带了一个示例应用程序,我已经在我的设备上安装了该应用程序。因此,每当我尝试安装我自己的应用程序实现库时,示例应用程序现在都是冲突的。所以我刚刚卸载了供应商的示例应用程序,之后就可以运行了。

答案 19 :(得分:0)

在AndroidManifest.xml文件中,更改您特别声明的权限&#39;名称,例如:

<!-- Creates a custom permission so only this app can receive its messages. NOTE: APP_PACKAGE.permission.C2D_MESSAGE -->   
<permission android:name="com.myapp.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.myapp.permission.C2D_MESSAGE" />    
<!-- END GCM -->

到此,

<!-- Creates a custom permission so only this app can receive its messages. NOTE: APP_PACKAGE.permission.C2D_MESSAGE -->   
<permission android:name="com.myapprocks.permission.C2D_MESSAGE"  android:protectionLevel="signature" />
<uses-permission android:name="com.myapprocks.permission.C2D_MESSAGE" />    
<!-- END GCM -->

com.myapprocks 此部分解决了与您的其他应用的冲突。

答案 20 :(得分:0)

在我的情况下,我收到了以下错误

  

安装错误:INSTALL_FAILED_DUPLICATE_PERMISSION   perm = com.map.permission.MAPS_RECEIVE pkg = com.abc.Firstapp

当我尝试安装包名为com.abc.Secondapp的应用时。这一点是我的应用程序中已经安装了包名为com.abc.Firstapp的应用程序。

我通过卸载包名为com.abc.Firstapp的应用程序然后安装包名为com.abc.Secondapp

的应用程序来解决此错误

我希望这会在测试时帮助某人。

答案 21 :(得分:0)

我遇到了与nexus 5 Android Lollipop 5.0.1相同的问题:

Installation error: INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.android.** pkg=com.android.**

在我的情况下,我无法解决此问题uninstalling应用,因为它是android app,但我必须在{{1}中更改我的应用custom permissions名称因为它们与Android应用程序相同,我无法卸载或进行任何更改。

希望这有助于某人!

答案 22 :(得分:0)

以前曾经说过在设备上找到了具有不同签名的应用。从IDE安装时,它还会问你要卸载吗?

但我认为从Android 5.0开始他们已经改变了卸载的原因。如果您使用相同的签名安装应用程序

,则不会发生这种情况