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中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Guide to BluetoothSecurity原文 本出版物可免费从以下网址获得:https://doi.o...
    公子小水阅读 8,263评论 0 6
  • 蓝牙 注:本文翻译自https://developer.android.com/guide/topics/conn...
    RxCode阅读 8,805评论 11 99
  • 公司的项目最近需要用到蓝牙开发的相关内容,因此特地查阅了Google官方文档的内容并进行二次整理,希望能对需要学习...
    Chuckiefan阅读 32,537评论 44 123
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,904评论 18 139
  • 前言 最近在做Android蓝牙这部分内容,所以查阅了很多相关资料,在此总结一下。 基本概念 Bluetooth是...
    猫疏阅读 14,731评论 7 113