Content Provider获取音频:未变更文件时Album Id与Duration为0的问题
问题解决:Content Provider获取音频Album Id和Duration为0的问题
问题原因
这是因为系统MediaStore未完成对目标音频文件的元数据索引。刚复制/添加到设备的音频,系统媒体扫描器可能还没解析其内嵌的元数据(比如专辑ID、时长),此时通过Content Provider查询到的就是默认值0。而移动或重命名文件会触发系统的媒体扫描,强制解析元数据,所以参数恢复正常。
解决方案
1. 手动触发媒体扫描
针对目标音频文件,主动请求系统媒体扫描器重新解析元数据,更新MediaStore中的记录:
fun triggerMediaScan(filePath: String) { val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) val fileUri = Uri.fromFile(File(filePath)) mediaScanIntent.data = fileUri context.sendBroadcast(mediaScanIntent) }
调用这个方法后,等待几秒让扫描完成,再查询Content Provider就能拿到正确的元数据。
2. 本地解析音频元数据作为 fallback
当MediaStore返回的Album Id或Duration为0时,直接读取音频文件的内嵌元数据作为补充:
fun getAudioMetadata(filePath: String): Pair<Long, Long> { var albumId = 0L var duration = 0L MediaMetadataRetriever().use { retriever -> try { retriever.setDataSource(filePath) // 获取时长(毫秒) retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.let { duration = it.toLong() } // 获取专辑ID(部分音频可能没有,返回空则保持0) retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM_ID)?.let { albumId = it.toLong() } } catch (e: Exception) { e.printStackTrace() } } return Pair(albumId, duration) }
在你的查询代码中加入判断:
// 原查询代码中获取albumId和duration后 val (fallbackAlbumId, fallbackDuration) = getAudioMetadata(data) val finalAlbumId = if (albumId == 0L) fallbackAlbumId else albumId val finalDuration = if (duration == 0L) fallbackDuration else duration
3. 检查查询参数正确性
确保你使用的查询URI是MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,同时投影字段的引用保持统一:
// 替换你的uri变量为正确的内容URI val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
另外,建议统一使用MediaStore.Audio.Media下的字段,比如将MediaStore.Audio.ArtistColumns.ARTIST替换为MediaStore.Audio.Media.ARTIST,避免混用不同类的字段导致潜在问题。
内容的提问来源于stack exchange,提问作者BRUTAL
相关产品推荐
相关产品推荐

