<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
Android 6.0+ (API 23+) 還需動態申請:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CALL_LOG}, REQ_CODE);
}
// 1. 獲取 _id(長整型)
long callId = cursor.getLong(cursor.getColumnIndex(CallLog.Calls._ID));
// 2. 構建帶 ID 的 URI
Uri deleteUri = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI, callId);
// 3. 執行刪除
int rows = getContentResolver().delete(deleteUri, null, null);
if (rows > 0) Log.d("CallLog", "刪除成功: " + callId);
| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
delete(CallLog.Calls.CONTENT_URI, "_id=?", new String[]{id}) | WHERE 子句字符串拼接,類型轉換易出錯 | ContentUris.withAppendedId(CONTENT_URI, id) 直接定位行 |
用 _id 字符串而非 Long | 類型不匹配,刪除 0 行 | cursor.getLong(...) 獲取長整型 |
缺 WRITE_CALL_LOG 權限 | SecurityException / 靜默失敗 | 清單靜態聲明 + 運行時動態申請 |
READ_CALL_LOG + WRITE_CALL_LOG 均授權。CallLog.Calls Provider,但建議適配 MediaStore 風格查詢。// 打印刪除前後行數對比
Cursor c = resolver.query(CallLog.Calls.CONTENT_URI, new String[]{CallLog.Calls._ID}, null, null, null);
Log.d("CountBefore", c.getCount() + "");
// ... delete ...
Cursor c2 = resolver.query(CallLog.Calls.CONTENT_URI, new String[]{CallLog.Calls._ID}, null, null, null);
Log.d("CountAfter", c2.getCount() + "");