Android WebView DownloadListener无法正常下载Excel文件问题求助
问题排查与修复方案
1. 补充WebView基础配置
大部分下载异常是WebView基础配置缺失导致,先确认你已添加以下配置:
web.settings.apply { javaScriptEnabled = true // 绝大多数站点的下载按钮由JS触发,必须开启 domStorageEnabled = true allowFileAccess = true // 若站点是HTTPS但下载链接为HTTP,需添加混合内容适配 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW } }
2. 给DownloadManager添加Cookie授权
Excel下载链接通常需要站点登录态或Cookie校验,浏览器会自动携带Cookie,但系统DownloadManager默认不会同步WebView的Cookie,需手动添加:
在你创建DownloadManager.Request的代码后追加以下内容:
// 同步WebView的Cookie到下载请求 val cookie = CookieManager.getInstance().getCookie(url) if (cookie != null) { request.addRequestHeader("Cookie", cookie) } // 保持UA和WebView一致,避免站点拦截请求 request.addRequestHeader("User-Agent", userAgent)
3. 适配高版本Android权限
- Android 10(API 29)及以上:你使用的
setDestinationInExternalPublicDir指向公共下载目录,无需申请WRITE_EXTERNAL_STORAGE权限,系统会自动授权 - Android 13(API 33)及以上:
WRITE_EXTERNAL_STORAGE权限已完全废弃,申请也不会被系统授予,建议在权限申请逻辑中添加版本判断,仅在API <= 28时申请该权限
4. 修复广播接收器注册逻辑
不要在onDownloadStart方法中注册广播,每次触发下载都会重复注册,不仅会引发内存泄漏,还会导致下载完成回调多次触发。把广播的注册/注销逻辑移到Activity生命周期中:
// 放在Activity类内部,不要嵌套在DownloadListener中 private val onComplete = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Toast.makeText(applicationContext, "Downloading Complete", Toast.LENGTH_SHORT).show() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 其他初始化逻辑 registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) } override fun onDestroy() { super.onDestroy() unregisterReceiver(onComplete) }
5. 特殊场景处理
如果你的Excel是点击按钮后通过POST请求动态生成的,系统DownloadManager不支持POST请求,这种情况需要你自己用OkHttp等网络库发起POST请求,把返回的文件流写入本地存储,不要使用系统DownloadManager。
排查时可以在onDownloadStart中打印传入的url参数,确认拿到的是可直接访问的Excel下载链接,如果url为blob协议地址,需要单独处理blob类型下载,同样不适用系统DownloadManager。
内容的提问来源于stack exchange,提问作者Ratri
相关产品推荐
相关产品推荐

