checkSelfPermission返回PERMISSION_GRANTED以取消targetSdkVersion <= 22的权限

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (35)

我正在研究Android Marshmallow的新许可模式,但我面临一个我觉得奇怪的问题。

具有targetSdkVersion22个应用程序(因此尚未使用Android Marshmallow的新许可模型)READ_CONTACTS在清单中声明权限:

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

并尝试通过以下方式阅读联系人的电话号码Intent.ACTION_PICK

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

在使用Marshmallow MRA58K的设备上运行时,在通过ADB安装应用程序后撤销权限后,该ContextCompat.checkSelfPermission()方法仍会返回PERMISSION_GRANTED,但由于没有记录的游标被返回,因此访问联系人时操作失败。据我了解,这是避免传统应用程序崩溃的默认“retrocompatibility”策略。

@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);
    }
}

如何在尝试操作之前安全地检测用户是否明确地在权限之前?

我还尝试了https://github.com/googlesamples/android-RuntimePermissions中的官方Google示例,将targetSdkVersion结果设置为22,结果相同:即使用户将其撤销,也会授予权限,然后操作失败。

谢谢 ;)

提问于
用户回答回答于

为了使用新的权限模型(并检查应用程序是否具有该权限),你需要将目标SDK更新为23。保持目标22没有任何意义。

扫码关注云+社区