天天看點

wangchenfeng android 監聽耳機插拔

private

class

NoisyAudioStreamReceiver

extends

BroadcastReceiver{

@Override

public

void

onReceive(Context context, Intent intent) {

if

(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {

int

state = intent.getIntExtra(

"state"

, -

1

);

switch

(state) {

case

:

//拔出耳機

videoView.pause();

Log.d(TAG,

"state:"

+state);

break

;

case

1

:

//插耳機自動播放

Log.d(TAG,

"state:"

+state);

videoView.start();

break

;

default

:

Log.d(TAG,

"未知狀态"

);

break

;

}

}

//隻監聽拔出耳機

if

(AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {

videoView.pause();

}

}

}

注冊廣播:

NoisyAudioStreamReceiver noisyAudioStreamReceiver =

new

NoisyAudioStreamReceiver();

IntentFilter filter =

new

IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);

filter.addAction(Intent.ACTION_HEADSET_PLUG);

registerReceiver(noisyAudioStreamReceiver, filter);

最近,項目了有這麼一個工作需求,當使用者正在使用我們産品裡提供的音樂播放器播放音樂時,使用者把耳機或者藍牙耳機接入後,過一會兒,使用者又把耳機給拔除,或者斷開藍牙耳機的連接配接,我們需要暫停播放音樂,

google, baidu了一下, 一般做法是:

定義一個BroadcastReceiver對象,  對于有線耳機,監聽Intent.ACTION_HEADSET_PLUG系統廣播,對于藍牙耳機,監聽BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED系統廣播

[java] view plain copy

  1. private void registerHeadsetPlugReceiver() {    
  2.         IntentFilter intentFilter = new IntentFilter();    
  3.         intentFilter.addAction("android.intent.action.HEADSET_PLUG");    
  4.         registerReceiver(headsetPlugReceiver, intentFilter);   
  5.         // for bluetooth headset connection receiver  
  6.         IntentFilter bluetoothFilter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);  
  7.         registerReceiver(headsetPlugReceiver, bluetoothFilter);  
  8.     }  
  9.     private BroadcastReceiver headsetPlugReceiver = new BroadcastReceiver() {  
  10.         @Override  
  11.         public void onReceive(Context context, Intent intent) {  
  12.             String action = intent.getAction();  
  13.             if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {  
  14.                 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();  
  15.                 if(BluetoothProfile.STATE_DISCONNECTED == adapter.getProfileConnectionState(BluetoothProfile.HEADSET)) {  
  16.                     //Bluetooth headset is now disconnected  
  17.                     handleHeadsetDisconnected();  
  18.                 }  
  19.             } else if ("android.intent.action.HEADSET_PLUG".equals(action)) {  
  20.                 if (intent.hasExtra("state")) {  
  21.                     if (intent.getIntExtra("state", 0) == 0) {  
  22.                         handleHeadsetDisconnected();  
  23.                     }  
  24.                 }  
  25.             }  
  26.         }  
  27.     };  

這樣做可以基本滿足需求,但是項目組長說,這樣做不完美,因為當拔出有線耳機時,播放器不會馬上暫停,要等上一秒鐘,才會收到Android的系統廣播, [java] view plain copy

  1. android.intent.action.HEADSET_PLUG,他說其他音樂播放器沒有這個延遲,經過調查發現,QQ音樂确實沒有這個延遲,耳機一拔,播放器立刻暫停,  

在網上找了一會兒,找到相關資料:從硬體層面來看,直接監聽耳機拔出事件不難,耳機的拔出和插入,會引起手機電平的變化,然後觸發什麼什麼中斷,

最終在stack overflow找到答案,監聽Android的系統廣播AudioManager.ACTION_AUDIO_BECOMING_NOISY, 但是這個廣播隻是針對有線耳機,或者無線耳機的手機斷開連接配接的事件,監聽不到有線耳機和藍牙耳機的接入,但對于我的需求來說足夠了,監聽這個廣播就沒有延遲了,UI可以立即響應

[java] view plain copy

  1. private void registerHeadsetPlugReceiver() {    
  2.         IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);    
  3.         registerReceiver(headsetPlugReceiver, intentFilter);   
  4.     }  
  5.     private BroadcastReceiver headsetPlugReceiver = new BroadcastReceiver() {  
  6.         @Override  
  7.         public void onReceive(Context context, Intent intent) {  
  8.             String action = intent.getAction();  
  9.             if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) {  
  10.                 handleHeadsetDisconnected();  
  11.             }  
  12.         }  
  13.     };