INSTALL_FAILED_DUPLICATE_PERMISSION... C2D_MESSAGE - android

I am using Google notifications in my app, and until now I have done below in the manifest:
<!-- 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 -->
It worked perfectly until I updated my Nexus 7 to Android 5.0.
Now when I try to install the app in this device with Eclipse, I get this error:
INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.myapp.permission.C2D_MESSAGE pkg=com.myapp
I don't understand what is wrong? It was working perfectly until Android 5.0.
I know that I am using C2D_MESSAGE in two lines, permission and uses-permission but I have copied that code from the original Google GCM guide, so it must be fine.

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.

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!.

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.

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.

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

try to uninstall the app with adb:
adb uninstall com.yourpackage

While giving this error it will clearly mention the package name of the app because of which the permission was denied. And just uninstalling the application will not solve the problem. In order to solve problem we need to do the following step:
Go to settings
Go to app
Go to downloaded app list
You can see the uninstalled application in the list
Click on the application, go to more option
Click on uninstall for all users options
Problem solved :D

Installing an application in OS 5.0 i get this message:
INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.myapp.permission.C2D_MESSAGE pkg=com.myapp
There´s no duplicated packages, and we can solve this issue uninstalling manually the old application or using the adb:
adb uninstall com.yourpackage

None of the above worked for me. My app was working fine in previous than Lollipop. But when I tested it on Lollipop the above error came up. It refused to install. I didn't have any previous versions installed so all the above solutions are invalid in my case. But thanks to this SO solution now it is running fine. Just like most developers I followed Google's misleading tutorial and I added the permissions by copy and paste like this:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.google.android.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
This would work with older versions < Lollipop. So now I changed to:
<uses-permission android:name="com.mycompany.myappname.c2dm.permission.RECEIVE" />
<permission android:name="com.mycompany.myappname.permission.C2D_MESSAGE"
android:protectionLevel="signature" />

CommonsWare is right, but in my opinion this is a (bug)poor way to say: "The apk installed on the device is signed with a different certificate then the new one you are trying to install".
This is probably a new bug since in the past it used to ask whether or not to uninstall the app from the device due to wrong certificate.
The solution as painful as it may be would be to uninstall the app it manually.
Also what we've done for the sake of team development, we added the debug keystore to our repository, and point gradle to use it like so:
android {
...
signingConfigs {
debug {
storeFile file("../certificates/debug.keystore")
}
}
...
buildTypes {
debug {
signingConfig signingConfigs.debug
}
}
...
}
And now when passing devices between team members, we all use the same debug certificate, so there is no issue. :)

In Android 5, check your settings -> apps. Instead of deleting for just the active user (since android 5 can have multiple users and my phone had a guest user) tap on the accessory button in the top right corner of the action/toolbar and choose "uninstall for all users". It appears that in Android 5 when you just uninstall from launcher you only uninstall the app for the active user.
The app is still on the device.. This had me dazzled to since I was trying to install a release version, didn't work so I thought ow right must be because I still have the debug version installed, uninstalled the app. But than still couldn't install.. First clue was a record in the app list of the uninstalled app with the message next to it that it was uninstalled (image).

See this link it said that it will work when they are signed by the same key. The release key and the debug key are not the same.
So do it:
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_"***"
}
}

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

In my case, I had several applications installed having the same domain name in the package name as follows.
com.mypackage.app1
com.mypackage.app2
com.mypackage.app3
...
I had to uninstall all the apps having similar package names and reinstall them again in order to get rid of the problem.
To find all package names from the device I used the following.
adb shell pm list packages
Then I grabbed the packages that match my package name that I am looking for.
dumpsys | grep -A18 "Package \[com.mypackage\]"
Then uninstalled all the apps having that domain.
uninstall com.mypackage.app1
uninstall com.mypackage.app2
uninstall com.mypackage.app3
...
You can also uninstall the applications using the Settings app. Go to the Settings -> Apps -> Find the app -> Uninstall
Hope that helps someone having the same problem as me.

Previously it used to say that an app with different signature is found on device. When installing from IDE it would also ask do you want to uninstall it?
But I think from Android 5.0 they have changed the reason for uninstallation. It does not happen if you are installing app with the same signature

I encountered the same problem with a nexus 5 Android Lollipop 5.0.1:
Installation error: INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.android.** pkg=com.android.**
And in my case I couldn't fix this problem uninstalling the app because it was an android app, but I had to change my app custom permissions name in manifest because they were the same as an android app, which I could not uninstall or do any change.
Hope this helps somebody!

In my case I received following error
Installation error: INSTALL_FAILED_DUPLICATE_PERMISSION
perm=com.map.permission.MAPS_RECEIVE pkg=com.abc.Firstapp
When I was trying to install the app which have package name com.abc.Secondapp. Here point was that app with package name com.abc.Firstapp was already installed in my application.
I resolved this error by uninstalling the application with package name com.abc.Firstapp and then installing the application with package name com.abc.Secondapp
I hope this will help someone while testing.

In your AndroidManifest.xml file, change your specially declared permissions' names, for example:
<!-- 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 -->
to this,
<!-- 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 this part solves the conflict with your other app.

In my case I was using a third party library (i.e. vendor) and the library comes with a sample app which I already had install on my device. So that sample app was now conflicting each time I try to install my own app implementing the library. So I just uninstalled the vendor's sample app and it works afterwards.

I uninstalled previous version. It worked for me.

I restarted my phone after uninstalling the app and it worked

If you have a different flavour of the app, try uninstalling that first. This helped me when I had the same issue.

I had another app using a plugin with this permission authorities.
I uninstalled other apps which use this same package and all worked

Related

Flutter APK Build

Goo day friends! I am new to Flutter and I have been experimenting on fetching data via REST API. On Android Studio, everything works just fine, so I suppose there's nothing wrong with my code.
Things I did to make sure my code works:
1.) Run the code in android simulator;
2.) Run the code using real device (enabling USB Debugging).
And it works just fine.
But when I build an apk file out of it and install it on my device, it no longer makes the API call (or is unable to?). I made it so, when the app runs initState(), it waits for the data to be loaded. While the data is not yet available, a CircularProgressIndicator() takes the entire screen.
If I run the app via the installed apk file, it's just CircularProgressIndicator(). Meaning, no data is being loaded and displayed. But when I run the code in AndroidStudio, the data is shown..
I am using http package. I'm not sure what I'm doing wrong, or what I'm missing.
Other things to note: I did not change anything in my AndroidManifest file, and just followed all the steps on building apk file in Flutter through the official documentation.
Like alexsanderfr said, this is indeed most of the time being caused by missing
<uses-permission android:name="android.permission.INTERNET" />
You shouldn't need
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
for REST API.
In Flutter, when debugging you implicitly have access to internet, however in release builds, you need to explicitly declare this permission.
update1
Ensure you have the http-package added to your pubspec.yaml file and that it's properly indented with two spaces:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
http: ^0.12.0+4
Did you add the internet permission to the manifest? If you're accessing the internet from an Android app you need to add the internet permission over the application tag.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

App Refuses to Install - INSTALL_FAILED_MISSING_SHARED_LIBRARY

I am new to programming generally please I need some help!
My app was installing successfully after every update until i decided to add the 'com.github.PhilJay:MPAndroidChart:v3.1.0-alpha' library to the app because i need the user to be able to view some data in form of statistical charts.
The library was synced successfully and have used packages and classes therein successful. But when i try to install the app in my android device it returned this error:
Installation failed with message Failed to commit install session 590492354 with command cmd package
install-commit 590492354. Error: INSTALL_FAILED_MISSING_SHARED_LIBRARY: Package couldn't be installed in
/data/app/com.cenitscitech.www.etimebook-jOP-jv2YuNu7_8qnkfqp-A==: Package com.cenitscitech.www.etimebook requires unavailable shared library com.google.android.things; failing!.
It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing." I have pasted a screenshot here:
I uninstalled the existing version of the apk, cleared some memory space but keep on getting the same message! What should I do next please?
You are most likely installing on a device that is not an Android Things device. I suspect the library you added either has some transitive dependency on com.google.android.things, or something else changed in your project.
To get around this, you must do the following 2 things:
1. Mark that Android Things is not required on the device in your AndroidManifest.xml file:
<uses-library
android:name="com.google.android.things"
android:required="false"
tools:replace="android:required" />
(tools:replace is not strictly required, but it just there in case something in the manifest merge process overrides your setting.)
2. In your app's code, before making any calls to the Things APIs, make sure that they are available on the current device. This can be tested with the following code snippet:
public boolean isThingsDevice(Context context) {
final PackageManager pm = context.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_EMBEDDED);
}
Only doing 1 should fix the install problem, but your app will crash if you make any Things API calls on a device that isn't an Android Things device.
Had a look in the com.github.PhilJay:MPAndroidChart:v3.1.0-alpha repository and did not find any reference to com.google.android.things inside the source code.
You need to remove the below entry in case it's found in the AndroidManifest.xml of your app for it to work on your device again:
<uses-library android:name="com.google.android.things" />

I have removed Call and SMS permission from manifest still im getting error while uploading apk

My App was removed by google because of presence of SMS and Call Permission in manifest. Now I have removed both the permission then also I'm not able to upload the apk .play store asking for the Permissions Declaration Form
Most likely some library you're using is adding the permissions. You can remove them during merge by adding the following to your AndroidManifest.xml:
<uses-permission android:name=”android.permission.RECEIVE_SMS” tools:node=”remove” />
<uses-permission android:name=”android.permission.SEND_SMS” tools:node=”remove” />
<uses-permission android:name=”android.permission.WRITE_SMS” tools:node=”remove” />
<uses-permission android:name=”android.permission.READ_SMS” tools:node=”remove” />
See this SO question for additional information.
You have to release a build with those permissions and fill the form (form will appear automatically on release page), then after that, you have to upload a build without those permissions.
I got the same problem recently and i have to removed those permissions and later my app got published. Please type all your permission you using in your app?
Remove SMS and CALL-Log permission from manifest file and Build new APK upload in Internal Test Track and deactivate previously released APK in internal Test track and roll out, Then release same APK in Alpha and Beta, Then Previously Declared Permissions will be automatically removed and release app to production and roll out

Android test-only permissions with gradle

I run ./gradlew connectedAndroidTest and I need my test APK to have a permission which should not be in any non-testing APK (debug, release). I have created a manifest with permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypackage">
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>
</manifest>
Then I have copied this manifest to src/androidTest directory, as release notes from gradle android plugin suggest:
0.13.0 (2014/09/18)
Requires Gradle 2.1
It is now possible to provide a manifest for test apps (src/androidTest/AndroidManifest.xml)
However, the permission is not applied during my connected tests.
If I create a src/debug directory and move this manifest there -- the permission is applied correctly during connected tests (but also during regular debug builds, which is undesirable).
Am I doing something wrong or is there a bug?
The problem stems from my misunderstanding of how connectedAndroidTest gradle task works. It creates and deploys 2 android applications - a testable (your project) and a tester (an app which simulates a user who interacts with the testable app). My intent was to add the permission to the testable app. However, adding a manifest to src/androidTest resulted in adding the permission to the tester app. Here's how I figured that out:
If I execute
adb shell pm list packages -f -3
(-3 means to list only third-party packages) I can see something like this
package:/data/app/SmokeTestApp.apk=com.android.smoketest
package:/data/app/GestureBuilder.apk=com.android.gesture.builder
package:/data/app/com.mycompany.myapp-2.apk=com.mycompany.myapp
package:/data/app/SoftKeyboard.apk=com.example.android.softkeyboard
package:/data/app/org.libsdl.app-2.apk=org.libsdl.app
package:/data/app/SmokeTest.apk=com.android.smoketest.tests
package:/data/app/com.mycompany.myapp.test-1.apk=com.mycompany.myapp.test
The app with test-1 suffix is the tester app, another one is my testable app. Checking their permission gives:
root#generic_x86:/ # aapt d permissions /data/app/com.mycompany.myapp-2.apk
package: com.spredfast.android
uses-permission: android.permission.INTERNET
uses-permission: android.permission.WRITE_EXTERNAL_STORAGE
root#generic_x86:/ # aapt d permissions /data/app/com.mycompany.myapp.test-1.apk
package: com.spredfast.android
uses-permission: android.permission.SET_ANIMATION_SCALE
So the permission, SET_ANIMATION_SCALE, which I was intending to put into my testable app is put into the tester app. No wonder that moving the manifest from src/androidTest to src/debug would put the permission into the testable app (correct, but too broad).
Here's how I solved the original problem - putting the permission into the application only in case of the application being run inside connectedAndroidTest task.
I have created an empty build flavor to be used with integration tests:
productFlavors {
/**
* This flavor is to be run only using connectedAndroidTestAnimcontrol
*/
animcontrol {}
regular {}
}
Moved src/androidTest/AndroidManifest.xml with the single permission into src/animcontrol/AndroidManifest.xml
Executed connected tests as
./gradlew connectedAnimcontrolDebugAndroidTest
That did the trick, now I have AndroidManifest.xml which will be merged with main app's manifest only when being run as connectedAndroidTest.
Hope this helps someone.

Is it possible to mock locations for release build type

I'd like to mock locations in release build type of Android app. I've created a special flavour "mockable" manifest in app/src/mockable/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
</manifest>
But it seems that Android lint blocks from using this permissions in release build type. For command:
./gradlew assembleRelease
I got output:
:app:lintVitalMockableRelease
/home/fr/app/src/mockable/AndroidManifest.xml:3: Error: Mock locations should only be requested in a debug-specific manifest file (typically src/debug/AndroidManifest.xml) [MockLocation]
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Explanation for issues of type "MockLocation":
Using a mock location provider (by requiring the permission
android.permission.ACCESS_MOCK_LOCATION) should only be done in debug
builds. In Gradle projects, that means you should only request this
permission in a debug source set specific manifest file.
To fix this, create a new manifest file in the debug folder and move the
<uses-permission> element there. A typical path to a debug manifest
override file in a Gradle project is src/debug/AndroidManifest.xml.
1 errors, 0 warnings
Is it possible to generate release app with location mocking permission?
Disable the MockLocation lint check for that particular permission, i.e.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission
android:name="android.permission.ACCESS_MOCK_LOCATION"
tools:ignore="MockLocation" />
</manifest>
(Refer to http://tools.android.com/tips/lint-checks)
The only solution I know for sure is to let lint report errors but don't let that abort the build process:
To enable that just add
lintOptions {
abortOnError false
}
inside the android block.
You will still get lint errors and warnings but the build will continue.
I am not sure if you can put that inside the flavor definition or use a custom buildType for that. I have no project where I could test that.
This is a caution. If you want a user to "mock location" then the user must enable mock locations in Android.
A production release is definitely possible, I have done this. You need to prompt the user to allow for "Mock Locations" like a developer/debug would.

Categories

Resources