Android:从内容URI获取文件URI?
在我的应用程序中,用户将select应用程序然后处理的audio文件。 问题是,为了使应用程序做我想要做的audio文件,我需要的URI在文件格式。 当我使用Android的本地音乐播放器浏览应用程序中的audio文件时,URI是内容URI,如下所示:
content://media/external/audio/media/710
但是,使用stream行的文件pipe理器应用程序Astro,我得到以下内容:
file:///sdcard/media/audio/ringtones/GetupGetOut.mp3
后者更方便我使用,但我希望应用程序具有用户select的audio文件的function,而不pipe他们用于浏览其collections的程序。 所以我的问题是,有没有办法将content://
style URI转换成file://
URI? 否则,你会推荐什么来解决这个问题? 这里是调用select器的代码,供参考:
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
。
您可以使用Content Resolver从content://
URI获得一个file://
path:
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);
尝试通过调用ContentResolver.query()
来处理具有content://scheme的URI不是一个好的解决scheme。 在运行4.2.2的HTC Desire上,您可以获得NULL作为查询结果。
为什么不使用ContentResolver呢? https://stackoverflow.com/a/29141800/3205334
如果你有一个内容Uri的content://com.externalstorage...
你可以使用这个方法获得Android 19或以上的文件夹或文件的绝对path。
public static String getPath(final Context context, final Uri uri) { System.out.println("%%%%%%%%%%%%%%%"); 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); System.out.println("%%%%%%%%%%%%%%%"); // 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卡中删除文件 ,只能使用此绝对path读取或打开图像。 如果您find使用此方法删除的解决scheme,请分享。 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
如果你想获得path使用后得到Uri file:///
DocumentFile documentFile = DocumentFile.fromFile(new File(path)); documentFile.getUri() // will return a Uri with file Uri
您应该使用getContentResolver().openInputStream(uri)
从URI获取InputStream
。 因为它非常容易理解。 更多openInputStream(android.net.Uri)