未经READ_CONTACTS权限如何获取Android联系人详细信息

aar*_*gas 4 android android-contentresolver contactscontract android-contacts android-permissions

根据https://developer.android.com/guide/components/intents-common#Contacts上的官方文档

您可以使用选择意图

public void selectContact() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(intent, REQUEST_SELECT_CONTACT);
}
Run Code Online (Sandbox Code Playgroud)

}

有关在获取联系人URI后如何检索联系人详细信息的信息,请阅读检索联系人的详细信息。记住,当你检索联系人URI与上面的意图,你不会需要READ_CONTACTS权限读取该联系人的详细信息。

它指向https://developer.android.com/training/contacts-provider/retrieve-details以获取联系人的详细信息

当我按照上面链接中的说明进行操作时,我得到

Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 uri content://com.android.contacts/data from pid=5313, uid=10087 requires android.permission.READ_CONTACTS, or grantUriPermission()
Run Code Online (Sandbox Code Playgroud)

我试图通过获取联系方式

  • 加载程序(如链接说明中所述)
  • getContentResolver()。query()
  • 尝试使用lookupKey并获取联系人ID

每一种方式都需要require android.permission.READ_CONTACTS异常。是否有一个示例可以按照文档中的说明工作?

最小,完整和可验证的示例,位于

https://github.com/aaronvargas/ContactsSSCCE

要测试是否使用READ_CONTACTS,必须在“系统应用设置”中进行更改

- 编辑

在Android问题跟踪器上通过https://issuetracker.google.com/issues/118400813创建了问题

mar*_*mor 5

Android的API ContactsContract数据存储在三个不同的表:ContactsRawContactsData

您将获得通过临时权限来通过读取数据contactUri,这意味着您只能从Contacts表中以及仅在所选联系人上读取详细信息。

这些是Contacts您可以获取的表中存储的字段,其他字段(如电话,电子邮件等)也存储在Data表中,并且需要READ_CONTACTS权限

_id
contact_chat_capability
contact_last_updated_timestamp
contact_presence
contact_status
contact_status_icon
contact_status_label
contact_status_res_package
contact_status_ts
custom_ringtone
dirty_contact
display_name
display_name_alt
display_name_reverse
display_name_source
has_email
has_phone_number
in_default_directory
in_visible_group
is_private
is_user_profile
last_time_contacted
link
link_count
link_type1
lookup
name_raw_contact_id
phonebook_bucket
phonebook_bucket_alt
phonebook_label
phonebook_label_alt
phonetic_name
phonetic_name_style
photo_file_id
photo_id
photo_thumb_uri
photo_uri
pinned
sec_custom_alert
sec_custom_vibration
sec_led
send_to_voicemail
sort_key
sort_key_alt
starred
times_contacted
Run Code Online (Sandbox Code Playgroud)

你可以做什么

如果您需要以下有关联系人的数据项之一:电话,电子邮件,地址,则可以切换为使用请求该特定类型的特定ACTION_PICK意图,然后就可以访问有关所选联系人的单个信息项。例如,如果您的应用程序需要所选择联系人的电话号码,请执行以下操作:

Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT_REQUEST);
Run Code Online (Sandbox Code Playgroud)

然后,在onActivityResult中,您将获得所选的联系人+电话:

if (resultCode == RESULT_OK) {
       Uri phoneUri = data.getData();
       Cursor cursor = getContentResolver().query(phoneUri, null, null, null, null);
       DatabaseUtils.dumpCursor(cursor);
}
Run Code Online (Sandbox Code Playgroud)


小智 -1

    You need this permission in android Manifest 
    <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>

   and need to grant the permission run something like this 

     private void requestContactPermission() {
        final String[] permissions = new String[]{Manifest.permission.READ_CONTACTS};
        ActivityCompat.requestPermissions(this, permissions, REQUEST_CONTACT_PERM);
    }

      private boolean isReadContactPermissionGranted() {
        return ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) 
          == PackageManager.PERMISSION_GRANTED;
       }

  on Permission granted, you would get callback to your activity  

        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode != REQUEST_CONTACT_PERM) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            return;
        }
     if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            //call your contact pick method
              return;
        }
      }
Run Code Online (Sandbox Code Playgroud)

所以最后在调用联系人选择器方法之前确保您有权限检查

            if (isReadContactPermissionGranted()) {
               //Start method
            } else {
                requestContactPermission();
            }
Run Code Online (Sandbox Code Playgroud)