[Android]AudioFocesRequest类粗略解析

AudioFocus是Android用来管理对Audio资源的竞争,举个例子:当QQ音乐、网易云音乐、酷我音乐等多个音乐播放器在播放音乐时,只有一个会播放音乐,其它的音乐播放器会自动停止,这就是因为这几家音乐播放器平台都使用了AudioFocus来管理,如果不适用这个机制的话就会出现多家播放器同时播放音乐的现象。

网上讲解AudioFocus的例子很多,但是很多都是使用的废弃的方法,如下所示:

public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)

这里就不说这个废弃的方法了,改为介绍现在推荐的的新的获取,如下所示:

public int requestAudioFocus(@NonNull AudioFocusRequest focusRequest)

可以看到旧的获取焦点的方法传入的参数是AudioFocousChangeListener、streamType和durationHint,而新的是传入AudioFocusRequest对象,百度了一下发现没什么人讲解这个AudioFocusRequest对象,所以只好看官方文档了,官方文档链接如下:https://developer.android.google.cn/reference/android/media/AudioFocusRequest

网页上讲解的很详细,这里粗略的翻译一下。

首先,讲了一下什么是AudioFocus:It is used to convey the fact that a user can only focus on a single audio stream at a time(它用来确保同一时间用户只能将焦点放到单一音频流上),这里最需要关注的句子是:Note: applications should not play anything until granted focus(应用在获取焦点前不应该播放任何音频)。当然啦,你不遵从也不影响你的应用使用,只不过会影响体验。

接着,讲了一下Foces的不同的类型

            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_LOSS:
                    //长时间丢失焦点,当其他应用申请的焦点为AUDIOFOCUS_GAIN时,
                    //会触发此回调事件,例如播放QQ音乐,网易云音乐等
                    //通常需要暂停音乐播放,若没有暂停播放就会出现和其他音乐同时输出声音
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    //短暂性丢失焦点,当其他应用申请AUDIOFOCUS_GAIN_TRANSIENT或AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE时,
                    //会触发此回调事件,例如播放短视频,拨打电话等。
                    //通常需要暂停音乐播放
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    //短暂性丢失焦点并作降音处理
                    break;
                case AudioManager.AUDIOFOCUS_GAIN:
                    //当其他应用申请焦点之后又释放焦点会触发此回调
                    //可重新播放音乐
                    break;

            }

然后就是如何确定你的AudioFocusRequest,这里其实没什么好说的,直接看官方给出的例子就好了,我这里做了删减,毕竟没有全部用到,如果需要的话请自行研究:

 // 初始化音频属性和焦点
 mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
 mPlaybackAttributes = new AudioAttributes.Builder()
         .setUsage(AudioAttributes.USAGE_MEDIA)
         .build();
 mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
         .setAudioAttributes(mPlaybackAttributes)
         .build();
 mMediaPlayer = new MediaPlayer();
 mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
 final Object mFocusLock = new Object();

 boolean mPlaybackDelayed = false;

 // 请求音频焦点,成功后播放音乐,失败后不播放
 int res = mAudioManager.requestAudioFocus(mFocusRequest);
 synchronized (mFocusLock) {
     if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
         mPlaybackDelayed = false;
     } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
         mPlaybackDelayed = false;
         playbackNow();
     }
 }

 // OnAudioFocusChangeListener的实现,也就是监听到的音频焦点变化
 @Override
 public void onAudioFocusChange(int focusChange) {
     switch (focusChange) {
         case AudioManager.AUDIOFOCUS_GAIN:
             if (mPlaybackDelayed || mResumeOnFocusGain) {
                 synchronized (mFocusLock) {
                     mPlaybackDelayed = false;
                     mResumeOnFocusGain = false;
                 }
                 playbackNow();
             }
             break;
         case AudioManager.AUDIOFOCUS_LOSS:
             synchronized (mFocusLock) {
                 // this is not a transient loss, we shouldn't automatically resume for now
                 mResumeOnFocusGain = false;
                 mPlaybackDelayed = false;
             }
             pausePlayback();
             break;
         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
             // we handle all transient losses the same way because we never duck audio books
             synchronized (mFocusLock) {
                 // we should only resume if playback was interrupted
                 mResumeOnFocusGain = mMediaPlayer.isPlaying();
                 mPlaybackDelayed = false;
             }
             pausePlayback();
             break;
     }
 }

暂时就到这里吧,以后使用中有问题再补充到这里

发布了61 篇原创文章 · 获赞 2 · 访问量 8724

猜你喜欢

转载自blog.csdn.net/woaily1346/article/details/86623655