什么是最简单的方法从android.net.Uri对象持有一个文件:类型转换为java.io.File对象在Android?
我尝试了下面的方法,但不管用:
File file = new File(Environment.getExternalStorageDirectory(), "read.me");
Uri uri = Uri.fromFile(file);
File auxFile = new File(uri.toString());
assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath());
一些库需要文件对象的过程,如改造,一些图像编辑器等。
将URI转换为文件对象或任何类似的东西,我们有一种方法,这是支持所有android旧版本和即将到来的版本。
步骤1:
你必须在FilesDir中创建一个新文件,这个文件对于其他与我们的文件和扩展名相同的应用程序是不可读的。
步骤2:
您必须通过使用InputStream复制URI的内容来创建一个文件。
File f = getFile(getApplicationContext(), uri);
public static File getFile(Context context, Uri uri) throws IOException {
File destinationFilename = new File(context.getFilesDir().getPath() + File.separatorChar + queryName(context, uri));
try (InputStream ins = context.getContentResolver().openInputStream(uri)) {
createFileFromStream(ins, destinationFilename);
} catch (Exception ex) {
Log.e("Save File", ex.getMessage());
ex.printStackTrace();
}
return destinationFilename;
}
public static void createFileFromStream(InputStream ins, File destination) {
try (OutputStream os = new FileOutputStream(destination)) {
byte[] buffer = new byte[4096];
int length;
while ((length = ins.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
} catch (Exception ex) {
Log.e("Save File", ex.getMessage());
ex.printStackTrace();
}
}
private static String queryName(Context context, Uri uri) {
Cursor returnCursor =
context.getContentResolver().query(uri, null, null, null, null);
assert returnCursor != null;
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst();
String name = returnCursor.getString(nameIndex);
returnCursor.close();
return name;
}
对于那些在这里寻找图像解决方案的人,特别是在这里。
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;
}
使用内容解析器获取输入流
InputStream inputStream = getContentResolver().openInputStream(uri);
然后将输入流复制到文件中
FileUtils.copyInputStreamToFile(inputStream, file);
样品使用方法:
private File toFile(Uri uri) throws IOException {
String displayName = "";
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if(cursor != null && cursor.moveToFirst()){
try {
displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}finally {
cursor.close();
}
}
File file = File.createTempFile(
FilenameUtils.getBaseName(displayName),
"."+FilenameUtils.getExtension(displayName)
);
InputStream inputStream = getContentResolver().openInputStream(uri);
FileUtils.copyInputStreamToFile(inputStream, file);
return file;
}
uri.toString()给我:"content://com.google.android.apps.nbu.files.provider/1/file%3A%2F%2F%2Fstorage%2Femulated%2F0%2FDownload%2Fbackup.file"
uri.getPath()给我:“/1/文件:///存储/模拟/0/下载/备份文件。”
new File(uri.getPath())给我“/1/ File:/storage/ emululated /0/Download/backup.file”。
所以如果你有一个文件的访问权限,想要避免使用ContentResolver或直接读取文件,答案是:
private String uriToPath( Uri uri )
{
File backupFile = new File( uri.getPath() );
String absolutePath = backupFile.getAbsolutePath();
return absolutePath.substring( absolutePath.indexOf( ':' ) + 1 );
}
为简化回答,跳过错误处理