在当时,把uri复制到沙盒目录是谷歌推荐的方法,这方法用到android11以上,同样有效,但android11有了效率更高的方法:
首先,添加 requestLegacyExternalStorage="true" ,这样android10也能使用该方法
fun uriToFile(context: Context, uri: Uri): File? {
try {
val docId = try {
DocumentsContract.getDocumentId(uri)
}catch (e:Exception){
try {
DocumentsContract.getTreeDocumentId(uri)
}catch (e:Exception){""}
}
val split = docId.split(":")
val type = split[0]
if(type.equals("primary",true)){
return runCatching { File("${Environment.getExternalStorageDirectory()}/${split[1]}") }.getOrNull()
}else{
val manager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumeClazz = Class.forName("android.os.storage.StorageVolume")
val getVolumeList: Method = manager.javaClass.getMethod("getVolumeList")
val getUuid = storageVolumeClazz.getMethod("getUuid")
val getState = storageVolumeClazz.getMethod("getState")
val getPath = storageVolumeClazz.getMethod("getPath")
val result = getVolumeList.invoke(manager)
val length = java.lang.reflect.Array.getLength(result)
for (i in 0 until length){
val ele = java.lang.reflect.Array.get(result,i)
if(Environment.MEDIA_MOUNTED == getState.invoke(ele) || Environment.MEDIA_MOUNTED_READ_ONLY == getState.invoke(ele)){
val uuid = getUuid.invoke(ele) as? String
if(uuid == type){
return runCatching { File("${getPath.invoke(ele)}/${split[1]}") }.getOrNull()
}
}
}
}
}catch (e:Exception){
}
return null
}