Android Studio中使用DownloadManager下载音频得到未知文件如何解决
问题根因
该现象通常由两类原因导致:
- 音频链接的路径末尾没有
.mp3后缀,DownloadManager默认取URL最后一段作为文件名,无法自动识别音频格式 - 服务端对非浏览器UA的请求返回了错误的
Content-Type响应头,DownloadManager无法匹配到正确的文件格式
解决方案
直接通过配置DownloadManager的请求参数即可解决,不需要引入WebView:
步骤1:添加必要权限
在AndroidManifest.xml中声明下载所需权限:
<!-- 网络访问权限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Android 13及以上版本下载到公共Download目录无需额外存储权限,以下版本需要 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- 可选:静默下载权限,不需要可移除 --> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
步骤2:构造下载请求
主动配置请求头、MIME类型、文件名后缀,对齐浏览器请求规则:
Java示例代码
String audioUrl = "替换为你的音频链接"; String saveFileName = "自定义音频名称.mp3"; // 必须带.mp3后缀 DownloadManager.Request request = new DownloadManager.Request(Uri.parse(audioUrl)); // 配置和移动端浏览器一致的UA,避免服务端返回异常响应头 request.setHeader("User-Agent", "Mozilla/5.0 (Linux; Android 13; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36"); // 强制指定MP3的MIME类型,覆盖服务端返回的错误类型 request.setMimeType("audio/mpeg"); // 指定存储路径和带后缀的文件名,示例保存到公共下载目录 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, saveFileName); // 配置下载通知可见性 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // 配置允许下载的网络类型 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE); // 加入下载队列 DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); long downloadId = downloadManager.enqueue(request);
Kotlin示例代码
val audioUrl = "替换为你的音频链接" val saveFileName = "自定义音频名称.mp3" val request = DownloadManager.Request(Uri.parse(audioUrl)).apply { setHeader("User-Agent", "Mozilla/5.0 (Linux; Android 13; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36") setMimeType("audio/mpeg") setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, saveFileName) setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE) } val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val downloadId = downloadManager.enqueue(request)
补充说明
- 如果服务端配置了防盗链,可额外添加
request.setHeader("Referer", "音频所属站点的域名")即可正常访问资源 - 如果需要自动适配服务端返回的文件名,可以先发起一次HEAD请求,解析响应头的
Content-Disposition字段获取官方文件名后再传入DownloadManager配置
内容的提问来源于stack exchange,提问作者quannm18
相关产品推荐
相关产品推荐

