文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android蓝牙总结

2022-06-06 13:43

关注

因为之前有做与蓝牙有关的项目,所以这里写个博客总结一下。
附带了一个项目以供参考: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 gattServices) {
        for (BluetoothGattService gattService : gattServices) {
            List 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 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.连接多蓝牙设备
需区分设备

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


作者:键盘舞者113


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯