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

使用MediaStore获取设备内部存储音频仅返回一首的问题排查

问题排查与修复方案

1. 权限缺失(最可能的原因)

Android 6.0(API 23)及以上版本,访问公共存储的媒体文件需要动态申请权限,仅在Manifest中声明无法生效。

修复步骤:

  • 在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+ 需替换为专属媒体权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
  • 在Activity中动态申请权限,并将媒体查询逻辑抽离到权限通过后执行:
private static final int STORAGE_PERMISSION_REQUEST = 100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                STORAGE_PERMISSION_REQUEST);
    } else {
        loadAudioFiles();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == STORAGE_PERMISSION_REQUEST) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            loadAudioFiles();
        } else {
            Toast.makeText(this, "需要存储权限才能读取音乐文件", Toast.LENGTH_SHORT).show();
        }
    }
}

private void loadAudioFiles() {
    ListView audioView = findViewById(R.id.songView);
    ArrayList<String> audioList = new ArrayList<>();

    String[] proj = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME};

    Cursor audioCursor = getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            proj,
            null,
            null,
            null);

    if (audioCursor != null) {
        try {
            while (audioCursor.moveToNext()) {
                int nameIndex = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
                audioList.add(audioCursor.getString(nameIndex));
            }
        } finally {
            audioCursor.close();
        }
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
            android.R.layout.simple_list_item_1,
            android.R.id.text1,
            audioList);
    audioView.setAdapter(adapter);
}

2. Cursor安全关闭问题

原代码中,如果audioCursor为null,执行audioCursor.close()会触发空指针异常。将关闭操作放在try-finally块中,确保Cursor无论是否有数据都能被正确释放。

3. 筛选有效音乐文件(可选)

如果只想获取真正的音乐文件(排除铃声、系统提示音等非音乐类音频),可以在查询时添加筛选条件:

// 仅查询标记为音乐的音频文件
String selection = MediaStore.Audio.Media.IS_MUSIC + " = 1";
Cursor audioCursor = getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        proj,
        selection,
        null,
        null);

4. 关于内部存储的说明

注意:Android中MediaStore.Audio.Media.EXTERNAL_CONTENT_URI包含设备内置的公共存储和外接SD卡。如果你的需求是访问应用私有内部存储中的音乐文件,MediaStore无法直接访问,需要通过文件路径直接读取(比如getFilesDir()下的文件)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:01:04