什么是最简单的方法从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());
要正确地使用context uri获取文件,
感谢来自@Mohsents, @Bogdan Kornev, @CommonsWare, @Juan Camilo Rodriguez的回答Durán;
我从uri中创建了一个inputStream,并使用这个iStream创建了一个临时文件,最后我能够从这个文件中提取uri和路径。
fun createFileFromContentUri(fileUri : Uri) : File{
var fileName : String = ""
fileUri.let { returnUri ->
requireActivity().contentResolver.query(returnUri,null,null,null)
}?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor.moveToFirst()
fileName = cursor.getString(nameIndex)
}
// For extract file mimeType
val fileType: String? = fileUri.let { returnUri ->
requireActivity().contentResolver.getType(returnUri)
}
val iStream : InputStream = requireActivity().contentResolver.openInputStream(fileUri)!!
val outputDir : File = context?.cacheDir!!
val outputFile : File = File(outputDir,fileName)
copyStreamToFile(iStream, outputFile)
iStream.close()
return outputFile
}
fun copyStreamToFile(inputStream: InputStream, outputFile: File) {
inputStream.use { input ->
val outputStream = FileOutputStream(outputFile)
outputStream.use { output ->
val buffer = ByteArray(4 * 1024) // buffer size
while (true) {
val byteCount = input.read(buffer)
if (byteCount < 0) break
output.write(buffer, 0, byteCount)
}
output.flush()
}
}
}
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 );
}
为简化回答,跳过错误处理