Android编程中如何获取外置SD卡路径以播放存储卡音频文件?
解决Android获取外置SD卡路径的可靠方案
我完全理解你的困扰——不同Android厂商对外置SD卡的路径命名真是五花八门,硬编码一堆判断逻辑不仅代码冗余,还很容易漏掉新机型的情况。下面给你几个更可靠的解决方案,帮你彻底解决这个问题:
1. 使用系统API获取所有外部存储卷(推荐)
从Android 4.4(API 19)开始,系统提供了Context.getExternalFilesDirs()方法,这个方法会返回所有可用的外部存储目录(包括内置存储和外置SD卡)。你可以通过判断目录是否可移除、是否可写来筛选出外置SD卡路径:
try { // 获取所有外部存储目录 File[] externalFilesDirs = getContext().getExternalFilesDirs(null); for (File file : externalFilesDirs) { if (file != null && Environment.isExternalStorageRemovable(file)) { // 得到外置SD卡的应用私有目录路径 String sdCardPrivatePath = file.getAbsolutePath(); // 转换为SD卡根路径(注意:Android 10+需特殊权限才能访问根目录) String sdCardRootPath = sdCardPrivatePath.replace("/Android/data/你的包名/files", ""); String audioPath = sdCardRootPath + "/telavatquran/naba.mp3"; // 尝试加载音频文件 player.setDataSource(audioPath); player.prepare(); player.start(); seekUpdation(); break; // 找到可用路径就停止遍历 } } } catch (Exception e) { e.printStackTrace(); }
关键说明:
Environment.isExternalStorageRemovable(file)用于判断当前存储卷是否为可移除的外置SD卡- Android 10及以上版本默认启用分区存储,直接访问SD卡根目录的自定义文件夹需要申请
MANAGE_EXTERNAL_STORAGE权限,需引导用户到系统设置手动开启
2. 通过StorageManager获取挂载的存储卷(Android 5.0+)
对于Android 5.0(API 21)及以上版本,可以使用StorageManager获取更详细的存储卷信息:
try { StorageManager storageManager = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE); List<StorageVolume> storageVolumes = storageManager.getStorageVolumes(); for (StorageVolume volume : storageVolumes) { if (volume.isRemovable()) { // 反射调用获取存储路径(适配部分隐藏API) Method getPathMethod = StorageVolume.class.getMethod("getPath"); String sdCardPath = (String) getPathMethod.invoke(volume); String audioPath = sdCardPath + "/telavatquran/naba.mp3"; player.setDataSource(audioPath); player.prepare(); player.start(); seekUpdation(); break; } } } catch (Exception e) { e.printStackTrace(); }
注意:StorageVolume.getPath()属于隐藏API,部分厂商可能会限制调用,建议和第一种方法搭配使用作为备选方案。
3. 权限相关的重要提醒
- Android 6.0-9.0:需要申请
READ_EXTERNAL_STORAGE权限(写入需额外申请WRITE_EXTERNAL_STORAGE),并在运行时请求用户授权 - Android 10+:访问SD卡根目录的非应用私有文件,必须申请
MANAGE_EXTERNAL_STORAGE权限,可通过以下代码引导用户开启:Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent);
总结
不要再用硬编码路径的方式适配机型了,这种方法根本无法覆盖所有厂商的自定义路径。使用系统提供的API才是长期可靠的解决方案,既能兼容新旧机型,也能符合Android的权限规范。
内容的提问来源于stack exchange,提问作者Shahin Sadeghi




