什么是最简单的方法从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());
public String getRealPathFromURI(Uri uri)
{
String result;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor == null) {
result = uri.getPath();
cursor.close();
return result;
}
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
return result;
}
然后使用从URI中获取文件:
File finalFile = newFile(getRealPathFromURI(uri));
——希望能帮到你----
你可以使用这个函数从uri中获取文件在新的android和旧的
fun getFileFromUri(context: Context, uri: Uri?): File? {
uri ?: return null
uri.path ?: return null
var newUriString = uri.toString()
newUriString = newUriString.replace(
"content://com.android.providers.downloads.documents/",
"content://com.android.providers.media.documents/"
)
newUriString = newUriString.replace(
"/msf%3A", "/image%3A"
)
val newUri = Uri.parse(newUriString)
var realPath = String()
val databaseUri: Uri
val selection: String?
val selectionArgs: Array<String>?
if (newUri.path?.contains("/document/image:") == true) {
databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
selection = "_id=?"
selectionArgs = arrayOf(DocumentsContract.getDocumentId(newUri).split(":")[1])
} else {
databaseUri = newUri
selection = null
selectionArgs = null
}
try {
val column = "_data"
val projection = arrayOf(column)
val cursor = context.contentResolver.query(
databaseUri,
projection,
selection,
selectionArgs,
null
)
cursor?.let {
if (it.moveToFirst()) {
val columnIndex = cursor.getColumnIndexOrThrow(column)
realPath = cursor.getString(columnIndex)
}
cursor.close()
}
} catch (e: Exception) {
Log.i("GetFileUri Exception:", e.message ?: "")
}
val path = realPath.ifEmpty {
when {
newUri.path?.contains("/document/raw:") == true -> newUri.path?.replace(
"/document/raw:",
""
)
newUri.path?.contains("/document/primary:") == true -> newUri.path?.replace(
"/document/primary:",
"/storage/emulated/0/"
)
else -> return null
}
}
return if (path.isNullOrEmpty()) null else File(path)
}
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 );
}
为简化回答,跳过错误处理
经过大量的搜索和尝试不同的方法,我发现这个方法适用于不同的Android版本:
首先复制这个函数:
fun getRealPathFromUri(context: Context, contentUri: Uri): String {
var cursor: Cursor? = null
try {
val proj: Array<String> = arrayOf(MediaStore.Images.Media.DATA)
cursor = context.contentResolver.query(contentUri, proj, null, null, null)
val columnIndex = cursor?.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor?.moveToFirst()
return columnIndex?.let { cursor?.getString(it) } ?: ""
} finally {
cursor?.close()
}
}
然后,生成一个像这样的文件:
File(getRealPathFromUri(context, uri))
扩展基于@Jacek kwiecievik回答转换图像uri文件
fun Uri.toImageFile(context: Context): File? {
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = context.contentResolver.query(this, filePathColumn, null, null, null)
if (cursor != null) {
if (cursor.moveToFirst()) {
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val filePath = cursor.getString(columnIndex)
cursor.close()
return File(filePath)
}
cursor.close()
}
return null
}
如果我们使用File(uri.getPath()),它将不起作用
如果我们使用扩展从android-ktx,它仍然不能工作,因为
https://github.com/android/android-ktx/blob/master/src/main/java/androidx/core/net/Uri.kt