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

Android 12设备MediaStore无法读取SD卡音频文件问题求助

特定Android 12设备上MediaStore读取SD卡音频文件失败排查方案

问题背景

开发的MP3播放器应用在Galaxy A34及Android虚拟设备(AVD)上可正常读取并播放SD卡音频,但在某特定Android 12设备上,通过MediaStore.Audio.Media.EXTERNAL_CONTENT_URI无法获取任何音频数据。已通过SDCardEventReceiver确认SD卡可被识别且路径正常,所有设备均配置了读取权限。

排查与解决步骤

1. 确认SD卡存储类型

部分设备的SD卡会被格式化为可移动存储(而非内部存储扩展),此时MediaStore默认索引范围不包含这类存储。可尝试:

  • 使用MediaStore.Files.getContentUri("external")替代EXTERNAL_CONTENT_URI,并通过RELATIVE_PATH筛选SD卡路径下的文件
  • 若需直接访问SD卡根目录,需申请MANAGE_EXTERNAL_STORAGE权限(Android 12需引导用户到系统设置手动开启)

2. 校验MediaStore查询逻辑

确保查询无错误约束条件,先执行无筛选的基础查询验证:

val projection = arrayOf(
    MediaStore.Audio.Media._ID,
    MediaStore.Audio.Media.DISPLAY_NAME,
    MediaStore.Audio.Media.DATA
)
val cursor = contentResolver.query(
    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
    projection,
    null,
    null,
    null
)
// 打印cursor.count确认是否真的无数据返回
cursor?.let { Log.d("MediaStore", "音频文件数量:${it.count}") }

3. 触发MediaStore重新索引SD卡

部分设备因系统优化或扫描异常,导致SD卡音频未被MediaStore索引:

  • 重启设备后等待系统自动扫描
  • 进入系统设置-存储,手动触发SD卡媒体扫描
  • 通过广播触发指定路径扫描:
val sdCardUri = Uri.parse("file:///你的SD卡根路径/")
sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, sdCardUri))

4. 验证权限细节

Android 12中READ_EXTERNAL_STORAGE对可移动SD卡的访问可能存在厂商限制:

  • 确保Manifest中声明权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />
  • 引导用户开启全文件访问权限:
if (!Environment.isExternalStorageManager()) {
    val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
    startActivity(intent)
}

5. 直接遍历SD卡路径对比测试

跳过MediaStore,直接遍历SD卡路径验证文件可访问性:

// 通过StorageManager获取可移动SD卡路径(替代Environment.getExternalStorageDirectory)
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
val sdCardDir = storageVolumes.find { it.isRemovable }?.directory

sdCardDir?.walk()?.filter { 
    it.extension.equals("mp3", ignoreCase = true) 
}?.forEach { 
    Log.d("DirectAccess", "找到音频文件:${it.name}")
}
  • 若直接遍历能获取文件,说明问题出在MediaStore索引或查询逻辑;若仍无法获取,需排查SD卡访问权限或设备系统限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:15:05