在 Android 中使用 MediaPlayer 實現簡單音頻播放,需注意文件路徑、權限、異步準備等關鍵點,否則會出現無聲音、崩潰等問題。
MediaPlayer mp = new MediaPlayer();
mp.setDataSource("/home/usr/audio/file.mp3"); // 錯誤:電腦路徑非手機路徑
mp.prepare(); // 同步準備會阻塞主線程
mp.start();
/home/usr/... 是 Linux/電腦路徑,Android 設備無此路徑READ_EXTERNAL_STORAGE 權限prepare() 在主線程執行會導致 ANROnErrorListener、OnCompletionListener// 原始資源 (res/raw/)
mp = MediaPlayer.create(this, R.raw.music);
// Assets 目錄
AssetFileDescriptor afd = getAssets().openFd("music.mp3");
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// 外部存儲 (需權限)
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), "music.mp3");
mp.setDataSource(file.getAbsolutePath());
// 網絡流媒體
mp.setDataSource("https://example.com/music.mp3");
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start(); // 準備完成後自動播放
}
});
mp.prepareAsync(); // 異步準備,不阻塞主線程
public class SimpleAudioPlayer {
private MediaPlayer mediaPlayer;
private Context context;
public SimpleAudioPlayer(Context context) {
this.context = context;
}
public void playRawResource(@RawRes int resId) {
release();
mediaPlayer = MediaPlayer.create(context, resId);
mediaPlayer.setOnCompletionListener(mp -> release());
mediaPlayer.start();
}
public void playFile(String filePath) {
release();
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(filePath);
mediaPlayer.setOnPreparedListener(mp -> mp.start());
mediaPlayer.setOnCompletionListener(mp -> release());
mediaPlayer.setOnErrorListener((mp, what, extra) -> {
release();
return true;
});
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
public void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
public void release() {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
public boolean isPlaying() {
return mediaPlayer != null && mediaPlayer.isPlaying();
}
}
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 後台播放需前台服務 -->
adb push music.mp3 /sdcard/Music//sdcard/ 或 /storage/emulated/0/| 場景 | 推薦方案 |
|---|---|
| 簡單音效、短音頻 | SoundPool / MediaPlayer.create() |
| 音樂播放器 App | ExoPlayer + MediaSession + Foreground Service |
| 網絡電台、直播流 | ExoPlayer (支持 HLS/DASH) |
| 短視頻、視頻播放 | ExoPlayer / Media3 |