Android平台获取联系人指定字段方法咨询
Android 获取指定联系人字段方法
1. 先申请联系人读取权限
首先在AndroidManifest.xml中添加静态权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
Android 6.0(API 23)及以上版本需要动态申请权限,可参考以下代码片段:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 100); }
2. 核心查询代码
以下是获取你需要字段的示例函数,注释已标注每个字段对应的系统常量:
private List<Map<String, String>> getTargetContactFields() { List<Map<String, String>> contactList = new ArrayList<>(); ContentResolver contentResolver = getContentResolver(); // 1. 查询联系人基本信息(获取联系人ID、姓名) String[] contactProjection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY // 对应Name字段 }; Cursor contactCursor = contentResolver.query( ContactsContract.Contacts.CONTENT_URI, contactProjection, null, null, null ); if (contactCursor != null && contactCursor.moveToFirst()) { do { String contactId = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = contactCursor.getString(contactCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)); Map<String, String> contactMap = new HashMap<>(); contactMap.put("Name", name); // 2. 查询FirstName(结构化姓名中的名) String[] nameProjection = { ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME // 对应First Name字段 }; Cursor nameCursor = contentResolver.query( ContactsContract.Data.CONTENT_URI, nameProjection, ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{contactId, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE}, null ); if (nameCursor != null && nameCursor.moveToFirst()) { String firstName = nameCursor.getString(nameCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME)); contactMap.put("First Name", firstName); nameCursor.close(); } // 3. 查询电话号码 String[] phoneProjection = { ContactsContract.CommonDataKinds.Phone.NUMBER // 对应Phone number(s)字段 }; Cursor phoneCursor = contentResolver.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phoneProjection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?", new String[]{contactId}, null ); if (phoneCursor != null) { StringBuilder phones = new StringBuilder(); while (phoneCursor.moveToNext()) { String phone = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); phones.append(phone).append(", "); } if (phones.length() > 0) { contactMap.put("Phone number(s)", phones.substring(0, phones.length() - 2)); } phoneCursor.close(); } // 4. 查询Enterprise(公司)和Function(职位) String[] orgProjection = { ContactsContract.CommonDataKinds.Organization.COMPANY, // 对应Enterprise字段 ContactsContract.CommonDataKinds.Organization.TITLE // 对应Function字段 }; Cursor orgCursor = contentResolver.query( ContactsContract.Data.CONTENT_URI, orgProjection, ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{contactId, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE}, null ); if (orgCursor != null && orgCursor.moveToFirst()) { String enterprise = orgCursor.getString(orgCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY)); String function = orgCursor.getString(orgCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE)); contactMap.put("Enterprise", enterprise); contactMap.put("Function", function); orgCursor.close(); } // 5. 查询Label(自定义标签,需根据实际mimetype调整) String[] labelProjection = { ContactsContract.Data.LABEL }; // 这里假设标签属于组织类数据,若属于其他类型需修改mimetype Cursor labelCursor = contentResolver.query( ContactsContract.Data.CONTENT_URI, labelProjection, ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[]{contactId, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE}, null ); if (labelCursor != null && labelCursor.moveToFirst()) { String label = labelCursor.getString(labelCursor.getColumnIndex(ContactsContract.Data.LABEL)); contactMap.put("Label", label); labelCursor.close(); } contactList.add(contactMap); } while (contactCursor.moveToNext()); contactCursor.close(); } return contactList; }
说明
- 若
Enterprise/Function/Label是第三方应用自定义的字段,需确认其对应的mimetype和列名,替换上述代码中对应的查询条件即可。 - 所有Cursor使用完毕后务必调用
close(),避免内存泄漏。 - 可根据需求修改查询条件(比如只查询特定联系人)。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

