Android蓝牙协议-蓝牙配对与连接

蓝牙设备在连接前,会先检查设备是否已经配对过,如果没有则先配对,配对完成后,再开始连接。

onPreferenceTreeClick

蓝牙连接开始于设备列表 DeviceListPreferenceFragment的onPreferenceTreeClick方法。
DeviceListPreferenceFragment是蓝牙设备列表,点击其中一个蓝牙设备,开始蓝牙的连接过程。

    @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
            Preference preference) {
        if (KEY_BT_SCAN.equals(preference.getKey())) {
            mLocalAdapter.startScanning(true);
            return true;
        }

        if (preference instanceof BluetoothDevicePreference) {
            BluetoothDevicePreference btPreference = (BluetoothDevicePreference) preference;
            CachedBluetoothDevice device = btPreference.getCachedDevice();
            mSelectedDevice = device.getDevice();
            //配对连接
            onDevicePreferenceClick(btPreference);
            return true;
        }

        return super.onPreferenceTreeClick(preferenceScreen, preference);
    }

调用onDevicePreferenceClick方法,接着调用BluetoothDevicePreference的onClicked方法,开始连接,以及连接前的状态检测。

BluetoothDevicePreference.onClicked

    void onClicked() {
        //选中设备的绑定状态
        int bondState = mCachedDevice.getBondState();
        //已连接,询问是否连接
        if (mCachedDevice.isConnected()) {
            askDisconnect();
        } else if (bondState == BluetoothDevice.BOND_BONDED) {
            mCachedDevice.connect(true);
        } else if (bondState == BluetoothDevice.BOND_NONE) {
            //配对
            pair();
        }
    }

获取mCachedDevice的绑定状态,

  • 已经连接,是否断开
  • 未连接,已经绑定,开始连接
  • 未连接,未绑定,开始配对

开始蓝牙配对流程

CachedBluetoothDevice.startPairing

pair方法会调用CachedBluetoothDevice.startPairing,启动配对

    public boolean startPairing() {
        // Pairing is unreliable while scanning, so cancel discovery
        //配对时,取消搜索
        if (mLocalAdapter.isDiscovering()) {
            mLocalAdapter.cancelDiscovery();
        }
        //开始配对配对
        if (!mDevice.createBond()) {
            return false;
        }
        //标识位,配对完成后,自动连接
        mConnectAfterPairing = true;  // auto-connect after pairing
        return true;
    }

createBond调用BluetoothDevice.createBond方法,BluetoothDevice.createBond接着调用IBluetooth.createBond方法,下面会调用蓝牙远程服务。
和蓝牙扫描一样,实现IBluetooth接口的类是AdapterServiceBinder,

AdapterServiceBinder extends IBluetooth.Stub

AdapterServiceBinder实现IBluetooth.Stub接口,并且是AdapterService的私有内部类,AdapterServiceBinder接受事件,都会转交AdapterService处理,所以IBluetooth.createBond方法会调用AdapterService.createBond方法。

AdapterService.createBond

     boolean createBond(BluetoothDevice device, int transport) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
            "Need BLUETOOTH ADMIN permission");
        DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
         //属性检查
        if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
            return false;
        }

        // Pairing is unreliable while scanning, so cancel discovery
        // Note, remove this when native stack improves
         //再次取消扫描
        cancelDiscoveryNative();
        //将配对任务转交状态机处理
        Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
        msg.obj = device;
        msg.arg1 = transport;
        mBondStateMachine.sendMessage(msg);
        return true;
    }

createBond方法会检查一下远程设备属性信息,再次取消蓝牙扫描任务,将配对任务转交mBondStateMachine,由状态机处理该信息。
BondStateMachine状态机的初始状态是StableState,所以BondStateMachine.CREATE_BOND由StableState处理,StableState在processMessage中调用BondStateMachine.createBond方法

BondStateMachine.createBond

    private boolean createBond(BluetoothDevice dev, int transport, boolean transition) {
        if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
            infoLog("Bond address is:" + dev);
            byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
            //调用createBondNative JNI方法
            if (!mAdapterService.createBondNative(addr, transport)) {
                //发送正在绑定的广播
                sendIntent(dev, BluetoothDevice.BOND_NONE,
                           BluetoothDevice.UNBOND_REASON_REMOVED);
                return false;
            } else if (transition) {
                transitionTo(mPendingCommandState);
            }
            return true;
        }
        return false;
    }

JNI 方法

createBondNative方法实现com_android_bluetooth_btservice_AdapterService.cpp中

    原文作者:stdying
    原文地址: https://www.jianshu.com/p/245ffac83d94
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞