Android 语音播放Media Player

本文介绍了在Android中使用MediaPlayer进行语音播放,包括本地和网络音频的播放流程,强调了不在主线程中使用prepare的重要性。同时,文章提到了唤醒锁(Wake Locks)的使用,确保后台播放音乐时不被手机休眠影响。此外,还讨论了Audio Focus概念,用于多应用间音频播放的协调,以及如何处理AUDIO_BECOMING_NOISY事件,如拔出耳机时暂停播放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:
https://developer.android.com/guide/topics/media/mediaplayer.html#viacontentresolver

语音播放

因为实习工作相关的缘故,最近在学习android语音播放的内容。

MediaPlayer

音频播放

MediaPlayer可以播放本地或者网络的音频,流程如下:

Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();

注意,mediaPlayer的prepare最好不要在主线程中使用,以免发生卡顿。如果要在主线程中用,应该使用prepareAsync,并设置回调接口。
音频播放完,记得要释放资源:

mediaPlayer.release();
mediaPlayer = null;
唤醒锁 Wake Locks

当手机休眠的时候,可能会停止诸如WiFi,CPU的一些模块。如果这个时候你的程序仍要在后台运行播放音乐,就需要放置一些功能诸如WiFi休眠。

Wake Lock 的作用就是在手机休眠时,通知手机你的程序仍然在使用某些模块,不要试图去关闭它们。

当初始化时,调用 mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); 可以保持CPU不被关闭。然而,这里仅仅保证了CPU的运行。如果播放的是流媒体音乐,需要使用wifi,那么还要获取wifi lock。

WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
    .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");

wifiLock.acquire();

当停止播放时,可以释放wifi lock。


Audio Focus

安卓是多应用的系统,后台可能有多个程序在同时运行。假如你在听音乐,这个时候突然打进来电话。如果音乐播放没有停止的话,那么你的和别人打电话的时候就会自带BGM,这种体验多数时候并不是让人那么愉快的。
为了解决这个问题,自android 2.2起,引入了Audio Focus用于让每个应用协调谁来使用扬声器播放。当某个应用获得了audio focus,那么它可以自由的使用扬声器。同时需要实现focus change接口,当其它应用获取audio focus时回调,及时的停止音乐的播放。
当然了,这并不是一种强制的机制,哪怕你失去了audio focus,依旧可以播放音乐。没有什么可以阻止你,但多半用户会关掉你。

获取audio focus 的代码如下:

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus( AudioManager.OnAudioFocusChangeListener, AudioManager.STREAM_MUSIC,
    AudioManager.AUDIOFOCUS_GAIN);

if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    // could not get audio focus.
}

其中AudioFocusChangeListener如下:

public void onAudioFocusChange(int focusChange) {
    switch (focusChange) {
        case AudioManager.AUDIOFOCUS_GAIN:
            // 可以继续播放
            if (mMediaPlayer == null) initMediaPlayer();
            else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
            mMediaPlayer.setVolume(1.0f, 1.0f);
            break;

        case AudioManager.AUDIOFOCUS_LOSS:
            // 失去Audio Focus,应该停止播放并释放资源。
            if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
            break;

        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
            // 暂时失去,可能一会还会获得,可以停止播放但是不需要释放资源
            if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
            break;

        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
            // 失去Focus,但是可以以比较小的声音继续播放。
            if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
            break;
    }
}

处理AUDIO_BECOMING_NOISY

当用户拔出耳机的时候,很多程序会选择暂停播放,这个是通过响应AUDIO_BECOMING_NOISY 的intent来实现的。
方法很简单,在你的程序中注册广播:

<receiver android:name=".MusicIntentReceiver">
   <intent-filter>
      <action android:name="android.media.AUDIO_BECOMING_NOISY" />
   </intent-filter>
</receiver>
public class MusicIntentReceiver extends android.content.BroadcastReceiver {
   @Override
   public void onReceive(Context ctx, Intent intent) {
      if (intent.getAction().equals(
                    android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
          // signal your service to stop playback
          // (via an Intent, for instance)
      }
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值