INSTALL_FAILED_DUPLICATE_PERMISSION... C2D_MESSAGE
Solution 1:
I've found a solution that works for me.
In My Device (Nexus 7) Android 5.0. Lollipop I follow these steps.
After Uninstalling App You will find App Name
under Apps List of the Downloaded
tab.
- Go to Settings
- Apps
- At the bottom of the list, you will find
YourApp
with a "NOT INSTALLED" Tag - Open
- Click on
OptionMenu
and Select "Uninstall for all Users"
After these steps, I successfully install the new app and it's running well.
Solution 2:
Remove
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
Run App... Then Add the permisson again and Run App.
Ready!.
Solution 3:
I had the same problem with a custom signature permission on Android-21 and solved it by making sure I was doing a complete uninstall.
This is an edge case that occurs when:
- An application defines a custom permission using signature level security
- You attempt to update the installed app with a version signed with a different key
- The test device is running Android 21 or newer with support for multiple users
Command line example
Here is a command-line transcript that demonstrates the issue and how to solve it. At this point a debug version is installed and I am trying to install a production version signed with the release key:
# 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 example
Going in the opposite direction (trying to install a debug build from Eclipse when a release build is already installed), I get the following dialog:
If you just answer yes at this point the install will succeed.
Device example
As pointed out in another answer, you can also go to an app info page in the device settings, click the overflow menu, and select "Uninstall for all users" to prevent this error.
Solution 4:
I've solved this without having to resort to uninstalling the alternate apk first (what a pain, right?). To successfully install both a debug and release version of an apk, simply use gradle's built-in ${applicationId} placeholder within the AndroidManifest.xml to modify the permissions' android:name values at compile time.
The build.gradle file snippet:
buildTypes {
debug {
applicationIdSuffix ".debug"
...
}
}
The AndroidStudio.xml file snippet:
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
You can inspect the modified AndroidManifest.xml file within the apk using aapt l -a app-debug.apk
to ensure the placeholder was properly applied. If you use various product flavors, I'm sure you can apply a variation of this method to suit your needs.
Solution 5:
Remove any "Hard Coded" reference of your package name, from your manifest file.
(This is best practice even if you don't using productFlavors
)
For example, if your manifest contains:
<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"/>
Changed it to:
<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"/>
Then, in your module gradle file, set your relevant 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