Venator85
Venator85

Reputation: 10335

checkSelfPermission returning PERMISSION_GRANTED for revoked permission with targetSdkVersion <= 22

I'm studying the new permission model of Android Marshmallow but I'm facing an issue I find odd.

An app with targetSdkVersion 22 (so not yet using the new permission model of Android Marshmallow) declares the READ_CONTACTS permission in the manifest:

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

and tries to read the phone number of a contact via Intent.ACTION_PICK:

Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT_REQUEST);

When running on a device with Marshmallow MRA58K, after I revoke the permission after installing the app via ADB, the ContextCompat.checkSelfPermission() method still returns PERMISSION_GRANTED, but the operation fails later when accessing the contacts because a cursor with no records is returned. As I understood, this is the default "retrocompatibility" strategy to avoid legacy app to crash.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == PICK_CONTACT_REQUEST && resultCode == Activity.RESULT_OK) {
        Log.i("", "Permission granted: " + (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED));
        Uri contactUri = data.getData();
        Cursor c = null;
        try {
            c = getContentResolver().query(contactUri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null);
            if (c != null && c.moveToFirst()) {
                Log.i("", "got phone number: " + c.getString(0));
            } else {
                Log.w("", "No data received");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (c != null) {
                c.close();
            }
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

How can I safely detect if the user explicitly before the permission before attempting the operation?

I also tried the official Google sample at https://github.com/googlesamples/android-RuntimePermissions setting the targetSdkVersion to 22 with the same result: it logs that the permission is granted even if the user revoked it, ant then the operation fails.

Thanks ;)

Upvotes: 18

Views: 8052

Answers (2)

hans
hans

Reputation: 124

Use the android.support.v4.content.PermissionChecker

https://developer.android.com/reference/android/support/v4/content/PermissionChecker.html

Upvotes: 10

greywolf82
greywolf82

Reputation: 22173

In order to use the new permission models (and checking if your app has or not the permission) you need to update your target SDK to 23. It doesn't make any sense to keeping target 22.

Upvotes: 0

Related Questions