android - 如何在没有 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()
我试图通过以下方式获取联系方式
- 加载程序(如链接说明中所示)
- getContentResolver().query()
- 尝试使用 lookupKey 并获取联系人 ID
每种方式都会给出需要的 android.permission.READ_CONTACTS 异常。有没有像文档所说的那样工作的例子?
最小、完整和可验证的示例
https://github.com/aaronvargas/ContactsSSCCE
要使用和不使用 READ_CONTACTS 进行测试,您必须在系统应用设置中进行更改
-编辑
在https://issuetracker.google.com/issues/118400813在 Android 问题跟踪器上创建问题
解决方案
Android 的 ContactsContract API 数据存储在三个不同的表中Contacts
:RawContacts
和Data
.
您获得了通过 读取数据的临时权限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);
}
推荐阅读
- arrays - VBA 数组函数的工作速度比 vlookup 慢
- tarantool - 如何向现有索引添加新字段?
- list - 我想在颤振中为购物应用程序制作类别页面?
- python - 与anaconda的包冲突
- php - 调用带有参数的控制器?
- xcode - 如何在 Xcode 12 的新更新中显示视图控件?
- linux - 带有 ssh 的 Git 克隆适用于 Linux,但不适用于 Windows PowerShell
- javascript - Tinymce 编辑器只添加文本
- microsoft-teams - 是否可以深层链接到频道内“文件”选项卡中的文件夹?
- android - 导航到另一个片段时如何保留 ActionBar 的 SearchView?