安卓如何从URL下载MP3文件到下载目录并解决播放报错问题
安卓下载MP3文件到系统下载目录解决方案
现有代码问题排查
- 无流读写逻辑:你仅创建了空字节数组,未从
InputStream读取网络端的音频数据就直接写入本地,最终生成的是损坏的空内容文件,自然无法被音频播放器识别 - 存储路径不兼容:
Environment.getExternalStorageDirectory()在Android 10(API 29)及以上系统已被官方废弃,直接使用会出现路径无法访问、权限报错等问题 - 异常被静默忽略:catch块直接吞掉所有异常,你无法定位运行时出现的网络异常、权限错误等问题
- 异步方案过时:AsyncTask已被官方弃用,长期维护更推荐使用协程、WorkManager等新异步方案
前置配置
首先在AndroidManifest.xml中添加必要权限:
<!-- 网络访问权限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 存储权限适配 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" android:minSdkVersion="33" />
注意Android 6.0及以上系统需要动态申请存储相关权限,权限未授予时无法写入公共下载目录。
修正后的代码实现
public class DownloadFile extends AsyncTask<String, Integer, String> { private final String videoUrl; private final Context context; // 传入上下文用于适配目录获取 public DownloadFile(String videoUrl, Context context) { this.videoUrl = videoUrl; this.context = context; } @Override protected String doInBackground(String... params) { InputStream input = null; OutputStream output = null; URLConnection connection = null; try { URL url = new URL(videoUrl); connection = url.openConnection(); connection.connect(); input = new BufferedInputStream(url.openStream()); // 获取系统公共下载目录,适配全版本系统 File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); File outputFile = new File(downloadDir, "test.mp3"); output = new FileOutputStream(outputFile); byte[] data = new byte[1024]; int readLength; // 循环读取网络流数据写入本地文件 while ((readLength = input.read(data)) != -1) { output.write(data, 0, readLength); } output.flush(); } catch (Exception e) { e.printStackTrace(); return "下载失败:" + e.getMessage(); } finally { // 统一关闭流资源 try { if (output != null) output.close(); if (input != null) input.close(); } catch (IOException ignored) {} } return "下载完成"; } }
额外优化建议
如果目标SDK版本为29及以上,更推荐使用系统自带的DownloadManager服务实现下载,无需自行处理流读写、网络状态判断等逻辑,稳定性和兼容性更高。
内容的提问来源于stack exchange,提问作者Biscoitinho
相关产品推荐
相关产品推荐

