I'm building an application for Android that is partitioned around SDK version 29. For compatibility reasons, the app must implement a feature differently on SDK versions < 29 and >= 29. These two versions require a different set of permissions. Currently, the application automatically switches the feature depending on the active SDK version. My application is getting rejected by the Play Store because all permissions are declared for both app versions. The >= 29 version for example does not need as many (sensitive) permissions as the < 29 version but is rejected for not actively using these permissions.
I've read about manifest merging, but I'm not sure if it can achieve what I'd like (conditional permission declaration).
I would like to maintain only one apk that handles both app versions. Is it possible to declare conditional manifest permissions, something like:
<if minSdkVersion="29">
<!-- Arbitrary permissions -->
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
</if>
<uses-permission android:name="android.permission.BLUETOOTH" />
Use the built in maxSdkVersion:
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"
android:maxSdkVersion="28"/>
Related
My app (code on GitHub) was rejected by Google Play with reason:
Please remove the background location permission requested and submit an update to your app.
However, my app does not declare the ACCESS_BACKGROUND_LOCATION permission:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS" />
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
I first suspected Mapbox, as my app includes these libraries:
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.1.0'
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:6.1.0'
However my app checks location only when the app is running fully visible on the screen.
Also, the merged manifest shown by Android Studio does not include ACCESS_BACKGROUND_LOCATION:
It seems that setting android:minSdkVersion="29" would circumvent the issue, but I can't do it as I have thousands of important users below that.
I also tried adding a popup disclaiming that the app uses location in the background (even though it does not), but that gets rejected too, with this reason:
It is possible to deliver a similar experience without access to location in the background.
Question: What could be making someone think that I use location in the background?
From the official Privacy changes in Android 10
Access granted automatically when targeting Android 9 or lower
If your app runs on Android 10 or higher but targets Android 9 (API level 28) or lower, the platform applies the following behavior:
If your app declares a <uses-permission> element for either ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION, the system automatically adds a element for ACCESS_BACKGROUND_LOCATION during installation.
If your app requests either ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION, the system automatically adds ACCESS_BACKGROUND_LOCATION to the request.
Access when device is upgraded to Android 10
If a user grants your app access to device location – either ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION – then upgrades their device from Android 9 to Android 10, the system automatically updates the set of location-based permissions granted to your app. The set of permissions that your app receives after the upgrade depends on its target SDK version and its defined permissions, as shown in the following table: here
In other words, it all depends on your Target platform version.
VS 2022 17.1.0
Xamarin Android SDK 12.2.0.4
We have a Xamarin Forms project that includes an Android target. That Android target has recently been updated to have a targetSdkVersion 31 (Android 12)
We are now getting the following errors when trying to upload our Signed APK to Google Play
Duplicate declarations of permission
android.permission.ACCESS_COARSE_LOCATION with different
maxSdkVersions. Duplicate declarations of permission
android.permission.ACCESS_FINE_LOCATION with different maxSdkVersions.
If I look at the signed APK created by VS2022 build I can see these entries in AndroidManifest.xml
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission-sdk-23
android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="30" />
<uses-permission-sdk-23
android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
How can I see what is causing these permission values to be merged into our AndroidManifest?
Our currently released build has a targetSdkVersion of 30 (Android 11) and whilst these duplicate permissions are present in the merged manifest for that relesase, Google Play does not complain.
Other AndroidManifest values that might be important are
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="3.7.0"
android:installLocation="0"
android:compileSdkVersion="31"
android:compileSdkVersionCodename="12"
package="com.OurCompany.OurApp"
platformBuildVersionCode="31"
platformBuildVersionName="12">
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="31" />
OTHER VALUES REMOVED
</manifest>
I finally managed to trace which component was adding ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permission entries.
The only way I found to track it down was from all the entries in the "obj" folder under "lp" e.g. \obj\Debug\120\lp
This was wear the various libraries I was using would unpack themselves. I search that folder for occurences of "ACCESS_COARSE_LOCATION" and that gave me the library name that was the problem
The change I made in our AndroidManifest was
<uses-permission-sdk-23
android:name="android.permission.ACCESS_FINE_LOCATION"
tools:node="remove"
android:maxSdkVersion="30" /
Note the use of the tools:node attribute, the Android docs for this are here, https://developer.android.com/studio/build/manage-manifests
What is the difference between these two syntaxes.
android:uses-permission and uses-permission. For example:
<android:uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The first one was automatically added to the manifest by Android Studio when I created an activity that reads from storage. Also why did it add an android:maxSdkVersion attribute and specifically set it to 18 when I have targetSdkVersion for the project set as 21.
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
Actually this permission is required for API level 18 and lower, Android 4.4 (API level 19), it's no longer necessary for your app to request the WRITE_EXTERNAL_STORAGE permission when your app wants to write to its own application-specific directories on external storage (the directories provided by getExternalFilesDir().
I have an app which makes use of wifi permissions only but ever since I moved to android studio, the compiled apk of my app uses two more extra permissions, that is phone calls/phone id and SD read/write.
I have no idea how and why those permissions have been added to my app but many users complain about that.
My app uses google analytics from google play services and appcompat. I also make use of this line
deviceId = Secure.getString(ctx.getContentResolver(), Secure.ANDROID_ID);
Any ideas? I don't want those extra permissions they scare my users away
Here is the content of manifest file
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="com.android.vending.BILLING" />
Studio is adding permissions appropriate to the classes / features that you are using in your project.
Update
Here is a related question that focuses on manifest merging config
I'm uploading an App to Google Play and there is about 2321 devices not compatibles with it. In order to test it I have setted all uses permissions to false (except openGl, for Maps V2). I'm using a lot of permissions but, for example, as far as I know Sony ST21 (http://www.gsmarena.com/sony_xperia_tipo-4718.php) has all my required features.
This are my required permissions (from Google Play):
android.hardware.CAMERA
android.hardware.camera.AUTOFOCUS
android.hardware.LOCATION
android.hardware.location.GPS
android.hardware.location.NETWORK
android.hardware.TOUCHSCREEN
And this are my permission inside Manifest:
<permission android:name="com.zonaapp.flamencomovil.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.zonaapp.flamencomovil.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
Whats wrong with my Manifest Configuration?
Check your min and max SDK version, those 2321 devices not compatibles with it may goes out of of your min & max sdk version.
So, provide min SDK version as below as and instead of max SDK or target SDK version provide latest android version.
Then it will cover lots of devices.
This has nothing to do with your permissions, you need to check the value of minSdkVersion in your manifest file. If it is very high, then many devices running older versions of Android won't support your app.