• FastBle辅助蓝牙app开发


    摘要

    最近项目有个带蓝牙得体温计,然后厂家没有对应的android BT的SDK,所以对于安卓端蓝牙数据交互无从下手,不过有论坛大佬推荐FastBle,可以从中拿到想要的的uuid、mac等信息。

    1、FastBle VS 原生Android蓝牙API

    原生Android的蓝牙API使用有点麻烦,要先获取设备的蓝牙适配器,接着注册广播来接受蓝牙设备信息,用完了还需要将广播给注销,相对来说有点麻烦。

    不好封装,可以说是原生Android最让人痛苦的地方,这是因为原生Android的代码不是很独立,与Activity、广播等相杂糅。市面上的蓝牙库也是少之又少,先看了看BleLib,感觉还是换汤不换药,用起来一点也不简洁。

    但是FastLib封装的就很技巧,基本上能把一个操作的粒度控制在一行内,另外,代码也无需与线程、通知之类的打交道,库中已经帮我们把这些复杂的东西都做完了。

    FastBle的Github项目地址在这,大家可以看看:[FastBle - GitHub]

    1.FastBle的使用

    a、申明权限

    只要使用到了蓝牙,申明权限是必不可少的,FastBle需要的权限如下:

    1. <uses-permission android:name="android.permission.BLUETOOTH" />
    2. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    3. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    4. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    这里要注意一点,如果Android版本高于6.0,用户还需要打开位置信息(不光要位置权限,还需要打开位置信息)才能通过蓝牙进行扫描。

    b、初始化与全局配置

    初始化需要在库中任何函数被调用前执行,由于库使用的是单例模式,只需要初始化一次,在哪里都能使用,建议在onCreate里执行初始化代码:

    BleManager.getInstance().init(getApplication());

    全局配置可以紧跟初始化之后执行,当然如果不进行配置也没有任何关系,每一个选项都有默认值:

    1. BleManager.getInstance()
    2. .enableLog(true)
    3. .setReConnectCount(1, 5000)
    4. .setSplitWriteNum(20)
    5. .setConnectOverTime(10000)
    6. .setOperateTimeout(5000);

    每一项的详细信息你都能在官方文档中找到说明

    c、打开蓝牙

    使用FastBle中的BleManager类有很多种方式来打开蓝牙,这里推荐使用下面这种方式,这种方式会使线程被阻塞,如果用户不选择是否打开蓝牙,线程将会暂停执行:

    BleManager.getInstance().enableBluetooth();

    d、扫描设备

    打开蓝牙之后即可扫描设备,在正式扫描之前,可以自定义扫描规则,像这样:

    1. BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
    2. .setServiceUuids(serviceUuids) // 只扫描指定的服务的设备,可选
    3. .setDeviceName(true, names) // 只扫描指定广播名的设备,可选
    4. .setDeviceMac(mac) // 只扫描指定mac的设备,可选
    5. .setAutoConnect(isAutoConnect) // 连接时的autoConnect参数,可选,默认false
    6. .setScanTimeOut(10000) // 扫描超时时间,可选,默认10秒;小于等于0表示不限制扫描时间
    7. .build();
    8. BleManager.getInstance().initScanRule(scanRuleConfig);

    在设置规则后,即可开始扫描,像这样

    1. BleManager.getInstance().scan(new BleScanCallBack() {
    2. @Override
    3. public void onScanStarted(boolean success) {
    4. // 开始扫描的回调
    5. }
    6. @Override
    7. public void onScanning(BleDevice bleDevice) {
    8. // 扫描到一个之前没有扫到过的设备的回调
    9. }
    10. @Override
    11. public void onScanFinished(List scanResultList) {
    12. // 扫描完成的回调,列表里将不会有重复的设备
    13. }
    14. });

    这几个回调都是安全的,将会自动返回主线程,所以可以放心使用。

    当然,在任何地方,任何时候,你都可以直接使用取消扫描这个函数来停止扫描:

    BleManager.getInstance().cancelScan();

    我要做的是过滤周围不需要的蓝牙设备,所以做了双重过滤,第一是过滤names,第二是根据mac直接刷选出来。

    e、连接设备

    在扫描之后,你已经获取到了一个或多个BleDevice对象,你可以直接使用这些对象向目标设备发起连接,像这样:

    1. BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
    2. @Override
    3. public void onStartConnect() {
    4. // 开始连接
    5. }
    6. @Override
    7. public void onConnectFail(BleDevice bleDevice, BleException exception) {
    8. // 连接失败
    9. }
    10. @Override
    11. public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
    12. // 连接成功,BleDevice即为所连接的BLE设备
    13. }
    14. @Override
    15. public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
    16. // 连接中断,isActiveDisConnected表示是否是主动调用了断开连接方法
    17. }
    18. });

    f、设备信息

    扫描得到的BLE外围设备,会以BleDevice对象的形式,作为后续操作的最小单元对象。它本身含有这些信息:

    1. String getName():蓝牙广播名
    2. String getMac():蓝牙Mac地址
    3. byte[] getScanRecord(): 被扫描到时候携带的广播数据
    4. int getRssi() :被扫描到时候的信号强度

    后续进行设备连接、断开、判断设备状态,读写操作等时候,都会用到这个对象。可以把它理解为外围蓝牙设备的载体,所有对外围蓝牙设备的操作,都通过这个对象来传导。

    g、连接、断连、监控连接状态

    拿到设备对象之后,可以进行连接操作。

    1.     BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
    2.         @Override
    3.         public void onStartConnect() {
    4.         }
    5.  
    6.         @Override
    7.         public void onConnectFail(BleException exception) {
    8.         }
    9.  
    10.         @Override
    11.         public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
    12.         }
    13.  
    14.         @Override
    15.         public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
    16.         }
    17.     });

    onStartConnect():开始进行连接。
    onConnectFail(BleException exception):连接不成功。
    onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status):连接成功并发现服务。
    onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status):连接断开,特指连接后再断开的情况。

    在这里可以监控设备的连接状态,一旦连接断开,可以根据自身情况考虑对BleDevice对象进行重连操作。需要注意的是,断开和重连之间最好间隔一段时间,否则可能会出现长时间连接不上的情况。此外,如果通过调用disconnect(BleDevice bleDevice)方法,主动断开蓝牙连接的结果也会在这个方法中回调,此时isActiveDisConnected将会是true。

    2、结果

    1.开始扫描(未对names和mac过滤)

    2.点“特征(1)”,可以获取log打印的uuid

     3.任意点哪个服务

     

    4.可以接收到设备端(体温计)发来的数据,数据换算就自己琢磨吧,超简单的

     

     

  • 相关阅读:
    Unity2D - 状态机(State Machine)详解
    Spring Boot 实现通用 Auth 认证的 4 种方式
    【翻译工具】如何复活谷歌翻译之二
    Qt控件按钮大全
    论文笔记--Baichuan 2: Open Large-scale Language Models
    Spring事务传播之嵌套调用
    Mysql数据类型
    c语言指针(深入了解指针)
    短视频引爆销售:TikTok如何改变跨境电商游戏规则
    【程序员装机】自定义Edge浏览器用户目录
  • 原文地址:https://blog.csdn.net/qq_18235445/article/details/126267096