android ContextCompat.checkSelfPermission always returns PERMISSION_GRANTED - android

In my android application (minSdkVersion 15), i have to create directory and write files into it. In my AppManifest i am using :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Before creating directory or file, i am checking if permission is allowed or deny, as
boolean isAllow = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
But it is always returning true or PERMISSION_GRANTED, even when someone set deny permission from Settings -> Apps -> Permissions
Why checkSelfPermission is always returning PERMISSION_GRANTED ? Is there any way to check if permission is denied ?
To invoke permission i have used :
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
But its not showing permission Dialogue??

In the new permission model permissions with protection level dangerous are runtime permissions. For apps targeting M and above the user may not grant such permissions or revoke them at any time. For apps targeting API lower than Marshmallow(<23) these permissions are always granted as such apps do not expect permission revocations and would crash. Therefore, when the user disables a permission for a legacy app in the UI the platform disables the APIs guarded by this permission making them a no-op which is doing nothing or returning an empty result or default error.
for more information visit PermissionChecker

For those who develop with Xamarin make sure that you explicitly set the targetSDK version >= 23 in your manifest.
Don't use automatic for your targetSDK!!!

if your targetSdkVersion is minimum 23 then your problem can be solved by code as below:
int permissionCheck = PermissionChecker.checkSelfPermission(getReactApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);

Related

API 26+: WRITE_EXTERNAL_STORAGE permission is always denied

I have switched my app to target API 27 and now it can't be granted WRITE_EXTERNAL_STORAGE permission -- grantResult is always -1.
My app needs this permission since it doesn't use apps private external storage space (which doesn't require WRITE_EXTERNAL_STORAGE starting from API 19).
I know that in API 26 there have been behavior changes for permissions. However this doesn't explain my problem.
I'm requesting both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions in a standard way:
ActivityCompat.requestPermissions(activity, new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, requestCode);
(both permissions are declared via <uses-permission in manifest).
The dialog appears and I click "Allow":
However inside onRequestPermissionsResult callback I'm getting a -1(denied) for WRITE_EXTERNAL_STORAGE (and 0 (granted) for READ_EXTERNAL_STORAGE).
Shouldn't the result be 0 for both since I have requested and, presumably, granted both?
I have tried to request WRITE_EXTERNAL_STORAGE alone, but in this case the dialog doesn't appear at all.
One more detail: I have just checked the merged manifest in build/intermediates/manifests/full/debug and noticed that WRITE_EXTERNAL_STORAGE permission has attribute android:maxSdkVersion="18" (there is no such attribute in my manifest). This could be happening because my app has minApiVersion=21, but I'm not sure.
Somewhere along the line, you are picking up that android:maxSdkVersion="18" attribute. My guess is that it is coming from a library. Check the "Merged Manifest" tab in Android Studio, when you are editing your own manifest. It will have details of what is contributing the various elements and attributes.
android:maxSdkVersion has the effect of removing your <uses-permission> element on higher Android SDK versions, at least in terms of how runtime permissions work.
Since you need this permission for all versions, adding tools:remove="android:maxSdkVersion" on the <uses-permission> element should revert the android:maxSdkVersion="18" and give you what you expect.
I noticed a space in my permission in manifest, it was <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE "/> and I changed it to <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> and problem solved.

Android 6 (23) - no permission requested

I stucked on new permission model in the Android 6.
I defined following permissions in the manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application...
But if i launched the app in the emulator and opened the app detail i saw the following :
It says that app does not require any permission.
How can i solve it please?
Many thanks for any advice.
It says that app does not require any permission.
That is correct. That portion of your app's page lists dangerous permissions. None of yours have a protectionLevel of dangerous.
How can i solve it please?
There is nothing wrong, and so there is nothing to solve.
Until Android 6.0, There are some permissions that will be automatically granted at install time and will not be able to revoke. We call it Normal Permission (PROTECTION_NORMAL). Here is the full list of them:
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
Just simply declare those permissions in AndroidManifest.xml and it will work just fine. No need to check for the permission listed above since it couldn't be revoked.
as #Saini said, Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
But if you choose targetSdkVersion lower than 23, your application will be treated like before and will ask user to grant permission to the app when they want to install application. you could read more from here
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.
For more info: https://developer.android.com/training/permissions/requesting.html
https://developer.android.com/training/permissions/declaring.html
https://developer.android.com/training/permissions/best-practices.html
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
In addition to https://stackoverflow.com/a/42697645/984471
Here is the protection_normal permissions link:
https://developer.android.com/guide/topics/permissions/overview#normal_permissions
And the comparison between old and new, normals

Android Program request permissions

I am trying to use GPS in android but it gives me this error:
I put in manifest these permission
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
can anyone help me please
As the hint suggests : The user may deny permission. In that case this call will throw error...
Right now, android asks for the user to accept all the permissions an app asks for in the manifest on installation. In the upcoming M release, android will switch over to the iOS style of permissions with an "on needed" basis.
Call this method to see if permission is granted or not. If not, you need to handle that situation.
context.checkCallingPermission(permission)
Declaring permission in manifest only means that you are requesting permission. In new releases it will not guarantee that user will give you that permission.
In older releases the user has to accept all or reject all permissions
This is not an error actually but a heads-up by the Lint and which may cause an issue!
Hope you are aware about the new permission model is introduced in Android 6.0 (Marshmallow), through which user may not permit to use GPS or Network or anything else and so it may cause an issue in your application!
Now, as per the lint analysis, so before implementing particular functionality, you should check whether permission for the same is available or not!
Since SDK 23, you should/need to check the permission using checkSelfPermission
http://developer.android.com/reference/android/support/v4/content/ContextCompat.html
for example
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
This condition checks user allowed to access the permission to read the location
if(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED||checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER,meter,mill,new locationlist(this));
}

checkSelfPermission() doesn't seem to work for WRITE_EXTERNAL_STORAGE

I have the app that uses
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
It's automatically granted on Android 6.0, but I can revoke it in the settings.
Wanted to check if it's granted in case user revokes it, so I do this:
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
//OK permission granted, let's do stuff
} else {
//I'll better ask for permission
}
Funny thing is that the condition is ALWAYS fulfilled, even the permission was revoked manually. And the the app fails... It looks like a bug to me, is it or am I missing something?
You are missing something: a targetSdkVersion of 23 or higher.
If your targetSdkVersion is 22 or lower, you have no ability to determine whether a permission was granted or revoked by the user from Settings.

Grant permission required for EXTERNAL_STORAGE in Android M?

Will the Android permissions WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE trigger the new grant permission dialog of Android M?
I agree with Guillaume Perrot 's answer. I have met the similar question when I write the permission of READ_WRITE_EXTERNAL_STORAGE in AndroidManifest.xml
with no permissions showing up in the app by default , people need to switch the toggle button of storage in the app permissions.Then I modify my targetSdkVersion in build.gradle to less than 23(MNC) and other number related with sdkVersion, the app installed with the permissions on.
The other way is to write requestpermission function in the place that you need the permisson. The code is as follow:
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)==
PackageManager.PERMISSION_GRANTED) {
//do the things} else {
requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
AnyNumber);
Because I have less than 15 reputation so I can't vote for the Guillaume Perrot 's answer.Just use this way to show my idea.
I solved add this if check version for Android M
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
My answer is based on my tests on M Preview SDK version 2, using an emulator.
If you target MNC preview API level, WRITE_EXTERNAL_STORAGE is not granted by default and will be part of the new dynamic permission API.
You will see the storage permission as a toggle button in the new app permissions menu in device settings, and you can use Activity.requestPermissions to show the popup for that permission.
However if you target api level < MNC, it won't be classified as a dangerous permission, and thus will be granted without a way for the user to disable it (not showing up in permission settings), and you will not be able to compile code using Activity.requestPermissions anyway as the preview SDK enforces minSdkVersion="MNC" to use the new APIs.
This is a different behavior than location permissions: whatever the API level you target, the user will be able to turn location off in permission menu.
For the permission menu itself, the permission toggle state is ON by default if:
Target API level < MNC.
Target API level = MNC but you upgrade app on device from a previous install where target API level was less than MNC.
Otherwise you will see the toggle as OFF by default.
Hope it helps.
According to the docs:
Limited Permissions Granted at Install Time: When the user installs or updates the app, the system grants the app all permissions that the app requests that fall under PROTECTION_NORMAL.
So because READ_EXTERNAL_STORAGE is falling under PROTECTION_NORMAL , it won't trigger the dialog.
But because the level of WRITE_EXTERNAL_STORAGE is PROTECTION_DANGEROUS, it will fall under this behavior as described in docs:
User Grants Permissions at Run-Time: When the app requests a permission, the system shows a dialog to the user, then calls the app's callback function to notify it whether the permission was granted. If a user grants a permission, the app is given all permissions in that permission's functional area that were declared in the app manifest
Here is the sources for the protection level:
detailed list
According to Android docs you don't need to request permission about read and write external storage.
Edit: in the latest Android M release you need to ask for both read and write permissions
Storage permission falls under dangerous protection level, So all the dangerous protection level permissions will not be granted at install time in Android M, if App target SDK is set to 23. They will be given at run time.
And yes these permissions can be revoked at run time also.
No permission dialog will not be triggered automatically, you need to do a request by using API such as requestPermissions() method to show that native dialog.
Please check the dangerous level permission list here

Categories

Resources