Search code examples
androidandroid-gradle-plugingoogle-playaltbeacon

Android Manifest Duplicate Permissions


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?


Solution

  • 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" />