You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 16:06:05