我有一个应用程序,允许用户从SD卡中选择音乐文件。要启动选择器意图,我正在使用
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);
工作正常。
答案 0 :(得分:1)
/sdcard
通常symlinked到文件系统中的真实(*)路径(/storage
)以保持与早期Android设备兼容,其中/sdcard
是默认设置
使用Environment.getExternalStorageDirectory()
是您应该使用的方法。如果您对该路径进行硬编码,则无法保证/sdcard
或/storage/sdcard0
能够正常工作。设备制造商几乎可以使用他们想要的任何文件系统布局,但他们会确保Environment
知道正确的路径。
(*)启动Honeycomb&统一存储模型"实际路径实际上类似于/data/media
,通过保险丝循环安装到/storage/sdcard0
(或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()
相同的位置,并且最多会在路径前面加上/
。
来自Uri
的 File
可以通过
Uri uri = Uri.fromFile(new File(soundPath));
如果您使用Uri
file://
方案获得正确的Uri.parse("/some/path")
并非如此(并可能导致错误)
答案 1 :(得分:1)
获取完整路径和文件名:
Private String getPath(Uri u) {
String[] projection = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(u, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
在onActivityResult上使用它
String mpath = getPath(data.getData());