更新记录

1.0.1(2024-10-28)

  1. 修复高版本HB回调一次问题

1.0.0(2024-08-16)

  1. 广播蓝牙数据,可以广播蓝牙名、serviceUuid、serviceDataUuid、serviceData、发射功率、厂家参数(ID和数据)、广播功率、是否可连接、持续时间
  2. 蓝牙数据通讯,增加删除service,characteristic读写

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.6.8,Android:4.4,iOS:9,HarmonyNext:不确定 × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

蓝牙外围设备从设备广播servicecharacteristic通讯

功能

  1. 广播蓝牙数据,可以广播蓝牙名、serviceUuid、serviceDataUuid、serviceData、发射功率、厂家参数(ID和数据)、广播功率、是否可连接、持续时间
  2. 蓝牙数据通讯,增加删除service,characteristic读写

蓝牙分为中心设备(Central、Master、主设备、客户端)和外围设备(Peripheral、Slave、从设备、服务端) 手机做为客户端可以连接多个蓝牙设备,所以手机又可以叫中心设备(Central),蓝牙设备叫外围设备(Peripheral)。 例如:通过手机蓝牙开启共享单车,手机称为中心设备,共享单车称为外围设备

本插件是外围设备(Peripheral、Slave、从设备、服务端)

中心设备蓝牙请使用插件https://ext.dcloud.net.cn/plugin?name=wrs-uts-bluetoothcenter

接口


import {
    UTSBluetoohSlave
} from "@/uni_modules/wrs-uts-bluetoothslave"
let slave = new UTSBluetoohSlave()
  • 设置回调

slave.setCallback((resp) => {
    this.showMsg(JSON.stringify(resp))
    let opt = resp.opt
    switch (opt) {
        // 广播开启成功
        case "onStartSuccess": {
            this.showMsg("广播成功")
            // 广播成功后添加service,添加了service这样客户端蓝牙才能连接通讯
            this.addService()
        }
        break;
        // 广播失败
        case "onStartFailure": {
            // 1: ADVERTISE_FAILED_DATA_TOO_LARGE
            // 2: ADVERTISE_FAILED_TOO_MANY_ADVERTISERS
            // 3: ADVERTISE_FAILED_ALREADY_STARTED
            // 4: ADVERTISE_FAILED_INTERNAL_ERROR
            // 5: ADVERTISE_FAILED_FEATURE_UNSUPPORTED
            // 18: 广播数据包太大,不同手机品牌支持的大小不一样
            // 如果有其他错误码,可以百度搜索"android AdvertiseCallback onStartFailure ${errorCode}"
            let errorCode = resp.errorCode
            this.showMsg("广播失败:" + JSON.stringify(resp))
        }
        break;
        // 蓝牙连接状态变化
        case "onConnectionStateChange": {
            var status = resp.status;
            var newState = resp
                .newState; // 0: STATE_DISCONNECTED 1: STATE_CONNECTING 2: STATE_CONNECTED 3: STATE_DISCONNECTING
            if (status == 0) { // 成功
                if (newState == 2) { // 连接成功
                    this.showMsg("收到新蓝牙连接成功 name:" + resp.device.name + " mac:" + resp.device
                        .address)
                } else if (newState == 0) { // 断开连接
                    this.showMsg("蓝牙断开连接")
                } else if (newState == 1) { // 连接中
                    this.showMsg("蓝牙连接中")
                } else if (newState == 3) { // 断开中
                    this.showMsg("蓝牙断开中")
                }
            } else { // 出错
                this.showMsg("蓝牙出错")
            }
        }
        break;
        case "onServiceAdded": {
            var status = resp.status;
            if (status == 0) { // 添加成功

            } else { // 添加失败

            }
        }
        break;
        // 收到客户端特征值读取请求
        case "onCharacteristicReadRequest": {
            this.showMsg("收到客户端特征值读取请求")
            let params = {}
            params.status = 0
            params.address = resp.device.address
            params.requestId = resp.requestId
            params.offset = resp.offset
            params.value = resp.characteristic.value
            let suc = slave.sendResponse(params)
            if (suc) {
                this.showMsg("发送响应数据成功:" + params.value)
            } else {
                this.showMsg("发送响应数据失败")
            }
        }
        break;
        // 收到客户端特征值写入数据,即:收到对方发来的蓝牙数据
        case "onCharacteristicWriteRequest": {
            this.showMsg("收到对方发来的蓝牙数据:" + JSON.stringify(resp))
            // {
            //  "characteristic": {
            //      "properties": 26,
            //      "value": [2, 6, -1],
            //      "uuid": "0000ff11-0000-1000-8000-00805f9b34fb",
            //      "permissions": 17,
            //      "writeType": 2,
            //      "instanceId": 43
            //  },
            //  "preparedWrite": false,
            //  "offset": 0,
            //  "device": {
            //      "bluetoothClass": {
            //          "majorDeviceClass": 0
            //      },
            //      "address": "46:82:6D:75:9A:EA",
            //      "type": 0,
            //      "bondState": 10
            //  },
            //  "requestId": 2,
            //  "value": [2],
            //  "responseNeeded": true,
            //  "opt": "onCharacteristicWriteRequest"
            // }
            // 
            let responseNeeded = resp.responseNeeded
            if (responseNeeded) {
                let params = {}
                params.address = resp.device.address
                params.requestId = resp.requestId
                params.status = 0 // 0: GATT_SUCCESS
                params.offset = resp.offset
                params.value = resp.value
                // 响应客户端,即:告诉对方蓝牙这边已经收到数据了
                let respSuc = slave.sendResponse(params)
                if (!respSuc) {
                    this.showMsg("sendResponse失败")
                } else {
                    this.showMsg("响应客户端:" + params.value)
                }
            }
            // 这里模拟数据处理业务,处理完成后发送处理结果给对方蓝牙,即:发数据客户端
            setTimeout(() => {
                let sendParams = {}
                sendParams.address = resp.device.address
                sendParams.serviceUuid = this.UUID_SERVICE
                sendParams.characteristicUuid = resp.characteristic.uuid
                sendParams.value = [0x01, 0x02, 0xFF]
                slave.sendData(sendParams)
                this.showMsg("发送数据给对方:"+ sendParams.value)
            }, 2000);
        }
        break;
        // 收到客户端描述读取请求,仅支持Android
        case "onDescriptorReadRequest": {
            this.showMsg("收到客户端描述读取请求")
            let params = {}
            params.address = resp.device.address
            params.requestId = resp.requestId
            params.offset = resp.offset
            params.status = 0
            params.value = resp.characteristic.value
            let suc = slave.sendResponse(params)
            if (suc) {
                this.showMsg("发送响应数据成功")
            } else {
                this.showMsg("发送响应数据失败")
            }
        }
        break;
        // 收到描述写入数据,仅支持Android
        case "onDescriptorWriteRequest": {
            this.showMsg("收到描述写入数据")
            let params = {}
            params.status = 0
            params.address = resp.device.address
            params.requestId = resp.requestId
            params.offset = resp.offset
            params.value = resp.characteristic.value
            let suc = slave.sendResponse(params)
            if (suc) {
                this.showMsg("发送响应数据成功")
            } else {
                this.showMsg("发送响应数据失败")
            }
        }
        break;
        // 仅支持Android
        case "onExecuteWrite": {

        }
        break;
        // 仅支持Android
        case "onNotificationSent": {

        }
        break;
        // 仅支持Android
        case "onMtuChanged": {

        }
        break;
        case "onPhyUpdate": {
            // 仅支持Android
        }
        break;
        // 仅支持Android
        case "onPhyRead": {

        }
        break;
        default:
            break;
    }
})
  • 初始化蓝牙

var params = {};
if(this.isAndroid) {

} else {
    params.CBCentralManagerOptionShowPowerAlertKey = true;
}
// 初始化
slave.initBluetooth(params);  
  • 广播蓝牙 android的蓝牙广播数据包大小不同机型大小不一样 广播结果在回调接口里slave.setCallback((resp) => {}) => onStartSuccess、onStartFailure

let params = {}
params.localName = this.name // 仅支持ios,ios需要将localName蓝牙名放到广播里,不然扫描不到蓝牙名
params.advertiseMode = 2
params.txPowerLevel = 3
params.connectable = true
params.advertiseData = {
    includeDeviceName: true, // 仅支持Android
    includeTxPowerLevel: true, // 仅支持Android
    serviceUuid: [this.UUID_SERVICE],
    manufacturerData: [{
        id: 1,
        data: [0x01, 0x22]
    }],
    serviceData:[ // 仅支持Android
        {
            uuid: this.UUID_SERVICE,
            data: [0x01, 0x22]
        },
        {
            uuid: this.UUID_SERVICE2,
            data: [0x01, 0x22]
        }
    ]
}
params.scanResponse = {
    includeDeviceName: true,
    includeTxPowerLevel: true,
    manufacturerData: [{
        id: 1,
        data: [0x01, 0x22]
    }]
}

slave.startAdvertising(params)
  • 停止广播

slave.stopAdvertising()

隐私、权限声明

1. 本插件需要申请的系统权限列表:

蓝牙、定位、读写

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问