Android使用DownloadManager下载PDF提示完成但无文件下载是什么原因?
问题原因及修复方案
1. 权限配置缺失
- 必须添加网络权限,在
AndroidManifest.xml中加入以下配置:<uses-permission android:name="android.permission.INTERNET" /> - 若目标设备运行Android 9及更低版本(API ≤28),还需添加存储权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2. HTTP明文请求被限制
Android 9及以上系统默认禁止HTTP明文流量,你当前使用的是HTTP协议的下载链接,两种解决方案可选:
- 优先替换为HTTPS协议的链接:将下载地址改为
https://www.africau.edu/images/default/sample.pdf - 若必须使用HTTP,在
AndroidManifest.xml的<application>标签中添加配置允许明文流量:<application ... android:usesCleartextTraffic="true">
3. 未显式指定下载存储路径
默认的存储路径可能导致你找不到下载的文件,建议在DownloadManager.Request配置中新增显式路径声明,直接存入系统公共下载目录:
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "sample.pdf")
添加后完整的请求配置示例:
var downloadRequest = DownloadManager.Request( Uri.parse ("https://www.africau.edu/images/default/sample.pdf")) .setTitle("a pdf") .setDescription("a pdf") .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE) .setAllowedOverMetered(true) .setAllowedOverRoaming(true) // 新增指定存储路径 .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "sample.pdf")
4. 广播接收器未校验下载结果
当前你只判断了下载任务ID匹配,但未校验下载是否成功,即使下载失败也会触发done提示,需要补充状态校验逻辑:
var receiver = object:BroadcastReceiver(){ override fun onReceive(context: Context?, intent: Intent?) { var id= intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) if (downloadID == id){ val query = DownloadManager.Query().setFilterById(id!!) val cursor = downloadManager.query(query) if (cursor.moveToFirst()) { val status = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) when(status){ DownloadManager.STATUS_SUCCESSFUL -> { Toast.makeText(applicationContext, "下载完成,文件已存至下载目录",Toast.LENGTH_LONG).show() } DownloadManager.STATUS_FAILED -> { val errorCode = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON)) Toast.makeText(applicationContext, "下载失败,错误码:$errorCode",Toast.LENGTH_LONG).show() } } } cursor.close() } } }
5. 额外注意项
动态注册的广播需要在页面销毁时注销,避免内存泄漏,在Activity的onDestroy生命周期中添加:
override fun onDestroy() { super.onDestroy() unregisterReceiver(receiver) }
内容的提问来源于stack exchange,提问作者skushu
相关产品推荐
相关产品推荐

