首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 獲取聯系人電話號碼:正確使用 ContactsContract API

     編輯:程式設計綜合問答

常見錯誤分析

原代碼查詢 ContactsContract.Contacts.CONTENT_URI 獲取聯系人 ID,再用 Phone._ID 作為查詢條件去查 Phone.CONTENT_URI,導致 phones.getCount() == 0。**錯誤點:Phone 表的外鍵是 CONTACT_ID,而非 _ID。**

正確查詢流程

  1. 查詢聯系人表獲取 _ID (即 CONTACT_ID)。
  2. 用 Phone.CONTACT_ID = ? 查詢 Phone.CONTENT_URI。
  3. 遍歷游標獲取 Phone.NUMBER 和 Phone.TYPE。

標準實現代碼 (API 2.0+)

public void loadContactsWithPhones() {
    ContentResolver cr = getContentResolver();
    
    // 1. 查詢聯系人基本信息
    String[] projection = new String[]{
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.HAS_PHONE_NUMBER
    };
    Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null, null);
    
    if (cursor != null && cursor.moveToFirst()) {
        do {
            String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
            
            if ("1".equals(hasPhone)) { // 有電話號碼
                // 2. 查詢該聯系人的所有電話
                Cursor phones = cr.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                    new String[]{contactId},
                    null
                );
                
                if (phones != null) {
                    while (phones.moveToNext()) {
                        String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        int type = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                        
                        String typeLabel = getPhoneTypeLabel(type);
                        Log.d("Contact", name + " - " + typeLabel + ": " + number);
                    }
                    phones.close();
                }
            }
        } while (cursor.moveToNext());
        cursor.close();
    }
}

private String getPhoneTypeLabel(int type) {
    switch (type) {
        case ContactsContract.CommonDataKinds.Phone.TYPE_HOME: return "住宅";
        case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE: return "手機";
        case ContactsContract.CommonDataKinds.Phone.TYPE_WORK: return "工作";
        default: return "其他";
    }
}

關鍵點總結

錯誤寫法正確寫法說明
Phone._ID + " = " + contactIdPhone.CONTACT_ID + " = ?"Phone 表關聯聯系人表的外鍵是 CONTACT_ID
字符串拼接 SQL參數化查詢 new String[]{contactId}防止 SQL 注入,處理特殊字符
未檢查 hasPhone先判斷 HAS_PHONE_NUMBER == "1"避免無號碼聯系人無效查詢
未關閉 Cursor嚴格在 finally 或 use-after-close 關閉防止內存洩漏,Cursor 是系統資源

權限聲明 (AndroidManifest.xml)

<uses-permission android:name="android.permission.READ_CONTACTS" />

Android 6.0+ 還需運行時請求權限。

性能優化建議

  • 使用 CursorLoader (LoaderManager) 異步加載,避免阻塞主線程。
  • 僅查詢所需列 (projection),不要用 null 查所有列。
  • 大量聯系人時考慮分頁或異步加載到 RecyclerView。

掌握 ContactsContract 正確關聯查詢邏輯,是 Android 聯系人開發的基礎功課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved