首页 > 解决方案 > 如何在没有 READ_CONTACTS 权限的情况下获取 Android 联系人详细信息

问题描述

根据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);
}

}

有关在获得联系人 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()

我试图通过以下方式获取联系方式

每种方式都会给出需要的 android.permission.READ_CONTACTS 异常。有没有像文档所说的那样工作的例子?

最小、完整和可验证的示例

https://github.com/aaronvargas/ContactsSSCCE

要使用和不使用 READ_CONTACTS 进行测试,您必须在系统应用设置中进行更改

-编辑

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

标签: androidandroid-permissionsandroid-contactsandroid-contentresolvercontactscontract

解决方案


Android 的 ContactsContract API 数据存储在三个不同的表中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

你可以做什么

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

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

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

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

推荐阅读