Android如何通过Intent打开指定的自定义下载文件夹?
问题分析与解决方案
1. 核心问题:路径获取逻辑错误
你当前用context.getExternalFilesDir()获取的是应用私有外部存储目录,但你的文件实际存在公共的Downloads/MyDirectory目录下,两者路径完全不匹配,这是打开错误文件夹的根本原因。
正确获取公共Downloads下MyDirectory的方式:
val targetFolder = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyDirectory" )
2. 适配Android版本的Uri处理
从Android 7.0(API 24)开始,直接使用Uri.fromFile()会抛出FileUriExposedException,且系统文件管理器对file:// Uri的支持不一致,推荐以下两种可靠实现方式:
方式一:使用ACTION_VIEW精准打开目标文件夹
val targetFolder = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyDirectory" ) val intent = Intent(Intent.ACTION_VIEW).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK type = "resource/folder" // 适配多数文件管理器的文件夹MIME类型 // 分版本处理Uri data = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // Android 10+ 使用MediaStore的Content Uri MediaStore.Downloads.EXTERNAL_CONTENT_URI.buildUpon() .appendPath("MyDirectory") .build() } else { Uri.fromFile(targetFolder) } } // 先判断是否有可处理该Intent的应用,避免崩溃 if (intent.resolveActivity(application.packageManager) != null) { application.startActivity(intent) }
方式二:使用ACTION_OPEN_DOCUMENT_TREE(更稳定)
如果需要更精准地定位到目标文件夹,可使用系统的文档树Intent:
val targetFolder = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "MyDirectory" ) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 指定初始打开的目录 val baseUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI val treeId = DocumentsContract.getTreeDocumentId(baseUri) + "/MyDirectory" val initialUri = DocumentsContract.buildDocumentUriUsingTree(baseUri, treeId) putExtra(DocumentsContract.EXTRA_INITIAL_URI, initialUri) } } if (intent.resolveActivity(application.packageManager) != null) { application.startActivity(intent) }
3. 修正下载代码的冗余设置
你的下载代码同时调用了setDestinationInExternalPublicDir和setDestinationUri,会导致路径覆盖,只需保留其中一种即可:
request = DownloadManager.Request(url) .setAllowedOverRoaming(false) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) // 推荐使用该方法,自动处理路径拼接 .setDestinationInExternalPublicDir( Environment.DIRECTORY_DOWNLOADS, "MyDirectory/${FILE_NAME}" )
额外注意事项
- Android 9及以下设备需提前声明并动态申请
WRITE_EXTERNAL_STORAGE权限;Android 10及以上无需该权限。 - 部分第三方文件管理器对Intent的支持存在差异,务必添加
intent.resolveActivity的判断逻辑,避免崩溃。
内容的提问来源于stack exchange,提问作者Korsun Pavel
相关产品推荐
相关产品推荐

