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().
Related
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
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"/>
Here's the scenario. My app (A) is using a library (B).
My app (A) is using permission READ_PHONE_STATE and it's declared in manifest.xml as
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
While library (B) is also using the same permission READ_PHONE_STATE, but with maxSdkVersion set to 22.
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
android:maxSdkVersion="22"/>
So now the problem is when app is built and in the final _merged_manifest_ I'm having maxSdkVersion="22" set, and because of this my current device which is running nougat can't request for this particular permission.
Currently I found a solution to override this value in my app (A) manifest.xml
<uses-permission
tools:replace="android:maxSdkVersion"
android:name="android.permission.READ_PHONE_STATE"
android:maxSdkVersion="28"/>
But this requires me to update maxSdkVersion every time I update the sdk version in my app (A).
So my question is
Is there a way to ignore maxSdkVersion set by library (B) using some namespace in my manifest.xml like tools:ignore
Set maxSdkVersion to latest sdkVersion in build.gradle automatically without manually changing it
Use tools:remove attribute on your own AndroidManifest.xml:
<uses-permission
android:name="android.permission.READ_PHONE_STATE"
tools:remove="android:maxSdkVersion"/>
In my project I have two permissions:
android.permission.USE_CREDENTIALS
android.permission.MANAGE_ACCOUNTS
that was removed in API Level 23 https://developer.android.com/sdk/api_diff/23/changes/android.Manifest.permission
Does that mean I can remove them if my targetSdkVersion is 23 or higher or minSdkVersion must be 23?
No you need to add android:maxSdkVersion="22" to these both permissions. Like below
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" android:maxSdkVersion="22"/>
Everything every Android Developer must know about new Android's Runtime Permission is a very good article for more info. And found Android M Permissions: Missing some of the old ones similar to your issue.
I noticed the READ_PHONE_STATE permission when I uploaded the apk to google play.
I have not added it and it is not written anywhere in my manifest or any other file of my project. (I looked through all libraries for this permission)
My app did not have this permission in my previous build with same libraries. Since last build I updated android studio to version 1, updated my android sdk and made a few changes (in code) to my app. I don't request the device ID in my app.
My app has minSDK 14 and no ads.
Here are my manifest permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Here's the apk file
I was able to resolve the problem. It's similar to the solution of reneph.
I found that one library had no minSDK specified neither in the build.gradle nor in the manifest file. After adding
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
}
the permission was gone. I don't know why it worked without the permission on my previous build (also no minSDK specified). Must have been either the Android Studio 1.0 or the Android SDK update.
Android developer documentation for READ_PHONE_STATE permission:
Note: If both your minSdkVersion and targetSdkVersion values are set to 3 or lower, the system implicitly grants your app this permission. If you don't need this permission, be sure your targetSdkVersion is 4 or higher.
I found the issue.
I had another library included that had minSdkVersion="4" (its not my library, but my app requires minSdkVersion="14").
I just changed the minSdkVersion of the additional library to 14 and the permission disappeared!
I declared the following permissions in my app:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<permission-group android:name="android.permission-group.STORAGE" />
--- WORKED FOR ME!--
I tried so many things on manifest, which mentioned here and other forums.
At the last, I noticed that the error message, The apk upload error message wants to add "Privacy Policy URL" into Store listing / Privacy policy section. (which checked "Not submitting a privacy policy URL at this time").
So, I add my privacy policy URL from my website, then submit. later, I successfully uploaded my apk.
One cause could be a (transitive) dependency, i.e. a library, that declares a minimum required Android SDK level below 4. In this case the "manifest merger tool" will add those permissions implicitly.
Lower-priority manifest declares Permissions added to the merged manifest
targetSdkVersion <= 3 WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
targetSdkVersion <= 15 and using READ_CONTACTS READ_CALL_LOG
targetSdkVersion <= 15 and using WRITE_CONTACTS WRITE_CALL_LOG
Source: https://developer.android.com/studio/build/manifest-merge#implicit_system_permissions
Look into the manifest-merger-*-report.txt log, found in build/outputs/logs if this was case.