Android Manifest Duplicate Permissions
Asked Answered
S

3

14

We have an app that consists of a third party library (altbeacon), a locally built Android library and an app component. All three components have an AndroidManifest.xml which are merged during the build. The app is built using gradle.

THis app has been long published on the Google Play Store. In the last iteration we upgraded from API level 22 to 25. Everything built without error, the APK was installed on and tested on real devices without error, but when we came to update the app on Google Play, the upload of the APK failed with the error:

Upload failed
Duplicate declarations of permission android.permission.ACCESS_COARSE_LOCATION with different maxSdkVersions.

Anaylyzing the AndroidManaifest.xml we found org.altbeacon.beacon has the following permission:

<uses-sdk
    android:minSdkVersion="7"
    android:targetSdkVersion="23" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />

Our local Android library module the targetSdkVersion is set to 25 in build.gradle and the the AndroidManifest.xml contains:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

In the app module the targetSdkVersion is set to 25 in build.gradle.

The generated AndroidManifest.xml in the app module contains:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />

and just to confirm, looking in the APK itself and extracting the binary manifest:

~/.android-sdk/build-tools/25.0.3/aapt l -a app-release.apk | grep -B1 COARSE
    E: uses-permission (line=62)
      A: android:name(0x01010003)="android.permission.ACCESS_COARSE_LOCATION" (Raw: "android.permission.ACCESS_COARSE_LOCATION")
--
    E: uses-permission-sdk-23 (line=76)
      A: android:name(0x01010003)="android.permission.ACCESS_COARSE_LOCATION" (Raw: "android.permission.ACCESS_COARSE_LOCATION")

So there is a duplicate tag, and I think the manifest merger should have recognized that and removed the one from the altbeacon library. My question is how do I remove the permission from the altbeacon library?

I have tried the following in the app module AndroidManifest.xml:

<uses-permission-sdk-23
   android:name="android.permission.ACCESS_COARSE_LOCATION"
   tools:node="remove"
   tools:selector="org.altbeacon.beacon"/>

This results in:

AndroidManifest.xml:12:5-15:48 Warning:
        uses-permission-sdk-23 was tagged at AndroidManifest.xml:12 to remove other declarations but no other declaration present

and

<uses-permission
   android:name="android.permission.ACCESS_COARSE_LOCATION"
   tools:node="remove"
   tools:selector="org.altbeacon.beacon"/>

This results in:

AndroidManifest.xml:12:5-15:48 Warning:
        uses-permission was tagged at AndroidManifest.xml:12 to remove other declarations but no other declaration present

The following does work, but it removes the wrong tag, it removes the one in the local Android library we build as part of our app.

 <uses-permission
      android:name="android.permission.ACCESS_COARSE_LOCATION"
      tools:node="remove"/>

The org.altbeacon.beacon permission is left:

~/.android-sdk/build-tools/25.0.3/aapt l -a app-release.apk | grep -B1 COARSE
E: uses-permission-sdk-23 (line=72)
  A: android:name(0x01010003)="android.permission.ACCESS_COARSE_LOCATION" (Raw: "android.permission.ACCESS_COARSE_LOCATION")

Which is unsatisfying because if the permission in org.altbeacon.beacon library chamge, or it is removed in the future, the ACCESS_COARSE_PERMISSION will be missing from our app.

Any suggestions on how to fix this properly?

Suffer answered 1/6, 2017 at 5:8 Comment(3)
I have exact same issue.Camise
I've filed a defect with Google - issuetracker.google.com/issues/62267639Suffer
Funny enough, we are facing the exact same issue with this exact same library right now!Emptyheaded
M
8

In your App manifest file add the below merge rule.

<uses-permission-sdk-23
        tools:node="removeAll" />

Make sure you already added the location permission.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Mckamey answered 3/6, 2017 at 13:59 Comment(2)
This works, but comes with a warning. All uses-permission-sdk-23 tags are removed in all manifests, so ensure you add a uses-permission tag in the main app AndroidManifest.xml for every uses-permission-sdk-23 tag removed in the AndroidManifest.xml files contributed by the library components.Suffer
Android Studio says, that the name attribute is missing: <uses-permission-sdk-23 tools:node="removeAll" /> But when I build it, all is OK.Heartwarming
S
5

Just replace below line to your existing uses permission would solve the issues.

What this causes because you added duplicated permission in manifest but below line split the permission.

<uses-permission
      android:name="android.permission.ACCESS_COARSE_LOCATION"
      android:maxSdkVersion="22"/>
Spirillum answered 1/6, 2017 at 6:6 Comment(2)
This fixed for me! Thx!Camise
That didn't work for me. In the merged AndroidManifest.xml I ended up with both lines still. I see what you were trying to achieve though, the permission from our library would be used upto API level 22, then from API level 23, the permission from altbeacon would be used. Even if it worked, it would not address my concern that a change in altbeacon could now affect our application without warning.Suffer
J
1

As described in this post, you have to specify how the Manifest should handle permissions. You probably included a library that transitively already requires this permission, e.g., READ_PHONE_STATE.

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

If you re-declare this permission in your manifest, it gives a warning, because it does not know how to handle these two declarations (even though they probably just state the same).

If you are willing to forward this permission in you app, you can fix it like this:

<uses-permission tools:node="merge" android:name="android.permission.READ_PHONE_STATE" />

If you are unwilling to forward that permission in your app, you can explicitly remove this permission:

<uses-permission tools:node="remove" android:name="android.permission.READ_PHONE_STATE" />
Juicy answered 29/1, 2020 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.