WRITE_EXTERNAL_STORAGE still required with KitKat? - android

As mentioned in the documentation, the WRITE_EXTERNAL_STORAGE permission should not be a requirement starting from API level 19. Hence, I've written this to the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
However, when running my app which uses Google Maps V2 and thus needs access to the external storage, I get a SecurityException:
java.lang.SecurityException: The Maps API requires the additional following permissions to be set in the AndroidManifest.xml to ensure a correct behavior:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
The phone I'm running the app is KitKat (4.4) which is API level 19. To my understanding, the app should be able to run fine without the permission. Why do I get the error anyway?

the WRITE_EXTERNAL_STORAGE permission should not be a requirement starting from API level 19
Only if you are using methods on Context, like getExternalFilesDir(), to get at standard locations on external storage that are specific for your app. For other locations, such as the paths reported by methods on Environment, you still need the permission.
Or, to quote the documentation that you linked to:
For example, beginning with 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()).
Also, third-party libraries are welcome to require that you have this permission for their own reasons.
Why do I get the error anyway?
It looks like MapsV2 is validating that you have the permission as part of its setup process. That is the prerogative of MapsV2. Perhaps they are looking to work with external storage outside of the limited areas that do not require this permission. Perhaps they aren't but failed to update the permission check in their code. MapsV2, being closed source, is difficult to analyze for this sort of thing.

According to the WRITE_EXTERNAL_STORAGE documentation (emphasis mine):
Starting in API level 19, this permission is not required to
read/write files in your application-specific directories returned by
getExternalFilesDir(String) and getExternalCacheDir().
The Google Maps API is presumably using directories on the external storage that are not specific to your application, and thus you need to include the permission for all API levels.

Related

Google says requestLegacyExternalStorage flag is detected, but my app doesn't use it

I'm receiving this email in apps compiled with api 29 and api 30.
These apps does not contains requestLegacyExternalStorage flag and does not contains MANAGE_EXTERNAL_STORAGE.
I already searched in manifest merger log, and in the final merged manifest, and didn't found requestLegacyExternalStorage flag inside.
These apps only have the old and deprecated WRITE_EXTERNAL_STORAGE in AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Is that old and deprecated permission which is firing that warning from google? is enough with removing that permission from my apps to get this issue solved?
Starting May 5th, you must let us know why your app requires broad
storage access
We've detected that your app contains the
requestLegacyExternalStorage flag in the manifest file of 1 or more of
your app bundles or APKs.
Developers with apps on devices running Android 11+ must use Scoped
Storage to give users better access control over their device storage.
To release your app on Android 11 or newer after May 5th, you must
either:
Update your app to use more privacy friendly best practices, such as
the Storage Access Framework or Media Store API
Update your app to declare the All files access
(MANAGE_EXTERNAL_STORAGE) permission in the manifest file, and
complete the All files access permission declaration in Play Console
from May 5th
Remove the All files access permission from your app entirely
For apps targeting Android 11, the requestLegacyExternalStorage flag
will be ignored. You must use the All files access permission to
retain broad access.
Apps requesting access to the All files access permission without a
permitted use will be removed from Google Play, and you won't be able
to publish updates.

Delay android requesting permissions

I have an app which contains <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Is there a way to delay asking the user for the location permission until they take an account which requires it? I've tried removing uses-permission from the XML, this breaks location even after programmatically asking for location permissions.
I do programmatically ask for location info, but that only seems to work if the permission is also specified in the XML.
I am assuming that you are experiencing this as you're targeting below Android 6.0?
As per the docs
Android 6.0 Marshmallow introduced a new permissions model that lets
apps request permissions from the user at runtime, rather than prior
to installation. Apps that support the new model request permissions
when the app actually requires the services or data protected by the
services.
Therefore, you will be unable to avoid requesting permissions before the user actually needs to use that particular service, unless you target a higher API level.
If you need permission, you can not remove it from manifest. If your target API is above 23 (Android 6) Just ask for permission programmatically when you need it. You as developer determine when to ask for permissions.
Otherwise if user's device is below android 6 or if your target API is below 23 then permissions will be requested at install time and you can not change it.

What does whitelisted mean for WRITE_EXTERNAL_STORAGE?

The docs for WRITE_EXTERNAL_STORAGE permission say:
If this permission is not whitelisted for an app that targets an API
level before Build.VERSION_CODES.Q this permission cannot be granted
to apps.
What does that mean and how can a permission be "whitelisted"?
In the context to which you are speaking, some apps that target certain permissions get "grandfathered".
Per the permission docs:
Over time, new restrictions may be added to the platform such that, in order to use certain APIs, your app must request a permission that it previously did not need. Because existing apps assume access to those APIs is freely available, Android may apply the new permission request to the app's manifest to avoid breaking the app on the new platform version (thereby, "grandfathering" your app for the permission). Android makes the decision as to whether an app might need the permission based on the value provided for the targetSdkVersion attribute. If the value is lower than the version in which the permission was added, then Android adds the permission.
For example, the READ_EXTERNAL_STORAGE permission is enforced beginning with API level 19 to restrict access to the shared storage space. If your targetSdkVersion is 18 or lower, this permission is added to your app on newer versions of Android.

Google Drive API Manifest Permissions

this isn't really a big problem. I've got an Android App that stores user's passwords on a SQLite Database. So last week I launched an update that allows the user to export those passwords to their Google Drive. To do this, I've used the Google Drive Android API. I didn't add any special permission to the Application Manifest (AndroidManifest.xml) and it works fine (tested on KitKat4.4). But one of my friends told me that it might not work on Android 6.0+, because I should always ask for permissions. But I checked some samples and none of them had those permissions on the Manifest. Do you guys think it's necessary to add permissions? Perhaps INTERNET or GET_ACCOUNTS?
If you are using the Google Drive Android API you don't need INTERNET or GET_ACCOUNTS permissions.
The API automatically handles previously complex tasks such as offline access and syncing files. This allows you to read and write files as if Drive were a local file system.
Check the official Quickstart and the demos sample on GitHub. None of them is having special permissions in the AndroidManifest.xml.
BUT if you are using the Google Drive REST API for Android then you need INTERNET permission for sure.
If you follow the tutorials on Drive API using Android, you will see in the Step 4:Prepare the project that you need to add the permissions below in your code.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
The permission "android.permission.INTERNET" is used if you want your application to connect/perform network operation.
For the "android.permission.GET_ACCOUNTS", it's stated in this documentation that:
Note: Beginning with Android 6.0 (API level 23), if an app shares the
signature of the authenticator that manages an account, it does not
need "GET_ACCOUNTS" permission to read information about that account.
On Android 5.1 and lower, all apps need "GET_ACCOUNTS" permission to
read information about any account.
For more information about different meaning/uses of android permission, check this page.
According to the Google Maps API documentation, INTERNET and ACCESS_NETWORK_STATE permissions will be automatically merged to project's manifest, meaning you don't have to specify them by yourself as long as calling API over Google Play services.
Couldn't find the same description for Google Drive API, though.

Determining the level of Android permission

I have some Android permissions which I would like to know to which permision PROTECTION LEVEL they belong. Does anybody know how can this be checked? For example I need to know the PROTECTION LEVEL of android.permission.RECEIVE_BOOT_COMPLETED permission, but I would like to check many more.
EDIT:
I see that I didn't put it clearly: What I mean is not an API level with which permission was introduced, but permission protection level, one of four: Normal, Dangerous, Signeture, Signature Or System. It determines for example how this permission is presented to user during the application installation. How can I check to which protection level certain permission belongs?
A list of default permissions with the associated protection levels can be found in the latest source here:
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml
Example:
<permission android:name="android.permission.INTERNET"
android:permissionGroup="android.permission-group.NETWORK"
android:protectionLevel="dangerous"
android:description="#string/permdesc_createNetworkSockets"
android:label="#string/permlab_createNetworkSockets" />
Keep in mind they could be changed by the OEM.
getPackageManager().getPermissionInfo(name, 0).protectionLevel
In this link you can see all the permissions of android.
The level you mark it here:
For Android-Permission..
To enforce permissions, various parts of the system invoke a
permission validation mechanism to check whether a given application
has a specied permission. The permission validation mechanism is
implemented as part of the trusted system process, and invocations of
the permission validation mechanism are spread throughout the API.
There is no centralized policy for checking permissions when an API
is called. Rather, mediation is contingent on the correct placement
of permission validation calls.
Permission checks are placed in the API implementation in the system
process. When necessary, the API implementation calls the
permission validation mechanism to check that the invoking
application has the necessary permissions. In some cases, the API
library may also redundantly check these permissions, but such checks
cannot be relied upon: applications can circumvent them by directly
communicating with the system process via the RPC stubs. Permission
checks therefore should not occur in the API library. In- stead, the
API implementation in the system process should invoke the permission
validation mechanism.
Also just go through with this documents for more info Android-Permission
You can find the protection level in the permission documentation

Categories

Resources