Android DownloadManager下载文件损坏无法打开,Bearer Token鉴权配置问题
问题根因及修复方案
1. 首要问题:授权头格式不匹配Laravel要求
Laravel框架的API认证(Passport/Sanctum)默认要求Bearer Token的请求头格式为 Authorization: Bearer <你的token>,你当前代码中使用Token 作为前缀,后端无法识别身份,实际下载到的是401未授权的错误页面内容而非源文件,所以文件损坏无法识别。
2. 其他潜在问题
- 授权头与Cookie冲突:如果你的接口是纯API令牌鉴权,不需要额外传递Cookie,同时传递两者可能触发Laravel的认证逻辑冲突
- MIME类型无兜底:
URLConnection.guessContentTypeFromName无法识别少见扩展名时会返回null,导致系统无法匹配文件打开方式 - 文件名合法性风险:
clickedItem.name如果包含特殊字符可能导致本地存储的文件名异常,系统无法识别
修复后的代码
下载请求代码
val downloadBaseUrl = "https://ticaphub.com/event-files/" val urlRequest = downloadBaseUrl + filepath val request = DownloadManager.Request(Uri.parse(urlRequest)) val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val title = URLUtil.guessFileName(urlRequest, null, null) request.setTitle(title) request.setDescription("Downloading File Attachments.") // 修复授权头前缀为Bearer request.addRequestHeader("Authorization", "Bearer " + this@TaskDetailsActivity .getSharedPreferences("loginCredential", Context.MODE_PRIVATE) .getString("userToken", "0")) // 纯API鉴权可删除Cookie传参 // request.addRequestHeader("cookie", cookie) request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, clickedItem.name) request.setMimeType(getMimeFromFileName(urlRequest)) downloadManager.enqueue(request)
优化后的MIME类型获取函数
private fun getMimeFromFileName(url: String): String { val mimeType = URLConnection.guessContentTypeFromName(url) // 识别不到时返回通用二进制流类型作为兜底 return mimeType ?: "application/octet-stream" }
验证方法
如果修改后仍有问题,可将下载的文件后缀改为.txt打开,若内容为HTML格式的错误提示,说明仍存在授权逻辑问题,可检查后端路由是否开启了API中间件、令牌是否有效。
内容的提问来源于stack exchange,提问作者beyondraymond
相关产品推荐
相关产品推荐

