权限拒绝异常,即使正确的权限已添加到清单?

Permission denial exception, even though correct permissions have been added to the Manifest?

我正在创建一个从 Android phone 获取所有姓名和号码的方法。

private void getContactList() {
    Cursor contacts = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    String aNameFromContacts[] = new String[contacts.getCount()];
    String aNumberFromContacts[] = new String[contacts.getCount()];
    int i = 0;

    int nameFieldColumnIndex = contacts.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
    int numberFieldColumnIndex = contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

    while(contacts.moveToNext()) {

        String contactName = contacts.getString(nameFieldColumnIndex);
        aNameFromContacts[i] =    contactName ;

        String number = contacts.getString(numberFieldColumnIndex);
        aNumberFromContacts[i] =    number ;
        i++;
    }

    contacts.close();
}

在清单中,我添加了:

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

不幸的是,我仍然遇到异常:

java.lang.SecurityException: Permission Denial: opening provider    com.android.providers.contacts.ContactsProvider2 from ProcessRecord{cb99505 8760:net.zedge.vibtest/u0a80} (pid=8760, uid=10080) requires   android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS

为什么会这样?

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
      Cursor contacts = 
          getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, 
          null, null, null);
      String aNameFromContacts[] = new String[contacts.getCount()];
      String aNumberFromContacts[] = new String[contacts.getCount()];
      int i = 0;

      int nameFieldColumnIndex = 
         contacts.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
      int numberFieldColumnIndex = 
         contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

      while(contacts.moveToNext()) {

          String contactName = contacts.getString(nameFieldColumnIndex);
          aNameFromContacts[i] =    contactName ;

          String number = contacts.getString(numberFieldColumnIndex);
          aNumberFromContacts[i] =    number ;
          i++;
      }

      contacts.close();
}

@Nora 像这样尝试,将代码放在 if 条件中。您现在正在检查您的设备是否启用了联系人权限,如果启用则内部代码将被执行,否则不会。

在 Android Marshmallow 之前,在清单中声明权限就足够了,系统会在安装期间授予这些权限。但是从 Android M 开始,声明权限是不够的。授予权限的权限已转移给用户。您需要在运行时请求这些权限,以便允许用户授予权限。

按照此 official documentation 了解实施细节。