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

如何让MediaPlayer通过URL链接在线播放音乐?现有本地播放代码如何改造

MediaPlayer网络音频播放适配方案

前置配置

首先在AndroidManifest.xml中添加必要配置:

<!-- 网络访问权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 如果使用HTTP明文链接,需要在application节点添加如下配置 -->
<application
    ...
    android:usesCleartextTraffic="true">
    ...
</application>

核心改造逻辑

原有MediaPlayer.create()方法仅适用于加载本地内置资源,加载网络资源需要改用异步初始化+准备回调的逻辑,避免主线程阻塞、调用方法抛出异常等问题。

改造后代码示例

// 替换原有MediaPlayer.create行,改为手动初始化
mediaPlayer = new MediaPlayer();
// 设置音频流类型为音乐
mediaPlayer.setAudioAttributes(
    new AudioAttributes.Builder()
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .setUsage(AudioAttributes.USAGE_MEDIA)
        .build()
);
try {
    // 替换为你的音乐URL链接
    mediaPlayer.setDataSource("https://你的音乐链接地址.mp3");
    // 异步准备,禁止调用prepare()阻塞主线程
    mediaPlayer.prepareAsync();
} catch (IOException e) {
    e.printStackTrace();
    // 此处可添加链接无效、网络异常的提示逻辑
}

runnable = new Runnable() {
    @Override
    public void run() {
        if(mediaPlayer != null && mediaPlayer.isPlaying()) {
            seekBar.setProgress(mediaPlayer.getCurrentPosition());
        }
        handler.postDelayed(this,500);
    }
};

// 准备完成回调,所有依赖MediaPlayer就绪的逻辑都要放到这里
mediaPlayer.setOnPreparedListener(mp -> {
    int duration = mp.getDuration();
    String sDuration = convertFormat(duration);
    playerDuration.setText(sDuration);
    seekBar.setMax(duration);
    // 准备完成后再开放播放按钮点击权限
    btPlay.setEnabled(true);
});

btPlay.setOnClickListener(v -> {
    mediaPlayer.start();
    handler.postDelayed(runnable, 0);
    btPlay.setVisibility(View.GONE);
    btPause.setVisibility(View.VISIBLE);
});

btPause.setOnClickListener(v -> {
    mediaPlayer.pause();
    btPlay.setVisibility(View.VISIBLE);
    btPause.setVisibility(View.GONE);
    handler.removeCallbacks(runnable);
});

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
        if (b && mediaPlayer != null) {
            mediaPlayer.seekTo(progress);
        }
        if(mediaPlayer != null) {
            playerPosition.setText(convertFormat(mediaPlayer.getCurrentPosition()));
        }
    }
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {}
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {}
});

mediaPlayer.setOnCompletionListener(mp -> {
    btPause.setVisibility(View.GONE);
    btPlay.setVisibility(View.VISIBLE);
    mediaPlayer.seekTo(0);
    handler.removeCallbacks(runnable);
});

// 页面销毁时释放资源避免内存泄漏
@Override
protected void onDestroy() {
    super.onDestroy();
    if(mediaPlayer != null) {
        mediaPlayer.release();
        mediaPlayer = null;
    }
    handler.removeCallbacks(runnable);
}

注意事项

  • 初始化阶段要捕获setDataSource相关的异常,处理无效链接、无网络等异常场景
  • 所有调用MediaPlayer方法的位置都要加非空判断,避免空指针异常
  • 禁止在主线程调用prepare()方法,必须使用prepareAsync()异步加载,否则网络较差时会触发ANR
  • 页面退出或者切换音频时要及时释放MediaPlayer资源

内容的提问来源于stack exchange,提问作者user15583048

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:06:02