Cursor email_crsr = getContentResolver().query(
CommonDataKinds.Email.CONTENT_URI,
null,
CommonDataKinds.Phone.CONTACT_ID + " = ?", // 錯誤:用 Phone 的 CONTACT_ID
new String[]{id},
null);
if (email_crsr != null)
email = phone_crsr.getString(phone_crsr.getColumnIndex(CommonDataKinds.Email.DATA)); // 多處錯誤
拋出:CursorIndexOutOfBoundsException: Index -1 requested, with a size of 4
CommonDataKinds.Phone.CONTACT_ID 用於電話表,Email 表應用 CommonDataKinds.Email.CONTACT_IDemail_crsr,但讀取用 phone_crsr (未定義/舊變量)query 返回游標在 beforeFirst 位置,必須 moveToFirst() 或 moveToNext() 才能讀取getColumnIndex 返回 -1 表示列名不存在,導致 getString(-1) 拋出異常
public ArrayList getContactEmails() {
ArrayList emails = new ArrayList<>();
ContentResolver cr = getContentResolver();
// 1. 查詢所有聯系人 ID
Cursor contactCursor = cr.query(
ContactsContract.Contacts.CONTENT_URI,
new String[]{ContactsContract.Contacts._ID},
null, null, null);
if (contactCursor != null) {
while (contactCursor.moveToNext()) {
String contactId = contactCursor.getString(
contactCursor.getColumnIndex(ContactsContract.Contacts._ID));
// 2. 根據聯系人 ID 查詢 Email
Cursor emailCursor = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Email.DATA}, // 只取需要的列
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", // 正確列
new String[]{contactId},
null);
if (emailCursor != null) {
while (emailCursor.moveToNext()) { // 關鍵:移動游標
String email = emailCursor.getString(
emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
if (!TextUtils.isEmpty(email)) {
emails.add(email);
}
}
emailCursor.close();
}
}
contactCursor.close();
}
return emails;
}
| 實踐 | 代碼體現 |
|---|---|
| 投影列 | new String[]{Email.DATA} 避免全表掃描 |
| 正確選擇列 | Email.CONTACT_ID 而非 Phone.CONTACT_ID |
| 游標移動 | while (cursor.moveToNext()) |
| 列索引檢查 | int idx = cursor.getColumnIndex(col); if (idx >= 0) ... |
| 資源關閉 | cursor.close() 在 finally 或 try-with-resources |
| 異步執行 | 聯系人查詢較慢,必須在 IO 線程 (RxJava/協程/AsyncTask) |
// 依賴: implementation "androidx.contacts:contacts:1.0.0-alpha1" (或更新版)
val cursor = contentResolver.query(
Email.CONTENT_URI,
arrayOf(Email.DATA),
"${Email.CONTACT_ID} = ?",
arrayOf(contactId),
null
)
// 使用 Kotlin 擴展函數安全遍歷
cursor?.use {
it.mapNotNull { it.getString(it.getColumnIndex(Email.DATA)) }
.filter { it.isNotBlank() }
.forEach { emails.add(it) }
}