Android MP3播放器:如何仅加载SD卡kalid文件夹内的MP3文件?
解决仅加载SD卡kalid文件夹内MP3文件的问题
我来帮你搞定这个只读取指定文件夹MP3的需求~先说说你之前两种方法无效的原因,再给你正确的实现方案:
为什么之前的方法不行?
- 方法1(Uri.fromFile):在Android 7.0及以上版本,直接用
Uri.fromFile()会触发FileUriExposedException,而且MediaStore的ContentResolver并不推荐用文件Uri来查询媒体库内容,因为它是基于内容提供者的索引,不是直接访问文件系统。 - 方法2(getContentUriForPath):这个方法的作用是将文件路径转换为用于插入MediaStore的Uri,不是用来查询的,所以用它作为query的Uri参数,根本得不到你要的文件夹内文件。
- 你源码里的Uri参数还犯了个小错误:
MediaStore.Audio.Media.getContentUriForPath("Environment.getExternalStorageDirectory().getPath()+ kalid+")这是把字符串字面量传进去了,不是动态拼接的真实路径。
正确的实现方案
核心思路是:继续使用MediaStore.Audio.Media.EXTERNAL_CONTENT_URI作为查询的Uri,然后通过筛选条件(selection)来限定文件路径必须在kalid文件夹下,这样就能精准获取目标文件夹内的MP3了。
修正后的完整代码如下:
ContentResolver resolver = context.getContentResolver(); // 正确获取kalid文件夹的路径 File kalidDir = new File(Environment.getExternalStorageDirectory(), "kalid"); String kalidAbsolutePath = kalidDir.getAbsolutePath(); // 构建筛选条件:只保留音乐文件,且路径以kalid文件夹开头 String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0 AND " + MediaStore.Audio.Media.DATA + " LIKE ?"; // 用通配符匹配kalid文件夹下所有子文件/子文件夹内的音乐 String[] selectionArgs = new String[]{kalidAbsolutePath + "/%"}; // 还是用MediaStore的标准媒体Uri来查询 Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Cursor cursor = resolver.query(media, PROJECTION, selection, selectionArgs, null); if (cursor == null || cursor.getCount() == 0) { Log.d(TAG, "Music List Empty"); return false; } mMusicList.clear(); while (cursor.moveToNext()) { mMusicList.add(new Music( cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)), cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)), cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)), cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)), cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)) )); } cursor.close();
额外注意事项
- 权限问题:
- Android 12及以下:需要申请
READ_EXTERNAL_STORAGE权限,记得在Manifest里声明并动态申请。 - Android 13及以上:需要申请
READ_MEDIA_AUDIO权限,替代旧的存储权限。
- Android 12及以下:需要申请
- 路径兼容性:如果你的App需要适配Android Q(10)及以上,建议使用
MediaStore的相对路径查询(比如MediaStore.Audio.Media.RELATIVE_PATH),避免直接访问外部存储根目录,示例:// Android Q+ 可用的相对路径筛选 String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0 AND " + MediaStore.Audio.Media.RELATIVE_PATH + " LIKE ?"; String[] selectionArgs = new String[]{"kalid/%"};
内容的提问来源于stack exchange,提问作者user9163992




