要解决这个问题,我遇到了一个问题,我正在使用Intent.createChooser
选择一个文件,并且我使用了各种不同的方法来获取文件的绝对路径,并且它们都会导致在content://downloads/public_downloads/1006
中。
在仿真器中使用此路径可以很好地工作并产生预期的结果,但是当我在设备(Galaxy S9)上构建应用程序后,我收到一个错误消息,指出该文件不存在。
我已请求Manifest.permission.READ_EXTERNAL_STORAGE
和Manifest.permission.WRITE_EXTERNAL_STORAGE
的权限,并验证该权限已在应用程序中启用。
经过几个小时的搜索后,我没有足够的想法去尝试,如果有人能以正确的方式指导我,我会很高兴。
我当前用于获取绝对路径的方法是
private fun getAbsoluteFilePath(uri: Uri): String {
val id = DocumentsContract.getDocumentId(uri)
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/my_downloads"), id.toLong())
val projection = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(contentUri, projection, null, null, null)
val columnIndex = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
return cursor.getString(columnIndex)
}
但我也尝试过
object PathUtil {
/*
* Gets the file path of the given Uri.
*/
@SuppressLint("NewApi")
@Throws(URISyntaxException::class)
fun getPath(context: Context, uri: Uri): String? {
var uri = uri
val needToCheckUri = Build.VERSION.SDK_INT >= 19
var selection: String? = null
var selectionArgs: Array<String>? = null
// Uri is different in versions after KITKAT (Android 4.4), we need to
// deal with different Uris.
if (needToCheckUri && DocumentsContract.isDocumentUri(context.applicationContext, uri)) {
if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
}
if (isDownloadsDocument(uri)) {
val id = DocumentsContract.getDocumentId(uri)
uri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
} else if (isMediaDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
if ("image" == type) {
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
} else if ("video" == type) {
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
} else if ("audio" == type) {
uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
selection = "_id=?"
selectionArgs = arrayOf(split[1])
}
}
if ("content".equals(uri.scheme, ignoreCase = true)) {
val projection = arrayOf(MediaStore.Images.Media.DATA)
var cursor: Cursor? = null
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
val columnIndex = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
if (cursor!!.moveToFirst()) {
return cursor!!.getString(columnIndex)
}
} else if ("file".equals(uri.scheme, ignoreCase = true)) {
return uri.path
}
return null
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
fun isExternalStorageDocument(uri: Uri): Boolean {
return "com.android.externalstorage.documents" == uri.authority
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
fun isMediaDocument(uri: Uri): Boolean {
return "com.android.providers.media.documents" == uri.authority
}
}
产生相同的结果,我的代码或多或少是这样的:
fun doSomething() {
val intent = Intent().apply {
action = Intent.ACTION_GET_CONTENT
type = "*/*"
addCategory(Intent.CATEGORY_OPENABLE)
}
val chooser = Intent.createChooser(intent, "Select")
startActivityForResult(chooser, 1)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
ZipFile(getAbsoluteFilePath(data.data))
}
哦,请不要重复进行此操作-我发现了很多类似的问题,但是还没有解决方案对我有用,不确定我所缺少的是什么,但我敢打赌这是愚蠢的