Android DownloadManager指定选中目录下载的适配问题
解决方案
1. 持久化文件夹访问权限
通过ACTION_OPEN_DOCUMENT_TREE获取用户选中的目录Tree Uri后,先申请持久化读写权限,避免应用重启后失去访问权:
Uri treeUri = resultData.getData(); // 从Activity回调中拿到的Tree Uri int permissionFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION; getContentResolver().takePersistableUriPermission(treeUri, permissionFlags);
2. 在目标目录创建下载文件的DocumentFile
用Tree Uri生成对应文件夹的DocumentFile实例,再在其中创建要下载的目标文件:
// 实例化选中的文件夹 DocumentFile targetFolder = DocumentFile.fromTreeUri(this, treeUri); // 创建下载文件,按需调整MIME类型和文件名 String fileMimeType = "application/octet-stream"; String downloadFileName = "target_file.pdf"; DocumentFile downloadFile = targetFolder.createFile(fileMimeType, downloadFileName);
3. 配置DownloadManager使用目标文件Uri
直接将downloadFile.getUri()传给DownloadManager.Request的setDestinationUri方法即可,系统DownloadManager支持content://类型的Uri作为下载目标:
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse("https://your-download-url.com/file")); // 设置下载路径为用户选中目录下的文件 request.setDestinationUri(downloadFile.getUri()); // 可选配置:下载通知、网络限制等 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE); // 发起下载 long downloadId = downloadManager.enqueue(request);
关键注意点
- Android 10+无需申请
WRITE_EXTERNAL_STORAGE运行时权限,但低版本(Android 9及以下)仍需正常申请。 - 如果
createFile()返回null,说明当前没有写入权限,检查权限申请流程是否正确。 - 极少数旧设备的DownloadManager可能不兼容
content://Uri,这种场景建议用自定义下载逻辑(比如OkHttp配合ContentResolver写入文件)替代系统服务。
内容的提问来源于stack exchange,提问作者SH DM
相关产品推荐
相关产品推荐

