Android 藍芽(有線)耳機監聽的問題
阿新 • • 發佈:2019-01-31
MediaButtonReceive只是作為一種通俗的命名方式來響應插入耳機後,點選耳機上的按鍵(MEDIA_BUTTON)接受該廣播事件類。
點選MEDIA_BUTTON傳送的Intent Action 為 ACTION_MEDIA_BUTTON="android.intent.action.MEDIA_BUTTON”
Intent 附加值為(Extra)點選MEDIA_BUTTON的按鍵碼 :
//獲得KeyEvent物件
KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT );
//獲得Action
String intentAction = intent.getAction() ;
直接上程式碼
public class BlueToothIntercom { public static final int START_SPEAK = 0x1; public static final int STOP_SPEAK = 0x2; /** * Local Bluetooth adapter */ private BluetoothAdapter mBluetoothAdapter= null; private final String TAG = "BlueToothIntercom"; private AudioManager mAudioManager = null; private Handler callbackHandler; private Context context; private static Object lockObject = new Object(); public int scoState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; //Sco狀態public boolean isPTTDown; //PTT鍵是否是按下狀態 private BroadcastReceiver blueToothScoBroadcast; private static BlueToothIntercom thisObject; private BlueToothIntercom() { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } public static BlueToothIntercom getInstance() { if (null == thisObject) { synchronized (lockObject) { if (null == thisObject) { thisObject = new BlueToothIntercom(); } } } return thisObject; } public void start(Context context, Handler handler) { this.callbackHandler = handler; this.context = context; if (null == mAudioManager) { mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); } if (null == blueToothScoBroadcast) { blueToothScoBroadcast = new BlueToothBroadcast(); IntentFilter filter = new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED); filter.addCategory(VENDOR_CATEGORY); filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);//另一款裝置的監聽(手咪) context.registerReceiver(blueToothScoBroadcast, filter); } open(context); } public void stop() { if (null != blueToothScoBroadcast) { context.unregisterReceiver(blueToothScoBroadcast); blueToothScoBroadcast = null; } close(context); } public boolean isPTTDown() { return isPTTDown; } public void startSco(int delay) { if (!mAudioManager.isBluetoothScoAvailableOffCall()) { Toast.makeText(context.getApplicationContext(), R.string.bluetooth_not_have, Toast.LENGTH_SHORT).show(); LogUtil.i(TAG, "系統不支援藍芽錄音"); return; } Handler handler = new Handler(context.getMainLooper()); handler.postDelayed(new Runnable(){ @Override public void run() { if (isPTTDown && !mAudioManager.isBluetoothScoOn() && AudioManager.SCO_AUDIO_STATE_CONNECTING != scoState) { // mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); scoState = AudioManager.SCO_AUDIO_STATE_CONNECTING; mAudioManager.startBluetoothSco();//藍芽錄音的關鍵,啟動SCO連線,耳機話筒才起作用 mAudioManager.setBluetoothScoOn(true); } else if (mAudioManager.isBluetoothScoOn()) { // mAudioManager.setMode(AudioManager.MODE_NORMAL); mAudioManager.setBluetoothScoOn(false); mAudioManager.stopBluetoothSco(); } } }, delay); } public void stopSco() { // mAudioManager.setMode(AudioManager.MODE_NORMAL); mAudioManager.stopBluetoothSco(); } public void startSpeak() { isPTTDown = true; callbackHandler.sendEmptyMessage(START_SPEAK); } public void stopSpeak() { isPTTDown = false; callbackHandler.sendEmptyMessage(STOP_SPEAK); } //註冊耳機監聽 public void open(Context context){ if(Device.getInstance().getBulueSelect()!=0){ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); ComponentName name = new ComponentName(context.getPackageName(), BlueToothBroadcast.class.getName()); //Intent intent=new Intent(context, BlueToothBroadcast.class); audioManager.registerMediaButtonEventReceiver(name); } } /** * 關閉耳機線控監聽 * @param context */ public void close(Context context){ if(Device.getInstance().getBulueSelect()!=0){ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); ComponentName name = new ComponentName(context.getPackageName(), BlueToothBroadcast.class.getName()); audioManager.unregisterMediaButtonEventReceiver(name); } } }
public class BlueToothBroadcast extends BroadcastReceiver { Timer timer = null; private static boolean isTimerStart = false; private static MyTimer myTimer = null; BlueToothBroadcast blueToothBroadcast; private OnBlueSetListener nnn = null; public BlueToothBroadcast() { timer = new Timer(true); } public void setOnHeadSetListener(OnBlueSetListener headSetListener){ this.nnn = headSetListener; } public interface OnBlueSetListener{ public void gogo(); } @Override public void onReceive(Context context, Intent intent) { // TODO: This method is called when the BroadcastReceiver is receiving // an Intent broadcast. if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(intent.getAction())) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1); BlueToothIntercom.getInstance().scoState = state; if(state==0&&BlueToothIntercom.getInstance().isPTTDown()){ BlueToothIntercom.getInstance().stopSpeak(); } } if (BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT.equals(intent.getAction())) { if(Device.getInstance().isbulueHands()){ Bundle eventExtra = intent.getExtras(); // get the arguments that the headset passed out Object[] args = (Object[]) eventExtra.get(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS); String eventName = (String) args[0]; if (eventName.equals(TALK_STRING)) { Integer eventValue = (Integer) args[1]; if (eventValue == 1) { BlueToothIntercom.getInstance().startSpeak(); } else if (eventValue == 0) { BlueToothIntercom.getInstance().stopSpeak(); } } } } if(Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())){ if(Device.getInstance().getBulueSelect()!=0){ //獲得KeyEvent物件 KeyEvent keyEvent = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); try { if(keyEvent.getAction() == KeyEvent.ACTION_UP){ if(isTimerStart){ myTimer.cancel(); isTimerStart = false; }else{ myTimer = new MyTimer(); timer.schedule(myTimer,1000); isTimerStart = true; } } } catch (Exception e) { } //終止廣播(不讓別的程式收到此廣播,免受干擾) abortBroadcast(); } } } /* * 定時器,用於延遲1秒,內若無操作則為單擊 */ class MyTimer extends TimerTask { @Override public void run() { try { myHandle.sendEmptyMessage(0); } catch (Exception e) { // TODO: handle exception } } }; /* * 此handle的目的主要是為了將介面在主執行緒中觸發 * ,為了安全起見把介面放到主執行緒觸發 */ Handler myHandle = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); BlueToothIntercom.getInstance().startSpeak(); isTimerStart = false; } }; } 注意我遇到的問題來了: 當按下耳機後傳送 MEDIA_BUTTON ,開始獲取
mAudioManager.startBluetoothSco();//藍芽錄音的關鍵,啟動SCO連線,耳機話筒才起作用 開始錄音,當在點選一下準備結束錄音的時候卻監聽不到 MEDIA_BUTTON 按鍵了,監聽到的是
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED ,因為當啟動
scoState = AudioManager.SCO_AUDIO_STATE_CONNECTING的值改變了所以會監聽
ACTION_SCO_AUDIO_STATE_UPDATED
順便加個別人的連結 http://blog.csdn.net/qinjuning/article/details/6938436