使用MediaStore插入图片后DATE_TAKEN字段始终为null的问题
解决MediaStore插入图片后DATE_TAKEN字段为null的问题
我之前也遇到过一模一样的情况,问题根源出在Android Q及以上版本使用IS_PENDING标记后的更新环节。你在插入阶段确实设置了DATE_TAKEN,但清除IS_PENDING状态时没把这个字段重新提交,导致系统没有持久化这个值。
原因拆解
在Android Q+中,当你带着IS_PENDING=1插入媒体记录时,这条记录处于临时状态,系统不会完整持久化所有字段。只有当你把IS_PENDING更新为0时,才会完成最终的持久化操作。而你当前的更新代码只重置了IS_PENDING,没有带上DATE_TAKEN这类关键字段,所以系统自然没保留这个值。
修复代码
修改更新IS_PENDING的逻辑,在values里重新添加DATE_TAKEN(建议连同DATE_MODIFIED一起,保证时间一致性):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { values.clear() values.put(MediaStore.Images.Media.IS_PENDING, 0) // 重新提交DATE_TAKEN,确保系统持久化该字段 values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()) // 同步更新DATE_MODIFIED,保持时间逻辑一致 values.put(MediaStore.Images.Media.DATE_MODIFIED, System.currentTimeMillis() / 1000) contentResolver.update(galleryFileUri, values, null, null) }
另外还要确认:查询图片时,必须在投影(projection)数组里明确包含MediaStore.Images.Media.DATE_TAKEN字段,否则查询结果肯定会返回null。举个查询的示例:
val projection = arrayOf( MediaStore.Images.Media._ID, MediaStore.Images.Media.DATE_TAKEN // 必须包含这个字段才能获取到值 ) contentResolver.query( targetUri, projection, null, null, null )?.use { cursor -> if (cursor.moveToFirst()) { val dateTaken = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_TAKEN)) // 处理拿到的时间戳 } }
额外测试建议
如果修改后问题还存在,可以临时去掉插入时的IS_PENDING设置(仅做测试),看看DATE_TAKEN能否正常保存。这能帮你确认是不是IS_PENDING的更新逻辑导致的问题。不过生产环境别去掉IS_PENDING,它能避免其他应用在你写入图片时访问到不完整的文件。
内容的提问来源于stack exchange,提问作者Jakob
相关产品推荐
相关产品推荐

