在做蓝牙带屏音箱项目的时候,碰到一个问题,具体是在连接蓝牙音箱回连的时候,播放音乐会在手机端点击播放过一会就回被暂停。
调试了一下问题后,大概问题是这样的,一般情况下,我们在播放音乐时会请求系统音频焦点,然后在不播放的时候释放焦点。
我也是按照这种逻辑处理的,但和一般情况不同的是,我应用所在的底层系统是经过定制的,而在音频焦点的处理上,除了我上层应用会在蓝牙播放变化的时候请求焦点,底层的系统也会做同样的操作,这就造成了在两者来回请求的过程中,焦点丢失了。
这种问题还是比较少见的,所以记录一下,而最终的解决办法是让提供定制系统的硬件方解决。不过这里也记录一下对于音频焦点请求和监听的学习。
完整的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| public class MusicService extends Service { private AudioManager mAm; private boolean isPlaymusic; private String url; private MediaPlayer mediaPlayer; @Override public void onCreate() { super.onCreate(); mAm = (AudioManager) getSystemService(AUDIO_SERVICE); } @Override public void onStart(Intent intent, int startId) { if (intent != null) { Bundle bundle = intent.getExtras(); if (bundle != null) { isPlaymusic = bundle.getBoolean("isPlay", true); url = bundle.getString("url"); if (isPlaymusic) play(); else stop(); } } } OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { pause(); } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { resume(); } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { mAm.abandonAudioFocus(afChangeListener); stop(); } } }; private boolean requestFocus() { int result = mAm.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED; } private void resume() { if (mediaPlayer != null) { mediaPlayer.start(); } } private void pause() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); } } OnCompletionListener completionListener = new OnCompletionListener() { @Override public void onCompletion(MediaPlayer player) { if(!player.isLooping()){ mAm.abandonAudioFocus(afChangeListener); } } }; private void play() { if (requestFocus()) { if (mediaPlayer == null) { try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(url); mediaPlayer.prepare(); mediaPlayer.setOnCompletionListener(completionListener); } catch (IOException e) { e.printStackTrace(); } } if (!mediaPlayer.isPlaying()) { mediaPlayer.start(); } } } @Override public void onDestroy() { super.onDestroy(); if (mediaPlayer != null) mediaPlayer.release(); } private void stop() { if (mediaPlayer != null) { mediaPlayer.stop(); } } @Override public IBinder onBind(Intent arg0) { return null; } }
|
需要解释一下的是,在 onAudioFocusChange
方法里的返回值代表了当前焦点变化的状态
常量 |
说明 |
AUDIOFOCUS_GAIN |
持有焦点 |
AUDIOFOCUS_LOSS |
失去焦点 |
AUDIOFOCUS_LOSS_TRANSIENT |
临时失去焦点 |
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK |
临时失去焦点,允许小声播放 |