ActivityCompat.requestPermissions not showing dialog box
Asked Answered
G

24

115
if (ContextCompat.checkSelfPermission(RegisterActivity.this,      Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE_PERMISSION);

i'm trying to use this function on nexus 5 api 23 and its just not showing me the dialog box like its supposed to do, it's just not doing anything. what could cause the problem? (this code is in the java activity) i tried changing my minimum api to 23 and use the requestPermissions() without the ActivityCompat but still not working.

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {
    applicationId "com.example.idanayzen.photomap"
    minSdkVersion 23
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
}

and the Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.idanayzen.photomap">

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">


    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps" />
    <activity android:name=".RegisterActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".WrongPhoneNum"></activity>
</application>

</manifest>
Garwood answered 18/2, 2016 at 14:54 Comment(2)
btw i already tried to change the string to "android.permission.READ_PHONE_STATE" still the sameGarwood
Is the permission is blocked?Triumphant
O
112

Here's an example of using requestPermissions():

First, define the permission (as you did in your post) in the manifest, otherwise, your request will automatically be denied:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Next, define a value to handle the permission callback, in onRequestPermissionsResult():

private final int REQUEST_PERMISSION_PHONE_STATE=1;

Here's the code to call requestPermissions():

private void showPhoneStatePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.READ_PHONE_STATE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.READ_PHONE_STATE)) {
            showExplanation("Permission Needed", "Rationale", Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
        } else {
            requestPermission(Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
        }
    } else {
        Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
    }
}

First, you check if you already have permission (remember, even after being granted permission, the user can later revoke the permission in the App Settings.)

And finally, this is how you check if you received permission or not:

@Override
public void onRequestPermissionsResult(
        int requestCode,
        String permissions[],
        int[] grantResults) {
    switch (requestCode) {
        case REQUEST_PERMISSION_PHONE_STATE:
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
            }
    }
}

private void showExplanation(String title,
                             String message,
                             final String permission,
                             final int permissionRequestCode) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    requestPermission(permission, permissionRequestCode);
                }
            });
    builder.create().show();
}

private void requestPermission(String permissionName, int permissionRequestCode) {
    ActivityCompat.requestPermissions(this,
            new String[]{permissionName}, permissionRequestCode);
}
Osmose answered 18/2, 2016 at 15:52 Comment(11)
isn't it useless to do all of this checking if the requestPermissions is not working? in my code im just checking if i have the permission and if not i call the requestPermissions. and later i guess ill change that. and i did the requestPermissions syntax exactly as you said but its not working for me.Garwood
Since you didn't post your actual requestPermissions() code, I posted a complete working example. Works fine for me.Osmose
I posted my actual requestPermissions() code just now. thank you for your help :)Garwood
You're code works for me as well... are you sure you haven't already given yourself permission? (You can go in to Settings | App | click our app and check the Permissions.)Osmose
I just checked and the permissions are turned off. it's really weird that it works for you and not for meGarwood
Your device or emulator is running Android 6.0, right? (I know these are basic questions, but always the best place to start ;)) Actually, you couldn't turn off the permission if you weren't. Have you tried making a new app, just to isolate the issue?Osmose
Glad you have it working, but not knowing why something doesn't work always bugs me.Osmose
@NightSkyDev - what are the requestPermission and showExplanation methods in your example?Lossa
@Lossa - Added both to the example. As you can see, it would be just as easy to call requestPermission directly, and you would need to if you are requesting multiple permissions as this method is just a wrapper to call one permission.Osmose
thanks for highlighting the "First, define the permission (as you did in your post) in the manifest, otherwise, your request will automatically be denied". Mine was like this <uses-permission android:name="android.permission.GET_ACCOUNTS" android:maxSdkVersion="22" tools:replace="maxSdkVersion" /> I changed the "22" to "23"Canny
@NightSkyDev pretty good answer. Thanks, solved my issue as wellSwart
C
60

I had the same issue and it turned out to be due to the manifest merger tool pulling in an android:maxSdkVersion attribute from a dependency.

To view the actual permissions you're requesting in your APK you can use the aapt tool, like this:

/path/to/android-sdk/build-tools/version/aapt d permissions /path/to/your-apk.apk

in my case, it printed:

uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'

even though I hadn't specified a maxSdkVersion in my manifest. I fixed this issue by changing <uses-permission> in my manifest to:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>

(where the tools namespace is http://schemas.android.com/tools)

Classmate answered 23/11, 2016 at 23:8 Comment(2)
@usman its not necessary that it should work for all, may be your case is different. Please post your question, someone surely resolve your problem :)Spina
as of now at least, to view the actual permission (merged) manifest, you can view it without any other tools like aapt. While you see your AndroidManifest.xml from Android Studio, look at the bottom tab, just click on the Merged Manifest tab.Unaccountable
A
31

I had a need to request permission for WRITE_EXTERNAL_STORAGE but was not getting a pop-up despite trying all of the different suggestions mentioned.

The culprit in the end was HockeyApp. It uses manifest merging to include its own permission for WRITE_EXTERNAL_STORAGE except it applies a max sdk version onto it.

The way to get around this problem is to include it in your Manifest file but with a replace against it, to override the HockeyApp's version and success!

4.7.2 Other dependencies requesting the external storage permission (SDK version 5.0.0 and later) To be ready for Android O, HockeySDK-Android 5.0.0 and later limit the WRITE_EXTERNAL_STORAGE permission with the maxSdkVersion filter. In some use cases, e.g. where an app contains a dependency that requires this permission, maxSdkVersion makes it impossible for those dependencies to grant or request the permission. The solution for those cases is as follows:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>

It will cause that other attributes from low priority manifests will be replaced instead of being merged.

https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk#permissions-advanced

Astri answered 14/11, 2017 at 10:21 Comment(2)
Thank you, It was my problem all this day.Reseau
This solved my problem. Thank you so much!Farmyard
P
16

It could be not a problem with a single line of your code.

On some devices (I don't recall if it is in stock Android) the Permission dialog includes a check box labeled "Never ask again". If you click Deny with the box checked then you won't be prompted again for that permission, it will automatically be denied to the app. To revert this, you have to go into Settings -> App -> Permissions and re--enable that perm for the app. Then turn it off to deny it again. You may have to open the app before turning it off again, not sure.

I don't know if your Nexus has it. Maybe worth a try.

Perfusion answered 13/11, 2018 at 3:51 Comment(1)
I had this situation. The best way out I could think of was to check for PackageManager.PERMISSION_DENIED in onRequestPermissionsResult() and adjust the UI to explain the user that the permissions had to be manually set and open Settings.ACTION_APPLICATION_DETAILS_SETTINGS.Mannerly
R
15

Replace:

ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.READ_PHONE_STATE"}, 225);

with:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);

The actual string for that permission is not "Manifest.permission.READ_PHONE_STATE". Use the symbol Manifest.permission.READ_PHONE_STATE.

Roseline answered 18/2, 2016 at 15:16 Comment(2)
not work for me. my app is configured to work from 16 to 23 sdk versionProjector
you should use android.Manifest.permission.READ_PHONE_STATEOsteopathy
O
5

In my case, target sdk 33 to 32 solves it

Overt answered 31/1, 2023 at 19:20 Comment(3)
Instead of simply providing the answer directly, try writing a detailed comment that explains the solution, as long as the explanation is not too lengthy.Autogenesis
This worked for me as well. Not sure why, but at least i know its related to target sdk and can investigate further.Udder
I agree @DSDmark. I will try to add from now on.Overt
G
4

Here is another experience I'd like to share with you guys. The problem showed up after I implemented the following code to check for BLE access permission:

final String requiredPermission = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) ?
            android.Manifest.permission.ACCESS_FINE_LOCATION :
            android.Manifest.permission.ACCESS_COARSE_LOCATION;

I meant to distinguish between FINE and COARSE location permission requests, both had been defined in the manifest. When checking for ACCESS_COARSE_LOCATION permission, the "Request permission" dialog never poped up but onRequestPermissionsResult was always called with PERMISSION_DENIED (in case permission was not enabled in app settings). So I removed the check for BUILD.SDK and checked only for ACCESS_FINE_LOCATION and voilla the missing dialog showed up.

final String requiredPermission = android.Manifest.permission.ACCESS_FINE_LOCATION;

did the trick.

The Manifest source contains:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

but the apk contained android.permission.ACCESS_FINE_LOCATION only. Sometime during build, the ACCESS_COARSE_LOCATION had been removed.

I hope this might help somebody having the same issue.

Geiss answered 11/3, 2020 at 13:44 Comment(0)
A
3

I updated my target SDK version from 22 to 23 and it worked perfectly.

Alberto answered 20/4, 2017 at 20:3 Comment(1)
Yes, but that wasn't random luck. The reason why is that 23 is when Android started interpreting <uses-permission> as a future code action instead of an on-install demand.Vide
S
3

Don't forget to write the permissions without extra spaces in the manifest. In my case, I had:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />

But look, at the end, there's an extra space. Just write it the right way:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

And it's working now.

Scurry answered 1/10, 2019 at 17:33 Comment(0)
U
3

For me, this was related to them getting more granular with permissions in 33, related to requesting read_external_storage.

This is the kotlin code I'm using to check and request access in Jan 2023.

private fun checkPermissions():Boolean{
        // version 33 gets more granular
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES)
                != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(
                    this, arrayOf(
                        Manifest.permission.READ_MEDIA_IMAGES,
                        Manifest.permission.READ_MEDIA_VIDEO // why isn't this plural too
                    ),
                    1
                )
                return false
            }
        }else{
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(
                    this, arrayOf(
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    ),
                    1
                )
                return false
            }
        }
        return true
    }

I also had to add all 3 of these to my manifest, to support apis 31-33.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"  />    
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"  />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"  />
Udder answered 3/2, 2023 at 0:27 Comment(0)
L
2

No matter what you do, Check if you declare Permission you need in the Manifest file.


    <!--Declaring the required 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.CAMERA" />


Then go to next steps..

Laquanda answered 28/1, 2020 at 16:27 Comment(0)
G
2

I followed the top answer, but still didn't work. This simple issue wasted me many days. For my case, I'm trying to get access for MANAGE_EXTERNAL_STORAGE. At the end, I found for this particular permission, we can't use ActivityCompat.requestPermissions(), instead I have to use Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION. And to check if the permission is there, we also need to use a different API: Environment.isExternalStorageManager() instead of ContextCompat.checkSelfPermission(), not sure why they design in such an inconsistent way cause so much confusions.

I get my issue resolved following: How to obtain MANAGE_EXTERNAL_STORAGE permission

And also this is mentioned in SDK document of: manage-all-files.

Goddaughter answered 7/3, 2022 at 4:44 Comment(1)
life saver.. no one tells u how messed up things are than they actually look :)Seleucid
S
1

For me the issue was requesting a group mistakenly instead of the actual permissions.

Sluiter answered 12/7, 2016 at 10:18 Comment(0)
V
1

The above information is good, but setting targetSdkVersion to 23 (or higher) is critical for Android to interpret the <uses-permission> tag in the manifest as "I will ask in code" instead of "I demand upon installation." Lots of sources will tell you that you need the <uses-permission> tag, but no one says why and if you don't have that value set, you're going to be as confused as I was for hours on end.

Vide answered 11/9, 2017 at 8:6 Comment(0)
S
1

I came across this problem in Samsung S8 and N8 (havent found in any other)

so the problem is in the manifest file uses-permission

<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true" />

For some reason, the attribute android:requiredFeature is the culprit. and I haven't found the explanation on why.

to solve simply remove it,

<uses-permission android:name="android.permission.CAMERA" />
Seditious answered 29/8, 2018 at 7:4 Comment(0)
I
0

I had this same issue.I updated to buildToolsVersion "23.0.3" It all of a sudden worked. Hope this helps anyone having this issue.

Illusage answered 19/5, 2016 at 3:34 Comment(0)
E
0

I was having the same problem, and solved it by replacing Manifest.permission.READ_PHONE_STATE with android.Manifest.permission.READ_PHONE_STATE.

Endres answered 11/5, 2017 at 5:0 Comment(0)
J
0

For me the issue was I had an invalid request code. I choose 0xDEADBEEF as a request code and it was silently failing (maybe it's cast to something smaller than 32-bit somewhere internally?) If I choose 255 everything worked fine as NightSkyDev described above.

Johnny answered 18/7, 2017 at 19:22 Comment(1)
The docs state that requestCode, should be ≥ 0. 0xDEADBEEF is < 0.Northcutt
L
0

This just happened to me. It turned out I was requesting ALL permissions, when I needed to filter to just DANGEROUS permissions, and it suddenly started working.

fun requestPermissions() {
    val missingDangerPermissions = PERMISSIONS
            .filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }
            .filter { this.getPackageManager().getPermissionInfo(it, PackageManager.GET_META_DATA).protectionLevel == PermissionInfo.PROTECTION_DANGEROUS } // THIS FILTER HERE!

    if (missingDangerPermissions.isNotEmpty()) {
        Log.i(TAG, "Requesting dangerous permission to $missingDangerPermissions.")
        ActivityCompat.requestPermissions(this,
                missingDangerPermissions.toTypedArray(),
                REQUEST_CODE_REQUIRED_PERMISSIONS);
        return
    } else {
        Log.i(TAG, "We had all the permissions we needed (yay!)")
    }
}
Leash answered 22/9, 2017 at 17:57 Comment(1)
where do you get the variable of ContextCompat? I tried but variable not foundresult?Penitence
G
0

For me the error was in the manifest: the permission was in uppercase. Android Studio suggest me the permissions in uppercase. I don't care about that and it took me two hours to fixe this problem.

The right syntaxe for permission is
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Ginkgo answered 16/10, 2017 at 17:52 Comment(0)
K
0

For me the problem was that right after making the request, my main activity launched another activity. That superseded the dialog so it was never seen.

Kingofarms answered 20/3, 2019 at 12:12 Comment(2)
Hi buddy, I think this is my case, did you manage to solve it?Rita
Just change the flow of events in the app. Do NOT launch another activity right after you request a permission!Kingofarms
S
0

TL;DR: Add the following to your Manifest file:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion" />

Check this article, it fixed it for me:

https://nphau.medium.com/android-request-permissions-not-showing-a-dialog-box-b7f2067d7b09

Seringa answered 17/5, 2022 at 15:0 Comment(0)
J
-1

it happen to me i was running it on API 23 and i had to use the code to request permission like this code below put it on on create method. note that MY_PERMISSIONS_REQUEST_READ_LOCATION is an integer that is equal to 1 example int MY_PERMISSIONS_REQUEST_READ_LOCATION = 1:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION},MY_PERMISSIONS_REQUEST_READ_LOCATION); }

Josephus answered 17/3, 2018 at 3:41 Comment(0)
A
-4

Maybe this solution could help anyone rather than:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

use :

ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

so we add android. to Manifest.permission.WRITE_EXTERNAL_STORAGE

Ashleighashlen answered 23/1, 2019 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.