Android:从内容URI获取文件URI?

| 在我的应用程序中,用户将选择一个由应用程序处理的音频文件。问题是,为了使该应用程序执行我希望它对音频文件执行的操作,我需要将URI设置为文件格式。当我使用Android的本地音乐播放器浏览应用程序中的音频文件时,URI是内容URI,如下所示:
content://media/external/audio/media/710
但是,使用流行的文件管理器应用程序Astro,我得到以下信息:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
后者对于我来说更易于访问,但是我当然希望该应用程序具有用户选择的音频文件的功能,而与他们用来浏览收藏夹的程序无关。所以我的问题是,有没有办法将
content://
样式URI转换为
file://
URI?否则,您会为我推荐什么解决此问题?这是调用选择器的代码,以供参考:
Intent ringIntent = new Intent();
ringIntent.setType(\"audio/mp3\");
ringIntent.setAction(Intent.ACTION_GET_CONTENT);
ringIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(ringIntent, \"Select Ringtone\"), SELECT_RINGTONE);
我对内容URI执行以下操作:
m_ringerPath = m_ringtoneUri.getPath();
File file = new File(m_ringerPath);
然后对文件进行一些FileInputStream的操作。     
已邀请:
只需使用
getContentResolver().openInputStream(uri)
从URI中获取
InputStream
。 http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)     
您可以使用Content Resolver从
content://
URI获取
file://
路径:
String filePath = null;
Uri _uri = data.getData();
Log.d(\"\",\"URI = \"+ _uri);                                       
if (_uri != null && \"content\".equals(_uri.getScheme())) {
    Cursor cursor = this.getContentResolver().query(_uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
    cursor.moveToFirst();   
    filePath = cursor.getString(0);
    cursor.close();
} else {
    filePath = _uri.getPath();
}
Log.d(\"\",\"Chosen path = \"+ filePath);
    
如果您的内容Uri带有
content://com.externalstorage...
,则可以使用此方法获取Android 19或更高版本上的文件夹或文件的绝对路径。
public static String getPath(final Context context, final Uri uri) {
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        System.out.println(\"getPath() uri: \" + uri.toString());
        System.out.println(\"getPath() uri authority: \" + uri.getAuthority());
        System.out.println(\"getPath() uri path: \" + uri.getPath());

        // ExternalStorageProvider
        if (\"com.android.externalstorage.documents\".equals(uri.getAuthority())) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(\":\");
            final String type = split[0];
            System.out.println(\"getPath() docId: \" + docId + \", split: \" + split.length + \", type: \" + type);

            // This is for checking Main Memory
            if (\"primary\".equalsIgnoreCase(type)) {
                if (split.length > 1) {
                    return Environment.getExternalStorageDirectory() + \"/\" + split[1] + \"/\";
                } else {
                    return Environment.getExternalStorageDirectory() + \"/\";
                }
                // This is for checking SD Card
            } else {
                return \"storage\" + \"/\" + docId.replace(\":\", \"/\");
            }

        }
    }
    return null;
}
您可以检查Uri的每个部分是否正在使用println。以下列出了我的SD卡和设备主内存的返回值。您可以访问和删除文件是否在内存中,但是我无法使用此方法从SD卡中删除文件,只能读取或打开 d使用此绝对路径的图像。如果您找到使用此方法删除的解决方案,请分享。 SD卡
getPath() uri: content://com.android.externalstorage.documents/tree/612E-B7BF%3A/document/612E-B7BF%3A
getPath() uri authority: com.android.externalstorage.documents
getPath() uri path: /tree/612E-B7BF:/document/612E-B7BF:
getPath() docId: 612E-B7BF:, split: 1, type: 612E-B7BF
主要记忆
getPath() uri: content://com.android.externalstorage.documents/tree/primary%3A/document/primary%3A
getPath() uri authority: com.android.externalstorage.documents
getPath() uri path: /tree/primary:/document/primary:
getPath() docId: primary:, split: 1, type: primary
如果您希望在获取路径后使用
file:///
获得Uri
DocumentFile documentFile = DocumentFile.fromFile(new File(path));
documentFile.getUri() // will return a Uri with file Uri
    
尝试通过调用
ContentResolver.query()
使用content://方案处理URI并不是一个好的解决方案。在运行4.2.2的HTC Desire上,您可以获得NULL作为查询结果。 为什么不改用ContentResolver? https://stackoverflow.com/a/29141800/3205334     
好吧,我来晚了,但是我的代码已经过测试 从uri检查方案:
 byte[] videoBytes;

if (uri.getScheme().equals(\"content\")){
        InputStream iStream =   context.getContentResolver().openInputStream(uri);
            videoBytes = getBytes(iStream);
        }else{
            File file = new File(uri.getPath());
            FileInputStream fileInputStream = new FileInputStream(file);     
            videoBytes = getBytes(fileInputStream);
        }
在上述答案中,我将视频uri转换为bytes数组,但这与问题无关, 我只是复制了完整的代码以显示
FileInputStream
InputStream
的用法,因为两者在我的代码中均相同。 我在Fragment中使用了变量上下文getActivity(),在Activity中它只是ActivityName.this
context=getActivity();
//在片段中
context=ActivityName.this;
//活动中     

要回复问题请先登录注册