2

我有一个应用程序可以让用户从 sdcard 中选择音乐文件。要启动我正在使用的选择器意图

    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); 

工作正常。

4

2 回答 2

1

/sdcard通常符号链接到文件系统(那个)中的真实(*)路径,以保持与默认/storage的早期 Android 设备兼容。/sdcard

UsingEnvironment.getExternalStorageDirectory()是你应该使用的方法。如果您对该路径进行硬编码,则无法保证/sdcard或将起作用。/storage/sdcard0设备制造商几乎可以使用他们想要的任何文件系统布局,但他们会确保Environment知道正确的路径。


(*) 启动 Honeycomb 和“统一存储模型”,实际路径实际上类似于/data/media通过 fuse 循环安装到/storage/sdcard0(或任何Environment告诉您)以强制执行权限所需的正确WRITE_EXTERNAL_STORAGE权限。

与 Android 工程师 Dan Morrill 的即兴问答会议揭示了 Galaxy Nexus 缺乏 USB 大容量存储背后的原因- 第二个问题有一些细节。


getAbsolutePath()顺便说一下,它的工作方式与桌面 Java 应用程序的工作方式不同。在 Android 上,当前工作目录 / 根目录始终为/. 所以getAbsolutePath()总是会返回与 dos 相同的结果,getPath()并且最多会在路径前加上/.

Uris fromFile可以通过以下方式轻松构建

Uri uri = Uri.fromFile(new File(soundPath));

这样你就可以得到一个正确Urifile://方案,如果你使用不是这种情况(并且可能导致错误)Uri.parse("/some/path")

于 2012-11-19T15:39:46.220 回答
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 上使用它

字符串 mpath = getPath(data.getData());

于 2013-07-26T14:33:46.903 回答