1. 程式人生 > >Android: 如何切換 SCO 鏈路。

Android: 如何切換 SCO 鏈路。

最近在做藍芽音箱開發,在 A2DP 和 HFP 來回切換的時候,遇到了手機相容性的問題。最終發現裝置收聲和手機收聲,是因為 soc 切換有問題。原先在網上找了一些資料發現其實還蠻簡單的。就兩句話,當時沒想這麼多就直接寫了,發現還真能從裝置收聲,然後就沒管了。然後客戶反饋很多手機不能從裝置收聲,尤其是三星、華為最為嚴重。好吧,查了很多資料,同時跟嵌入式開發對程式碼。 SOC 都連線上了,還是不行。最終發現手機在切換的時候,需要設定 AudioManager 的模式:

  • MODE_NORMAL : 普通模式,既不是鈴聲模式也不是通話模式
  • MODE_RINGTONE : 鈴聲模式
  • MODE_IN_CALL
     : 通話模式
  • MODE_IN_COMMUNICATION : 通訊模式,包括音/視訊,VoIP通話.(3.0加入的,與通話模式類似)

1、開啟 SCO 錄音

public void startSCO() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mAudioManager.setMode(AudioManager.MODE_IN_CALL);
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mAudioManager.setMode(AudioManager.MODE_IN_CALL);
        }
        if (mAudioManager.isBluetoothScoOn()) {
            if (mAliRecorderManager != null) {
                if (!isStartRecord){
                    mAliRecorderManager.startTalk();
                }
            }
            return;
        }
        try {
            mAudioManager.setBluetoothScoOn(true);
            mAudioManager.startBluetoothSco();
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
                if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
                    if (mAliRecorderManager != null) {
                        if (!isStartRecord){
                            mAliRecorderManager.startTalk();
                        }
                    }
                    ca.unregisterReceiver(this);
                }
            }
        };
        ca.registerReceiver(receiver, intentFilter);
    }

2、關閉 SOC 錄音

public void stopSCO() {
        mAudioManager.setMode(AudioManager.MODE_NORMAL);
        if (mAudioManager.isBluetoothScoOn()) {
            mAudioManager.setBluetoothScoOn(false);
            mAudioManager.stopBluetoothSco();
        }
    }