當用戶正在使用我們產品里提供的音樂播放器播放音樂時,用戶把耳機或者藍牙耳機接入后,過一會兒,用戶又把耳機給拔除,或者斷開藍牙耳機的連接,我們需要暫停播放音樂,定義一個BroadcastReceiver對象, 對於有線耳機,監聽Intent.ACTION_HEADSET_PLUG系統廣播,對於藍牙耳機,監聽BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED系統廣播
private void registerHeadsetPlugReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.HEADSET_PLUG");
registerReceiver(headsetPlugReceiver, intentFilter);
// for bluetooth headset connection receiver
IntentFilter bluetoothFilter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
registerReceiver(headsetPlugReceiver, bluetoothFilter);
}
private BroadcastReceiver headsetPlugReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(BluetoothProfile.STATE_DISCONNECTED == adapter.getProfileConnectionState(BluetoothProfile.HEADSET)) {
//Bluetooth headset is now disconnected
handleHeadsetDisconnected();
}
} else if ("android.intent.action.HEADSET_PLUG".equals(action)) {
if (intent.hasExtra("state")) {
if (intent.getIntExtra("state", 0) == 0) {
handleHeadsetDisconnected();
}
}
}
}
};
這樣做可以基本滿足需求,但不完美,因為當拔出有線耳機時,播放器不會馬上暫停,要等上一秒鍾,才會收到Android的系統廣播,
android.intent.action.HEADSET_PLUG,他說其他音樂播放器沒有這個延遲,經過調查發現,QQ音樂確實沒有這個延遲,耳機一拔,播放器立刻暫停,
相關資料:從硬件層面來看,直接監聽耳機拔出事件不難,耳機的拔出和插入,會引起手機電平的變化,然后觸發什么什么中斷,
最終在stack overflow找到答案,監聽Android的系統廣播AudioManager.ACTION_AUDIO_BECOMING_NOISY, 但是這個廣播只是針對有線耳機,或者無線耳機的手機斷開連接的事件,監聽不到有線耳機和藍牙耳機的接入,但對於我的需求來說足夠了,監聽這個廣播就沒有延遲了,UI可以立即響應
private void registerHeadsetPlugReceiver() {
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
registerReceiver(headsetPlugReceiver, intentFilter);
}
private BroadcastReceiver headsetPlugReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) {
handleHeadsetDisconnected();
}
}
};
