转换文件: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.Uri
to a File
in 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 ContentResolver
is a file's name and size as mentioned here:
Retrieving File Information | Android developers
顺便说一下,我们在查询时唯一可以依赖的信息ContentResolver
是文件的名称和大小,如下所述:
检索文件信息 | 安卓开发者
As you could see there is an interface OpenableColumns
that 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 ContentResolver
and 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 类型。