You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android读取CallLog通话记录时Cursor报Couldn't read row错误如何解决

报错原因

报错信息中的col -1说明c.getColumnIndex(CallLog.Calls.CACHED_PHOTO_URI)调用返回了-1,即当前查询返回的Cursor中不存在指定列,和你查询全列还是单列无关,具体触发原因如下:

  • CallLog.Calls.CACHED_PHOTO_URI是Android 6.0(API等级23)才新增的系统字段,如果你运行App的设备系统版本低于API 23,系统通话记录Provider不会返回该字段,查询列索引自然返回-1。
  • 即使设备系统版本≥API 23,部分厂商定制ROM修改了通话记录Provider的实现,可能不会暴露CACHED_PHOTO_URI字段,也会导致列索引查询失败。
  • 你当前贴出的代码中没有调用Cursor指针移动方法(如moveToFirst()、moveToNext()),Cursor默认指针位置在首行之前(索引为-1),直接取值也会触发类似报错,你报错中的row 305说明你有遍历逻辑只是未贴全,但建议补充指针位置合法性判断。
修复方案
  1. 增加版本判断,低于API 23的设备不要访问该字段,可通过联系人ID查询Contacts Provider获取头像。
  2. 取值前先判断列索引是否合法,确认列存在再读取值。
  3. 操作Cursor时补充指针位置判断,用完及时关闭Cursor避免内存泄漏。

修复后的参考代码如下:

Cursor c = activity.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC ");
if (c == null) {
    // 处理Cursor为空的异常情况
    return;
}
try {
    // 遍历所有通话记录
    while (c.moveToNext()) {
        String photo = null;
        // 先判断系统版本是否支持该字段
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            // 先查询列索引,判断是否存在
            int photoUriColIndex = c.getColumnIndex(CallLog.Calls.CACHED_PHOTO_URI);
            if (photoUriColIndex >= 0 && !c.isNull(photoUriColIndex)) {
                photo = c.getString(photoUriColIndex);
                Log.d("PHOTO_URI", photo);
            }
        }
        // 剩余逻辑处理
    }
} catch (Exception e) {
    Log.e("ERROR_LOG", e.toString());
} finally {
    // 用完关闭Cursor
    if (!c.isClosed()) {
        c.close();
    }
}

内容的提问来源于stack exchange,提问作者Unknown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:39:03