我有一个应用程序,可以让用户从 SD 卡中选择音乐文件。为了启动选择器 Intent ,我正在使用
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Complete action using"), 0);
但是根据用户选择的方法,我得到了不同的绝对路径。如果用户使用 ES 文件资源管理器,那么我会得到 /sdcard/Music/song.mp3
但如果用户使用一些音乐应用程序,那么我会得到 /storage/sdcard0/Music/song.mp3
。这非常令人困惑,我的应用程序要求我知道一个最终的基本路径。
Environment.getExternalStorageDirectory()
返回/storage/sdcard0/
。任何帮助将不胜感激。
注意:在这两种情况下
Uri uri = Uri.parse(new File(soundPath).getAbsolutePath());
mPlayer = MediaPlayer.create(this, uri);
工作正常。
最佳答案
/sdcard
通常是 symlinked文件系统中的真实 (*) 路径(/storage
),以保持与早期 Android 设备的兼容性,其中 /sdcard
是默认值。
使用 Environment.getExternalStorageDirectory()
是您应该使用的方法。如果您对该路径进行硬编码,则不能保证 /sdcard
或 /storage/sdcard0
能够正常工作。设备制造商几乎可以使用他们想要的任何文件系统布局,但他们将确保环境
知道正确的路径。
(*) 启动 Honeycomb 和“统一存储模型”,真正的路径实际上类似于 /data/media
,它通过 fuse 循环安装到 /storage/sdcard0
code> (或任何 Environment
告诉您的内容)来强制执行 WRITE_EXTERNAL_STORAGE
所需的正确权限。许可。
Impromptu Q&A Session With Android Engineer Dan Morrill Brings To Light Reasons Behind Galaxy Nexus' Lack Of USB Mass Storage - 第二个问题有一些细节。
顺便说一下,
getAbsolutePath()
的工作方式与桌面 Java 应用程序的工作方式不同。在 Android 上,当前工作目录/root 始终为 /
。因此,getAbsolutePath()
始终会返回与 getPath()
相同的结果,并且最多会在路径前加上 /
前缀。
File
的 Uri
可以通过以下方式轻松构建
Uri uri = Uri.fromFile(new File(soundPath));
这样您就可以使用 file://
方案获得正确的 Uri
,但如果您使用 Uri 则情况并非如此(并且可能导致错误) .parse("/some/path")
关于Android 音乐文件选择器 Intent 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13456070/