在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
不是File
。 Uri
不必在可以访问的文件系统上表示文件。 Uri
可能指出的内容是:
- 存储在您无法访问的可移动存储上
- 存储在您无法访问的另一个应用程序的内部存储上
- 以encryption的forms存储,
ContentProvider
需要对其进行解密 - 存储在SQLite数据库的BLOB列中,
ContentProvider
需要加载并提供它 - 存储在“云”中,
ContentProvider
需要下载它 - dynamic生成,这个网页的方式
- 等等
您可以使用ContentResolver
和openInputStream()
来获取由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信息,并在发送到服务器之前将其旋转(如果需要)。 为此,我使用ContentResolver
和openInputStream()
将文件内容复制到临时文件中
我是这样做的:
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 /(某个目录和文件名)