我正在将文件保存在Downloads
设备目录(Android 11)
稍后由我的应用程序查看。我允许多种文件类型,例如pdf
, word
等等。我能够像这样保存文件:(我从here https://gitlab.com/commonsguy/download-wrangler/-/blob/master/app/src/main/java/com/commonsware/android/download/DownloadRepository.kt)
@TargetApi(29)
private suspend fun downloadQ(
url: String,
filename: String,
mimeType: String
) =
withContext(Dispatchers.IO) {
val response = ok.newCall(Request.Builder().url(url).build()).execute()
if (response.isSuccessful) {
val values = ContentValues().apply {
put(MediaStore.Downloads.DISPLAY_NAME, filename)
put(MediaStore.Downloads.MIME_TYPE, mimeType)
put(MediaStore.Downloads.IS_PENDING, 1)
}
val resolver = context.contentResolver
val uri =
resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
uri?.let {
resolver.openOutputStream(uri)?.use { outputStream ->
val sink = outputStream.sink().buffer()
response.body()?.source()?.let { sink.writeAll(it) }
sink.close()
}
values.clear()
values.put(MediaStore.Downloads.IS_PENDING, 0)
resolver.update(uri, values, null, null)
} ?: throw RuntimeException("MediaStore failed for some reason")
} else {
throw RuntimeException("OkHttp failed for some reason")
}
}
但是当我尝试检索该文件时,我尝试了以下方法但不起作用:
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID)
val id = cursor.getLong(idColumn)
Log.d("uri id ","$id")
val contentUri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI,id)
这种方法抛出了一个异常:
java.lang.IllegalArgumentException:无法找到包含 /external/downloads/78 的配置根目录
我懂了ID
(此处为 78)来自query
and cursor
from ContentResolver.query()
我希望它能返回Uri
我可以从中获取文件。
第二种方法是这样的:
val uri = MediaStore.Downloads.getContentUri("external",id)
uri.path?.let { filePath ->
Log.d("uri path ",filePath)
val file = File(filePath)
} ?: Log.d("uri path ","null")
I used external
作为基于的目录this https://stackoverflow.com/a/22069562/13343177答案,但这种方法也引发了相同的异常
java.lang.IllegalArgumentException:无法找到包含 /external/downloads/78 的配置根目录
最后,在我使用文件资源管理器应用程序查看确切的目录路径后,最终的工作是对类似的内容进行硬编码:
val file = File("storage/emulated/0/Download/$name.$extension")
所以我的问题是,如何动态获取该路径的值,并且该路径对于所有可以这样使用的设备都相同吗?
编辑:我也想知道我是否正在使用filename
这是extension
要查看文件,那么如果用户下载另一个同名文件,那么如何确保打开正确的文件? (即使我在里面为我的应用程序创建一个单独的目录Download
,用户仍然可以下载同一个文件两次,其名称如下storage/emulated/0/Download/myDir/file(2).extension
)