Android Q及以上版本如何安全访问公共Download目录原路径?
Android Q及以上版本安全访问公共下载目录的方法
在Android Q(API 29)之前,我们常用以下代码访问公共下载存储目录,但该API现已被废弃:
var publicExternalFilesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
在模拟器中,该路径指向:
/mnt/sdcard/Download/
Android Q及以上版本是有安全访问该路径的方法的,下面分两种常用场景说明:
一、官方推荐:使用MediaStore API
Android Q引入了分区存储(Scoped Storage),公共媒体目录的访问需通过MediaStore操作,这是合规且无需特殊敏感权限的方式:
查询下载目录文件
val projection = arrayOf( MediaStore.Downloads._ID, MediaStore.Downloads.DISPLAY_NAME, MediaStore.Downloads.RELATIVE_PATH ) val queryUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI val selection = "${MediaStore.Downloads.RELATIVE_PATH} = ?" val selectionArgs = arrayOf("Download/") context.contentResolver.query( queryUri, projection, selection, selectionArgs, null )?.use { cursor -> while (cursor.moveToNext()) { val fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Downloads.DISPLAY_NAME)) // 在这里处理获取到的文件信息 } }
向下载目录写入文件
val contentValues = ContentValues().apply { put(MediaStore.Downloads.DISPLAY_NAME, "example.txt") put(MediaStore.Downloads.MIME_TYPE, "text/plain") put(MediaStore.Downloads.RELATIVE_PATH, "Download/") } val uri = context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) uri?.let { context.contentResolver.openOutputStream(it)?.use { outputStream -> outputStream.write("测试内容".toByteArray()) } }
注:Android Q及以上版本,通过MediaStore写入公共下载目录无需申请READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限。
二、特殊场景:使用MANAGE_EXTERNAL_STORAGE权限
如果你的应用是文件管理器、备份工具这类需要完整访问外部存储的类型,可以申请MANAGE_EXTERNAL_STORAGE权限,但该权限需要用户手动在设置中开启,且Google Play审核严格,非必要不建议使用:
- 在Manifest中添加权限:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />
- 检查并引导用户开启权限:
if (Environment.isExternalStorageManager()) { // 权限已获取,可直接访问路径 val downloadDir = File(Environment.getExternalStorageDirectory(), "Download") } else { // 跳转至应用权限设置页面 val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) intent.data = Uri.parse("package:${context.packageName}") startActivity(intent) }
总结:优先使用MediaStore API来访问公共下载目录,它符合Android的隐私规范,也能避免权限审核问题;仅当应用有特殊需求时,再考虑使用MANAGE_EXTERNAL_STORAGE权限。
内容的提问来源于stack exchange,提问作者Ayub
相关产品推荐
相关产品推荐

