Android蓝牙开发小结

因为之前有做与蓝牙有关的项目,所以这里写个博客总结一下。
附带了一个项目以供参考:https://github.com/979451341/BleStudy

一.蓝牙操作流程

1.获取蓝牙服务

        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = mBluetoothManager.getAdapter();
        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

2.开启蓝牙

mBluetoothAdapter.enable();

3.搜索蓝牙设备

    var mScanCallback = object :ScanCallback(){
        override fun onScanResult(callbackType: Int, result: ScanResult?) {
        }
    }
mBluetoothLeScanner.startScan(mScanCallback)

4.连接蓝牙设备

//首先获取设备
        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
//建立连接获取BluetoothGatt对象,并设置监听
        gatts = device.connectGatt(instance, false, mGattCallback);
        

首先说说BluetoothGatt对象,他是蓝牙通信的协议,连接蓝牙设备,发现服务,向蓝牙设备传数据和接收蓝牙设备的数据,都需经过他。
然后我们通过BluetoothGattCallback的,来监听这些过程。

    private static BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
            if (BluetoothGatt.GATT_SUCCESS == status) {
//开启监听成功,可以像设备写入命令了
            } 
        }

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
//连接成功
                Log.e(TAG, "设备连接上 开始扫描服务");
                    boolean discoverServices = gatt.discoverServices();
                    if (discoverServices) {
                    } 
            } 
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
            //发现服务
                String address = gatt.getDevice().getAddress();
                //绑定特征
                bindCharas(address, getSupportedGattServices(address));
            } 
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                //characteristic.getValue()为设备发送的数据,根据数据协议进行解析,对应onCharacteristicRead
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            //  characteristic.getValue()为设备发送的数据,根据数据协议进行解析,对应onCharacteristicChanged
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.e(TAG, "发送成功");
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
        }
    };

其中绑定特征需要详细说说,一个蓝牙设备有多个BluetoothGattService服务,一个服务有多个BluetoothGattCharacteristic特征,一个特征有多个BluetoothGattDescriptor描述。

其中我们是通过UUID来区别特征,这个由硬件工程师提供。

我们刚连接蓝牙,需要获取蓝牙设备传过来的数据。首先获取 read的特征,然后获取 通知描述,并给 mBluetoothGatt,使其知道我们需要接受通知

//获取服务
mBluetoothGatt.getServices()
//获取read特征
    private static void bindCharas(String address, List<BluetoothGattService> gattServices) {
        for (BluetoothGattService gattService : gattServices) {
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                String uuid_str = gattCharacteristic.getUuid().toString();
                if (uuid_str.equalsIgnoreCase(Constant.SMART_TAG_READ_UUID)) {
                    BluetoothGattCharacteristic mReadCharacteristic = gattCharacteristic;
                    setCharacteristicNotification(address, mReadCharacteristic, true);
                }
            }
        }
    }

5.手机传送命令
首先获取write特征

        for (BluetoothGattService gattService : mBluetoothGatt.getServices()) {
            uuid = gattService.getUuid().toString();
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            // Loops through available Characteristics.
            for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                uuid = gattCharacteristic.getUuid().toString();
                if (uuid.equalsIgnoreCase(Constant.SMART_TAG_WRITE_UUID)) {
                    return gattCharacteristic;
                }
            }
        }

然后给特征赋值,给gatt发出命令

            boolean write = characteristic.setValue(cmd);
            mBluetoothGatt.writeCharacteristic(characteristic);

6.断开蓝牙

在我们退出应用时,需断开连接

gatts.disconnect();
gatts.close();

二.蓝牙通信如何写入项目

1.蓝牙通信模块放哪
我们需要将蓝牙通信模块放在一个生命周期和应用相当的对象里,比如Application,不过这个类承担了很多sdk初始化的任务,所以我认为应该交给Service。

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(Intent(this, BleService::class.java))
        } else {
            startService(Intent(this, BleService::class.java))
        }

2.数据分发
在Service里初始化蓝牙服务,在BluetoothGattCallback里监听蓝牙连接的状况,并通过EventBus发送出去,也可以通过广播发送出去,我认为EventBus写的代码少一些好用一些。

3.蓝牙重连和心跳包
在service的onCeate函数里,使用Handler或TimerTask完成这个任务

4.使用FastBle框架
https://www.jianshu.com/p/795bb0a08beb

参考文献
https://juejin.im/post/599b8388f265da249600bbfd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值