Android DownloadManager下载文件未存入Download文件夹如何解决
问题描述
开发中使用DownloadManager下载PDF与图片文件时,下载完成的文件未保存到系统Download文件夹,相关实现位于HomeActivity内,原代码如下:
val fileName = "MG Uploaded Documents" val request = DownloadManager.Request(Uri.parse(downloadUrl)) .setTitle("Download") .setDescription("Downloading") request.setDestinationUri( Uri.fromFile(File(this.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) .toString() , fileName))) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) .setAllowedOverMetered(true) val dm = this.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager dm.enqueue(request) this.T("File is Downloading. Please wait!")
问题根因
原代码存在3个核心问题:
- 路径选择错误:
getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)获取的是应用私有下载目录,对应路径为/sdcard/Android/data/当前应用包名/files/Download,不属于系统公共Download文件夹。该目录下的文件会随应用卸载被删除,且默认对其他应用、系统文件管理器不可见。 - 公共目录写入方式错误:Android 10及以上版本启用分区存储机制,应用无法直接通过File路径随意写入公共存储目录,直接使用
setDestinationUri指向公共Download路径会抛出权限异常。 - 文件名缺失格式后缀:原代码设置的文件名未携带.pdf/.jpg/.png等对应格式后缀,下载完成后系统无法识别文件类型,也会导致用户无法在Download文件夹中识别到目标文件。
修改方案
- 放弃手动拼接File路径的写法,改用DownloadManager提供的
setDestinationInExternalPublicDirAPI直接指定写入系统公共Download目录,该API由系统服务代理写入,不需要应用单独申请存储权限即可在全版本Android系统正常工作。 - 根据下载文件的实际类型,给文件名补充对应的格式后缀,保证系统可以正常识别文件类型。
- 权限适配:若应用
targetSdkVersion>= 29,无需额外申请存储权限;若targetSdkVersion< 29,需要在AndroidManifest中声明WRITE_EXTERNAL_STORAGE权限,并在Android 6.0+版本动态申请该权限。
修改后的可正常运行代码如下:
// 请根据实际下载的文件类型替换后缀,例如下载PDF则补.pdf,下载jpg图片则补.jpg val fileName = "MG Uploaded Documents.pdf" val request = DownloadManager.Request(Uri.parse(downloadUrl)) .setTitle("Download") .setDescription("Downloading") // 直接指定写入系统公共Download目录 .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) .setAllowedOverMetered(true) val dm = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager dm.enqueue(request) T("File is Downloading. Please wait!")
提示:修改后下载完成的文件会直接展示在系统公共Download文件夹中,用户可通过系统文件管理器、系统下载记录直接查看、打开文件。
内容的提问来源于stack exchange,提问作者dennisrufigill
相关产品推荐
相关产品推荐

