android 连接多蓝牙,蓝牙断开自动切换到其他蓝牙连接

文章描述了如何在Android框架层的Bluetooth服务中,通过修改ActiveDeviceManager类的AudioDeviceCallback来实现在蓝牙耳机或音箱断开连接后,自动切换到其他蓝牙设备的功能。主要涉及对AudioDeviceInfo的监控,以及在特定条件下调用BluetoothInCallService进行音频路由切换。
摘要由CSDN通过智能技术生成

近期接到一个要求,在手及连接到多个蓝牙设备时(如蓝牙耳机、蓝牙音箱等),其中一个断开后,能够自动切换掉另外一个蓝牙设备的连接。

此方案为framwork层的修改。

/packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java

中有一个监听蓝牙设备断开和连接的方法。

 private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback {
361          private boolean isWiredAudioHeadset(AudioDeviceInfo deviceInfo) {
362              switch (deviceInfo.getType()) {
363                  case AudioDeviceInfo.TYPE_WIRED_HEADSET:
364                  case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
365                  case AudioDeviceInfo.TYPE_USB_HEADSET:
366                      return true;
367                  default:
368                      break;
369              }
370              return false;
371          }
372  
373          @Override
374          public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
375              if (DBG) {
376                  Log.d(TAG, "onAudioDevicesAdded");
377              }
378              boolean hasAddedWiredDevice = false;
379              for (AudioDeviceInfo deviceInfo : addedDevices) {
380                  if (DBG) {
381                      Log.d(TAG, "Audio device added: " + deviceInfo.getProductName() + " type: "
382                              + deviceInfo.getType());
383                  }
384                  if (isWiredAudioHeadset(deviceInfo)) {
385                      hasAddedWiredDevice = true;
386                      break;
387                  }
388              }
389              if (hasAddedWiredDevice) {
390                  wiredAudioDeviceConnected();
391              }
392          }
393  
394          @Override
395          public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
396          }
397      }

所以我们就可以在监听蓝牙断开的地方添加我们想要进行的操作。

@Override
        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {

            // No need to switch when setting Bluetooth devices to inactive state
            for (BluetoothDevice mA2dpConnectedDevice : mA2dpConnectedDevices) {
                if (mA2dpConnectedDevice.getAddress().equals(removedDevices[0].getAddress())) return;
            }

            // removedDevices 为被移除的蓝牙数组
            // 判断手机是否还存在其他的蓝牙连接,以及是否插入耳机,因为耳机的优先级较高,插入耳机时保持默认行为即可。
            if (mA2dpConnectedDevices.size() != 0  && !(mAudioManager.isWiredHeadsetOn())) {
                // 判断是否在通话模式,因为在通话时蓝牙通路的切换方法有所不同,
                // 在通话时应由通话服务去切换(试过setA2dpActiveDevice在通话时不起作用)
                // 非通话时主要由AudioManager去管理 ,通话时由CallAudioManager管理。
                if (mAudioManager.getMode() == AudioManager.MODE_IN_CALL)  {

                // BluetoothInCallService继承的InCallServices,调用父类的方法,
                //也就是requestBluetoothAudio()  方法,切换蓝牙通路。这里最终会调用到CallAudioManager.setAudioRoute()里面
                 BluetoothInCallService.getInstance().requestBluetoothAudio(mA2dpConnectedDevices.get(0));
                }else {
                // 此方法用于一般情况下将已连接的蓝牙变为活动状态。此方法就在这个类定义的
                // ,可以自己研究具体的流程。mA2dpConnectedDevices为已连接设备的集合。
                    setA2dpActiveDevice(mA2dpConnectedDevices.get(0));
                }
            }
        }

如果想要去切换扬声器,或者听筒也是可以的。可以调用

BluetoothInCallService.getInstance().setAudioRoute(int route)

BluetoothInCallService.getInstance().setAudioRoute(CallAudioState.ROUTE_SPEAKER);

BluetoothInCallService.getInstance().setAudioRoute(CallAudioState.ROUTE_EARPIECE);

    /** Direct the audio stream through the device's earpiece. */
    public static final int ROUTE_EARPIECE      = 0x00000001;

    /** Direct the audio stream through Bluetooth. */
    public static final int ROUTE_BLUETOOTH     = 0x00000002;

    /** Direct the audio stream through a wired headset. */
    public static final int ROUTE_WIRED_HEADSET = 0x00000004;

    /** Direct the audio stream through the device's speakerphone. */
    public static final int ROUTE_SPEAKER       = 0x00000008;

    /**
     * Direct the audio stream through the device's earpiece or wired headset if one is
     * connected.
     */
    public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET;

    /**
     * Bit mask of all possible audio routes.
     *
     * @hide
     **/
    public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
            ROUTE_SPEAKER;

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值