【问题标题】:how to switch audio output programatically in android 10?如何在android 10中以编程方式切换音频输出?
【发布时间】:2020-03-26 01:52:15
【问题描述】:

我的用例是我有一个应用程序,用户可以在其中按下按钮,它会在外部扬声器和有线耳机/蓝牙设备之间切换。如果用户连接到有线耳机或蓝牙耳机设备,我想将该有线耳机或蓝牙的音频输出切换到外部扬声器,然后当他们再次单击时,重新启用有线耳机/蓝牙音频输出.

有人知道这可以在 Android 10 中完成吗?我在post 中尝试了以下示例,但它并不始终适用于蓝牙案例。我的代码如下:

if (shouldEnableExternalSpeaker) {
     audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
     audioManager.isSpeakerphoneOn = true
     if (isBlueToothConnected) {
         audioManager.stopBluetoothScoOn()
     }
} else {
     if (isBlueToothConnected) {
         audioManager.startBluetoothSco()
     }

     audioManager.mode = AudioManager.NORMAL
     audioManager.isSpeakerphoneOn = false
}

我对用户的音频也有必要的权限:

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

【问题讨论】:

    标签: android bluetooth


    【解决方案1】:

    我认为你应该把你的处理分成 3 种情况,通过以下方式播放声音:

    1. 通过蓝牙连接的外部设备
    2. 有线耳机/设备
    3. 电话扬声器

    生成的代码可能会像这样。

    if(shouldEnableExternalSpeaker) {
        if(isBlueToothConnected) {
            // 1. case - bluetooth device
            mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            mAudioManager.startBluetoothSco();
            mAudioManager.setBluetoothScoOn(true);
        } else {
            // 2. case - wired device
            mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            mAudioManager.stopBluetoothSco();
            mAudioManager.setBluetoothScoOn(false);
            mAudioManager.setSpeakerphoneOn(false);
        }
    } else {
       // 3. case - phone speaker
       mAudioManager.setMode(AudioManager.MODE_NORMAL);
       mAudioManager.stopBluetoothSco();
       mAudioManager.setBluetoothScoOn(false);
       mAudioManager.setSpeakerphoneOn(true);
    }
    

    尽管我最近没有使用过AudioManager,但它在过去对我有用。

    【讨论】:

      【解决方案2】:

      行:

      audioManager.isSpeakerphoneOn = true
      audioManager.isSpeakerphoneOn = false
      

      不会工作。你必须使用 setMethods:

      案例 1 - 蓝牙

      mAudioManager.startBluetoothSco(); // This method can be used by applications wanting to send and received audio to/from a bluetooth SCO headset while the phone is not in call. 
      mAudioManager.setBluetoothScoOn(true); // set true to use bluetooth SCO for communications; false to not use bluetooth SCO for communications
      

      案例 2 - 有线

      mAudioManager.stopBluetoothSco(); // stop wanting to send and receive
      mAudioManager.setBluetoothScoOn(false); // turn off bluetooth
      mAudioManager.setSpeakerphoneOn(false); //set true to turn on speakerphone; false to turn it off
      

      案例 3 - 内置扬声器

      mAudioManager.stopBluetoothSco();
      mAudioManager.setBluetoothScoOn(false);
      mAudioManager.setSpeakerphoneOn(true); // turn on speaker phone
      

      您可以让事情自动发生,如下所示:

      public class BluetoothReceiver extends BroadcastReceiver {
          private AudioManager localAudioManager;
          private static final int STATE_DISCONNECTED  = 0x00000000;
          private static final String EXTRA_STATE = "android.bluetooth.headset.extra.STATE";
          private static final String TAG = "BluetoothReceiver";
          private static final String ACTION_BT_HEADSET_STATE_CHANGED  = "android.bluetooth.headset.action.STATE_CHANGED";
          private static final String ACTION_BT_HEADSET_FORCE_ON = "android.bluetooth.headset.action.FORCE_ON";
          private static final String ACTION_BT_HEADSET_FORCE_OFF = "android.bluetooth.headset.action.FORCE_OFF";
      
          @Override
          public void onReceive(final Context context, final Intent intent) {
              Log.i(TAG,"onReceive - BluetoothBroadcast");
              localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
              final String action = intent.getAction();
              if (action.equals(ACTION_BT_HEADSET_STATE_CHANGED)) {
                  final int extraData = intent.getIntExtra(EXTRA_STATE, STATE_DISCONNECTED);
                  if (extraData == STATE_DISCONNECTED) {
                      //no headset -> going other modes
                      localAudioManager.setBluetoothScoOn(false);
                      localAudioManager.stopBluetoothSco();
                      localAudioManager.setMode(AudioManager.MODE_NORMAL);
                      Log.i(TAG, "Bluetooth Headset Off " + localAudioManager.getMode());
                      Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
                  } else {            
                      localAudioManager.setMode(0);
                      localAudioManager.setBluetoothScoOn(true);
                      localAudioManager.startBluetoothSco();
                      localAudioManager.setMode(AudioManager.MODE_IN_CALL);
                      Log.i(TAG, "Bluetooth Headset On " + localAudioManager.getMode());
                      Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
                  }
              }   
      
              if (action.equals(ACTION_BT_HEADSET_FORCE_ON)) {
                  localAudioManager.setMode(0);
                  localAudioManager.setBluetoothScoOn(true);
                  localAudioManager.startBluetoothSco();
                  localAudioManager.setMode(AudioManager.MODE_IN_CALL);
                  Log.i(TAG, "Bluetooth Headset On " + localAudioManager.getMode());
                  Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
              }
      
              if (action.equals(ACTION_BT_HEADSET_FORCE_OFF)) {
                  localAudioManager.setBluetoothScoOn(false);
                  localAudioManager.stopBluetoothSco();
                  localAudioManager.setMode(AudioManager.MODE_NORMAL);
                  Log.i(TAG, "Bluetooth Headset Off " + localAudioManager.getMode());
                  Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-02
        • 1970-01-01
        • 2014-02-09
        • 1970-01-01
        • 2017-07-06
        相关资源
        最近更新 更多