使用registerForActivityResult获取联系人电话与邮箱问题求助
使用registerForActivityResult获取联系人的电话与邮箱示例
问题原因
ActivityResultContracts.PickContact()返回的是联系人主表(ContactsContract.Contacts)的Uri,而非旧版Intent.ACTION_PICK + Phone.CONTENT_TYPE对应的电话表Uri。因此直接用Phone.CONTACT_ID、Phone.NUMBER等列查询会找不到对应字段,需要先从联系人主表获取ContactsContract.Contacts._ID(对应旧的Phone.CONTACT_ID),再关联查询电话表和邮箱表。
完整示例代码
1. 权限声明与动态申请
在AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
动态申请权限(适配Android 6.0+):
private ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { if (isGranted) { pickContactLauncher.launch(null); } else { Toast.makeText(this, "需要获取联系人权限", Toast.LENGTH_SHORT).show(); } });
2. 注册联系人选择的ActivityResultLauncher
private ActivityResultLauncher<Void> pickContactLauncher = registerForActivityResult(new ActivityResultContracts.PickContact(), contactUri -> { if (contactUri == null) return; // 1. 从联系人主表获取Contact ID和姓名 String[] contactProjection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; Cursor contactCursor = getContentResolver().query(contactUri, contactProjection, null, null, null); if (contactCursor != null && contactCursor.moveToFirst()) { String contactId = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts._ID)); String contactName = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); // 2. 查询该联系人的所有电话 List<String> phoneNumbers = new ArrayList<>(); String[] phoneProjection = {ContactsContract.CommonDataKinds.Phone.NUMBER}; String phoneSelection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?"; String[] phoneSelectionArgs = {contactId}; Cursor phoneCursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phoneProjection, phoneSelection, phoneSelectionArgs, null ); if (phoneCursor != null) { while (phoneCursor.moveToNext()) { String number = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); phoneNumbers.add(number); } phoneCursor.close(); } // 3. 查询该联系人的所有邮箱 List<String> emails = new ArrayList<>(); String[] emailProjection = {ContactsContract.CommonDataKinds.Email.ADDRESS}; String emailSelection = ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?"; String[] emailSelectionArgs = {contactId}; Cursor emailCursor = getContentResolver().query( ContactsContract.CommonDataKinds.Email.CONTENT_URI, emailProjection, emailSelection, emailSelectionArgs, null ); if (emailCursor != null) { while (emailCursor.moveToNext()) { String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS)); emails.add(email); } emailCursor.close(); } // 处理获取到的联系人信息 StringBuilder sb = new StringBuilder(); sb.append("姓名:").append(contactName).append("\n"); sb.append("电话:").append(phoneNumbers.isEmpty() ? "无" : String.join(", ", phoneNumbers)).append("\n"); sb.append("邮箱:").append(emails.isEmpty() ? "无" : String.join(", ", emails)); Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show(); contactCursor.close(); } });
3. 触发联系人选择
在按钮点击等事件中调用:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { requestPermissionLauncher.launch(Manifest.permission.READ_CONTACTS); } else { pickContactLauncher.launch(null); }
关键说明
- 联系人主表仅存储基础信息,电话、邮箱等数据分别存在
ContactsContract.CommonDataKinds.Phone和ContactsContract.CommonDataKinds.Email表中,需通过CONTACT_ID关联查询。 - 务必关闭所有Cursor,避免内存泄漏。
- Android 13+适配无需额外修改权限逻辑,
READ_CONTACTS权限仍适用。
内容的提问来源于stack exchange,提问作者programmerboy
相关产品推荐
相关产品推荐

