1. 程式人生 > >Android 藍芽(有線)耳機監聽的問題

Android 藍芽(有線)耳機監聽的問題

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