【问题标题】:INSTALL_FAILED_DUPLICATE_PERMISSION... C2D_MESSAGEINSTALL_FAILED_DUPLICATE_PERMISSION... C2D_MESSAGE
【发布时间】:2014-11-20 15:57:31
【问题描述】:

我在我的应用中使用 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_MESSAGE,permission 和uses-permission,但我已经从原始 Google GCM 指南中复制了该代码,所以它一定没问题。

【问题讨论】:

  • 你最初为一个不起眼的错误(好吧,我做了......)实际上是一个新的安全功能,可以防止两个应用程序声明使用不同签名签名的相同自定义权限,以安装在一个设备
  • @NullPointerException 您能否接受这个答案,因为它对很多人都有帮助。

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


【解决方案1】:

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

在我的设备中 (Nexus 7) Android 5.0。 Lollipop 我按照这些步骤操作。

卸载应用程序后,您将在Downloaded 选项卡的应用程序列表下找到App Name。

  • 进入设置
  • 应用程序
  • 在列表底部,您会找到带有“未安装”标签的YourApp
  • 打开
  • 点击OptionMenu并选择“为所有用户卸载”

完成这些步骤后,我成功安装了新应用,并且运行良好。

【讨论】:

  • 我使用 android 5.0.1 安装了 nexus 9,但我看不到带有“noto installed”标签的应用程序
  • 这对我有用,谢谢!我的问题略有不同。我正在我们的移动应用程序上进行自动化测试 (Xamarin.UITest),并且我上传了一个不同的版本进行一些手动测试。当我尝试将应用程序(通过 VS / Xamarin UITest)加载到设备时,我开始看到这个问题。再次感谢。
  • 这个应该是正确答案:stackoverflow.com/a/27767179/343679
  • @Pratik Butani 该解决方案对我有用。我想知道出现错误的原因?您能解释一下吗?
  • 我没有在列表底部找到带有 NOT INSTALLED 标签的应用。什么意思?
【解决方案2】:

删除

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

运行应用程序... 然后再次添加权限并运行应用程序。

准备好了!

【讨论】:

  • 这个答案应该放在首位,因为当您尝试在同一设备上安装应用程序的调试和发布版本时,经常会出现此问题。使用此解决方案,您可以轻松做到。我不知道您可以在清单中使用变量。点赞!
  • 如果应用程序已经在生产中,则此答案不起作用。我不能指望我的应用程序的用户在没有权限的情况下下载新版本,然后再次安装具有权限的新版本。
  • 如果发生这种情况是因为您的应用程序的调试和发布版本具有不同的名称,则无需卸载即可工作:您只需要使用 ${applicationId} 而不是硬编码
  • 使用 ${applicationId} 而不是静态应用程序 ID 解决了我的问题!!包括在使用 Flavours 时!!!!
  • @yuval 的评论很到位,并为我解决了这个问题。在众多答案中,这个最能解决问题:stackoverflow.com/a/36992939/56285
【解决方案3】:

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

这是一种极端情况,发生在以下情况:

  1. 应用程序使用签名级安全性定义自定义权限
  2. 您尝试使用使用不同密钥签名的版本更新已安装的应用程序
  3. 测试设备运行 Android 21 或更高版本,支持多用户

命令行示例

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

# 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 安装调试版本),我得到以下对话框:

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

设备示例

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

【讨论】:

  • 谢谢,但是您应该以“您也可以转到设备设置中的应用信息页面,单击溢出菜单,然后选择“为所有用户卸载”来防止出现此错误。 "
  • 请嫁给我吧。在您修改后,我进入设置 > 应用程序,触摸旧版应用程序,然后在选项菜单中选择“为所有用户卸载”。
  • 前置条件列表中的#2 不一定是真的。在我的情况下,我不是 更新 应用程序,而是安装具有不同包名称的同一应用程序的调试版本,如本程序所述。 stackoverflow.com/a/21006552/507339。这是一个我没有找到解决方案的问题
【解决方案4】:

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

build.gradle 文件 sn -p:

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

AndroidStudio.xml 文件 sn-p:

<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 文件,以确保正确应用占位符。如果您使用各种产品口味,我相信您可以应用此方法的变体来满足您的需求。

【讨论】:

  • 看来如果我在两个不同的productFlavors中定义不同的applicationId,并使用${applicationId},效果是一样的。
  • 我认为如果您需要超过 1 种风味,这是更强大的解决方案。
  • 这应该被标记为正确。考虑到你不能指望每个同事都做一些黑客攻击来简单地构建一个项目并安装 apk
  • 谢谢,@jackpile 该应用程序对我来说运行得非常好,如果同时安装了发布版本和调试版本,那么只有一个问题,然后在安装调试版本之后,发布版本会打开
  • 这应该被标记为正确答案..谢谢@Jackpile
【解决方案5】:

从清单文件中删除任何对包名称的“硬编码”引用。

(即使您不使用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

【讨论】:

  • 使用 ${applicationId} 为我解决了这个问题!
  • 如何解决上述问题?
【解决方案6】:

尝试使用 adb 卸载应用:

adb uninstall com.yourpackage

【讨论】:

  • 奇怪的是,我只需要在我的 Nexus 6 上执行此操作,即使我已通过系统 UI 卸载了我的 APK 并且它没有显示在已安装的应用程序下。
  • 它给了我Failure [DELETE_FAILED_INTERNAL_ERROR]。可能是什么原因?
  • 这对我来说非常有效,没有别的办法。感谢分享。
【解决方案7】:

在给出此错误时,它会清楚地提及应用程序的包名称,因为该应用程序的权限被拒绝。并且仅仅卸载应用程序并不能解决问题。为了解决问题,我们需要执行以下步骤:

  1. 进入设置
  2. 转到应用程序
  3. 进入下载的应用列表
  4. 您可以在列表中看到已卸载的应用程序
  5. 点击应用,进入更多选项
  6. 点击为所有用户卸载选项

问题解决了 :D

【讨论】:

    【解决方案8】:

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

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

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

    adb uninstall com.yourpackage

    【讨论】:

      【解决方案9】:

      以上都不适合我。我的应用在 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" />
      

      这适用于旧版本

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

      【讨论】:

        【解决方案10】:

        CommonsWare 是对的,但在我看来,这是一种(错误)糟糕的说法:“设备上安装的 apk 使用不同的证书签名,而不是您尝试安装的新证书” em>。

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

        手动卸载应用是最痛苦的解决方案。

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

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

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

        【讨论】:

          【解决方案11】:

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

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

          【讨论】:

          • 抱歉,查看了您的评论。我们只会将此视为带有图片的额外信息帖子。
          【解决方案12】:

          看到这个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_"***"
                  }
          
          
          }
          

          【讨论】:

            【解决方案13】:

            替换以下行:

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

            【讨论】:

              【解决方案14】:

              在我的例子中,我安装了几个应用程序,在包名称中具有相同的域名,如下所示。

              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 -&gt; Apps -&gt; Find the app -&gt; Uninstall

              希望能帮助遇到和我一样问题的人。

              【讨论】:

                【解决方案15】:

                为了制作应用程序及其多个实例,您可以直接添加此行,然后您可以在每次修改应用程序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】:

                  以前常说在设备上发现了具有不同签名的应用程序。从 IDE 安装时,它还会询问您是否要卸载它?

                  但我认为从 Android 5.0 开始,他们已经改变了卸载的原因。如果您正在安装具有相同签名的应用程序,则不会发生这种情况

                  【讨论】:

                    【解决方案17】:

                    我在使用 nexus 5 Android Lollipop 5.0.1 时遇到了同样的问题:

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

                    在我的情况下,我无法解决这个问题 uninstalling 应用程序,因为它是一个 android app,但我不得不在 manifest 中更改我的应用程序 custom permissions 名称,因为它们与 android 相同应用程序,我无法卸载或进行任何更改。

                    希望这对某人有所帮助!

                    【讨论】:

                      【解决方案18】:

                      就我而言,我收到以下错误

                      安装错误: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 的应用程序解决了此错误

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

                      【讨论】:

                        【解决方案19】:

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

                        <!-- 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】:

                          就我而言,我使用的是第三方库(即供应商),并且该库附带一个示例应用程序,我已经在我的设备上安装了该应用程序。因此,每次我尝试安装实现该库的自己的应用程序时,该示例应用程序现在都会发生冲突。所以我只是卸载了供应商的示例应用程序,然后它就可以工作了。

                          【讨论】:

                            【解决方案21】:

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

                            【讨论】:

                              【解决方案22】:

                              卸载应用后我重新启动了手机,它运行正常

                              【讨论】:

                                【解决方案23】:

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

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 2018-07-14
                                  • 2018-09-22
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多