转换文件:Uri 到 Android 中的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2975197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert file: Uri to File in Android
提问by hpique
What's the easiest way to convert from a file:android.net.Urito a Filein Android?
什么是从一个转换的最简单的方法file:android.net.Uri,以一个File在Android的?
Tried the following but it doesn't work:
尝试了以下但它不起作用:
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());
回答by Adil Hussain
What you want is...
你想要的是...
new File(uri.getPath());
... and not...
... 并不是...
new File(uri.toString());
NOTE:uri.toString()returns a String in the format: "file:///mnt/sdcard/myPicture.jpg", whereas uri.getPath()returns a String in the format: "/mnt/sdcard/myPicture.jpg".
注意:uri.toString()返回格式为:的字符串"file:///mnt/sdcard/myPicture.jpg",而uri.getPath()返回格式为:的字符串"/mnt/sdcard/myPicture.jpg"。
回答by Sanket Berde
After searching for a long time this is what worked for me:
经过长时间的搜索,这对我有用:
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;
}
回答by Juan Camilo Rodriguez Durán
use
用
InputStream inputStream = getContentResolver().openInputStream(uri);
directly and copy the file. Also see:
直接复制文件。另见:
https://developer.android.com/guide/topics/providers/document-provider.html
https://developer.android.com/guide/topics/providers/document-provider.html
回答by Matthew Flaschen
EDIT: Sorry, I should have tested better before. This should work:
编辑:对不起,我之前应该测试得更好。这应该有效:
new File(new URI(androidURI.toString()));
URI is java.net.URI.
URI 是 java.net.URI。
回答by vishwajit76
Best Solution
最佳解决方案
Create one simple FileUtil class & use to create, copy and rename the file
创建一个简单的 FileUtil 类并用于创建、复制和重命名文件
I am use uri.toString()and uri.getPath()but not work for me.
I finally found this solution.
我正在使用uri.toString(),uri.getPath()但不适合我。我终于找到了这个解决方案。
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtil {
private static final int EOF = -1;
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
private FileUtil() {
}
public static File from(Context context, Uri uri) throws IOException {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
String fileName = getFileName(context, uri);
String[] splitName = splitFileName(fileName);
File tempFile = File.createTempFile(splitName[0], splitName[1]);
tempFile = rename(tempFile, fileName);
tempFile.deleteOnExit();
FileOutputStream out = null;
try {
out = new FileOutputStream(tempFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (inputStream != null) {
copy(inputStream, out);
inputStream.close();
}
if (out != null) {
out.close();
}
return tempFile;
}
private static String[] splitFileName(String fileName) {
String name = fileName;
String extension = "";
int i = fileName.lastIndexOf(".");
if (i != -1) {
name = fileName.substring(0, i);
extension = fileName.substring(i);
}
return new String[]{name, extension};
}
private static String getFileName(Context context, Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf(File.separator);
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
private static File rename(File file, String newName) {
File newFile = new File(file.getParent(), newName);
if (!newFile.equals(file)) {
if (newFile.exists() && newFile.delete()) {
Log.d("FileUtil", "Delete old " + newName + " file");
}
if (file.renameTo(newFile)) {
Log.d("FileUtil", "Rename file to " + newName);
}
}
return newFile;
}
private static long copy(InputStream input, OutputStream output) throws IOException {
long count = 0;
int n;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
}
Use FileUtil class in your code
在代码中使用 FileUtil 类
try {
File file = FileUtil.from(MainActivity.this,fileUri);
Log.d("file", "File...:::: uti - "+file .getPath()+" file -" + file + " : " + file .exists());
} catch (IOException e) {
e.printStackTrace();
}
回答by Hemant Kaushik
Android + Kotlin
安卓 + 科特林
Add dependency for Kotlin Android extensions:
implementation 'androidx.core:core-ktx:{latestVersion}'Get file from uri:
uri.toFile()
为 Kotlin Android 扩展添加依赖项:
implementation 'androidx.core:core-ktx:{latestVersion}'从uri获取文件:
uri.toFile()
Android + Java
安卓+Java
Just move to top ;)
只需移至顶部;)
回答by Jacek Kwiecień
None of this works for me. I found this to be the working solution. But my case is specific to images.
这些都不适合我。我发现这是可行的解决方案。但我的情况是特定于图像的。
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();
回答by Volodymyr
With Kotlin it is even easier:
使用 Kotlin 就更简单了:
val file = File(uri.path)
Or if you are using Kotlin extensions for Android:
或者,如果您使用的是适用于 Android 的 Kotlin 扩展:
val file = uri.toFile()
回答by Bogdan Kornev
@CommonsWare explained all things quite well. And we really should use the solution he proposed.
@CommonsWare 很好地解释了所有事情。我们真的应该使用他提出的解决方案。
By the way, only information we could rely on when querying ContentResolveris a file's name and size as mentioned here:
Retrieving File Information | Android developers
顺便说一下,我们在查询时唯一可以依赖的信息ContentResolver是文件的名称和大小,如下所述:
检索文件信息 | 安卓开发者
As you could see there is an interface OpenableColumnsthat contains only two fields: DISPLAY_NAME and SIZE.
如您所见,有一个界面OpenableColumns仅包含两个字段:DISPLAY_NAME 和 SIZE。
In my case I was need to retrieve EXIF information about a JPEG image and rotate it if needed before sending to a server. To do that I copied a file content into a temporary file using ContentResolverand openInputStream()
就我而言,我需要检索有关 JPEG 图像的 EXIF 信息,并在发送到服务器之前根据需要对其进行旋转。为此,我使用ContentResolver和将文件内容复制到临时文件中openInputStream()
回答by Kovács Ede
I made this like the following way:
我是这样制作的:
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);
}
So basically first I try to use a file i.e. picture taken by camera and saved on SD card. This don't work for image returned by:
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
That case there is a need to convert Uri to real path by getRealPathFromURI()function.
So the conclusion is that it depends on what type of Uri you want to convert to File.
所以基本上首先我尝试使用一个文件,即由相机拍摄并保存在 SD 卡上的图片。这不适用于返回的图像: Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); 在这种情况下,需要通过getRealPathFromURI()函数将 Uri 转换为真实路径。所以得出的结论是,这取决于你想转换成 File 的 Uri 类型。

