在Android中将文件:Uri转换为文件

什么是从file:转换最简单的方法file: android.net.Uri到Android中的File

试过以下,但它不起作用:

  final File file = new File(Environment.getExternalStorageDirectory(), "read.me"); Uri uri = Uri.fromFile(file); File auxFile = new File(uri.toString()); assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath()); 

你想要的是…

 new File(uri.getPath()); 

… 并不是…

 new File(uri.toString()); 

注意: url.toString()返回格式为"file:///mnt/sdcard/myPicture.jpg"的string,而url.getPath()以格式"/mnt/sdcard/myPicture.jpg"返回string"/mnt/sdcard/myPicture.jpg"

没有“简单”的方法来做到这一点。 Uri不是FileUri不必在可以访问的文件系统上表示文件。 Uri可能指出的内容是:

  • 存储在您无法访问的可移动存储上
  • 存储在您无法访问的另一个应用程序的内部存储上
  • 以encryption的forms存储, ContentProvider需要对其进行解密
  • 存储在SQLite数据库的BLOB列中, ContentProvider需要加载并提供它
  • 存储在“云”中, ContentProvider需要下载它
  • dynamic生成,这个网页的方式
  • 等等

您可以使用ContentResolveropenInputStream()来获取由Uri表示的内容的InputStream 。 您可以在您控制的某个文件上创buildFileOutputStream 。 而且,您可以使用Java I / O从InputStream复制到OutputStream ,在您控制的文件中创build自己的内容副本。

编辑:对不起,我应该有更好的testing之前。 这应该工作:

 new File(new URI(androidURI.toString())); 

URI是java.net.URI。

经过长时间的搜寻,这对我来说是有效的:

 File file = new File(getPath(uri)); public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if (cursor == null) return null; int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String s=cursor.getString(column_index); cursor.close(); return s; } 

使用

 InputStream inputStream = getContentResolver().openInputStream(uri); 

直接复制文件。 另请参阅:

https://developer.android.com/guide/topics/providers/document-provider.html

这一切都不适合我。 我发现这是工作的解决scheme:

 String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getActivity().getContentResolver().query(uri, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String filePath = cursor.getString(columnIndex); cursor.close(); 

@CommonsWare解释得很好。 我们真的应该使用他提出的解决scheme。

顺便说一句,只有在查询ContentResolver时我们才能依赖的信息是文件的名称和大小,如下所述: 检索文件信息| Android开发者

正如你可以看到有一个接口OpenableColumns只包含两个字段:DISPLAY_NAME和SIZE。

在我的情况下,我需要检索有关JPEG图像的EXIF信息,并在发送到服务器之前将其旋转(如果需要)。 为此,我使用ContentResolveropenInputStream()将文件内容复制到临时文件中

我是这样做的:

 try { readImageInformation(new File(contentUri.getPath())); } catch (IOException e) { readImageInformation(new File(getRealPathFromURI(context, contentUri))); } public static String getRealPathFromURI(Context context, Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } 

所以基本上我首先尝试使用一个文件,即相机拍摄的照片,并保存在SD卡上。 这不适用于返回的图像:Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); 这种情况下,需要通过getRealPathFromURI()函数将Uri转换为实际path。 所以结论是,这取决于你想要转换为文件的Uritypes。

您可以使用以下方法从文件Uri获取文件。 它具有DocumentFile参数,但您可以轻松更改它。 使用DocumentFile.fromFile(Environment.getExternalStorageDirectory());testing此方法以创build文件uri最简单的方法DocumentFile.fromFile(Environment.getExternalStorageDirectory()); 其中有一个Uri file:///storage/emulated/0

 /** * Gets File from DocumentFile if Uri is file:/// * * @param documentFile Document file that contains Uri to create File from * @return File with absolute path to the physical file on device memory */ public static File getFileFromDocumentFile(DocumentFile documentFile) { try { File file = new File(URI.create(documentFile.getUri().toString())); return file; } catch (Exception e) { return null; } } 

使用DocumentFile.fromTreeUri(Context, Uri)DocumentFile.fromSingleri(Context, Uri)创build或删除文件,并使用getContentResolver().openOutputStream(documentFile.getUri())getContentResolver().openInputStream(documentFile.getUri())来创build文件getContentResolver().openInputStream(documentFile.getUri())用于写入文件或从文件读取。

对于这里寻找特别的图像解决scheme的人来说是这样的。

 private Bitmap getBitmapFromUri(Uri contentUri) { String path = null; String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null); if (cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); path = cursor.getString(columnIndex); } cursor.close(); Bitmap bitmap = BitmapFactory.decodeFile(path); return bitmap; } 

文件imageToUpload =新的文件(新的URI(androidURI.toString())); 如果这是您在外部存储中创build的文件,则工作。

例如file:/// storage / emulated / 0 /(某个目录和文件名)