更新记录

1.0.2(2023-07-14)

1、修复部分Android12搜不到蓝牙

1.0.0(2023-06-12)

初始版


平台兼容性

Android Android CPU类型 iOS
适用版本区间:5.0 - 12.0 armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 适用版本区间:11 - 16

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


特别提醒

  • 购买本插件前,请先试用,并充分自测确认满足需求之后再行购买。虚拟物品一旦购买之后无法退款;
  • 如有使用上的疑问、bug,可以在QQ群(345533496)反馈;
  • 请在合法范围内使用,若使用本插件做非法开发,本方概不负责;
  • iOS示例demo打包运行时可能因为名称太长,无法启动请先前往manifest-->基础设置中修改应用名称

插件使用文档

一.引入插件

const bluetooth = uni.requireNativePlugin('LY-Bluetooth');

二.使用

  • 初始化
//isPrimitive=false回调数据转成保留2位小数数据(针对电子秤),isPrimitive=true蓝牙返回的原始数据流
bluetooth.initBluetooth({isPrimitive:false})
  • 扫描蓝牙
bluetooth.discoveryBluetooth((res) => {//多次回调,可添加到数组展示蓝牙列表
<!--res的数据:{"status":5,"data":{
    "name": "EDIFIER TWS1 Pro",//蓝牙名称
    "blueType": 3,//蓝牙类型----1、经典蓝牙 2、BLE 3、DUAL
    "address": "FC:E8:06:03:93:96",//外设mac(iOS是UUID)
    "rssi": -94//信号量
}}-->
    if (res.status == 5) {
        this.bluetoothList = this.bluetoothList.concat(res.data)
    }
});
  • 连接蓝牙分经典蓝牙(iOS不支持)和BLE蓝牙
res.status 说明 res.data
0 没有配对蓝牙
1 读取数据 res.data(返回电子秤数据,已保留两位小数)
2 蓝牙连接成功
3 蓝牙已断开
7 连接失败
  • 1、经典蓝牙(未配对弹配对框待配对成功连接蓝牙,已配对直接连接)
bluetooth.connectBlutoothWithName({
    blutoothName: bluetoothName,//蓝牙名称
    peripheralUUID:peripheralUUID//蓝牙macddress
}, (res) => {
    switch (parseInt(res.status)) {
        case 0: {
            uni.showToast({
                title: '请先配对电子秤',
                icon: 'error'
            })
        }
        break;
        case 1: {//读取数据
            this.weight = res.data;
        }
        break;
        case 2: {
            uni.showToast({
                title: '蓝牙连接成功',
                icon: 'success'
            })
        }
        break;
        case 3: {
            uni.showToast({
                title: '蓝牙已断开',
                icon: 'error'
            })
        }
        break;
        default:
        break;
    }
})
经典蓝牙参数说明 说明 补充
blutoothName 蓝牙名称 先搜索周边蓝牙找到该名称的蓝牙连接
peripheralUUID 蓝牙macAddress 不搜索直接根据mac连接
  • 2、BLE(BLE连接)
bluetooth.connectBlutoothWithName({
    blutoothName: bluetoothName,//蓝牙名称
    peripheralUUID:peripheralUUID,//蓝牙macaddress
    notifyServiceIDs: 'FFB0', //notify对应服务ID
    notifyCharacteristicIDs: 'FFB2', //notify特征ID
}, (res) => {
    switch (parseInt(res.status)) {
        case 0: {
            uni.showToast({
                title: '请先配对电子秤',
                icon: 'error'
            })
        }
        break;
        case 1: {//读取数据
            this.weight = res.data;
        }
        break;
        case 2: {
            uni.showToast({
                title: '蓝牙连接成功',
                icon: 'success'
            })
        }
        break;
        case 3: {
            uni.showToast({
                title: '蓝牙已断开',
                icon: 'error'
            })
        }
        break;
        default:
        break;
    }
})

// "0000xxxx-0000-1000-8000-00805f9b34fb"下面的服务ID和特征ID取xxxx部分一般是4位(为适配iOS字母大写)

BLE蓝牙参数说明 说明 补充
blutoothName 蓝牙名称 先搜索周边蓝牙找到该名称的蓝牙连接
peripheralUUID 外设唯一标识(iOS:UUID ,Android:mac) 不搜索直接根据mac连接
serviceIDs 服务ID 字母大写
characteristicIDs 特征ID 字母大写(特征ID必须是上面服务中的特征ID)
  • 向蓝牙发送数据
bluetooth.sendDataToBluetooth({
    serviceID: 'FFB0',
    characteristicID: 'FFB1',
    data: '86',//发送数据
    charserType:"HEX",//用于设置编码HEX:16进制字符串、GBK:GBK字符串、UTF-8
    writeResponse: false //写入数据是否有响应 默认false
}, (res) => { //写入回调
    if (res.status == 200) { //写入成功

    } else if (res.status == 401) { //蓝牙未连接

    } else if (res.status == 402) { //服务ID为空

    } else if (res.status == 403) { //特征ID为空

    } else if (res.status == 404) { //写入数据为空

    } else if (res.status == 405) { //不支持响应Write

    } else if (res.status == 406) { //不支持noResponseWrite

    }
    uni.showToast({
        title: res.msg,
        icon: 'none',
        duration: 1500
    })

});
发送数据参数说明 说明 补充
charserType 设置发送编码格式 HEX:16进制字符串、GBK:GBK字符串、UTF-8
data 数据
serviceID 服务ID 字母大写
characteristicID 特征ID 字母大写(特征ID必须是上面服务中的特征ID)
writeResponse 写入成功是否有响应 默认false
  • 读取蓝牙数据(经典蓝牙无效)
bluetooth.readDataToBluetooth({
    serviceID: 'FFB0',
    characteristicID: 'FFB1'
}, res => {
    if (res.code == 200) {
        console.log("读取数据:" + res.data)
    }else{
        uni.showToast({
            title:res.msg,
            icon:'none',
            duration:1500
        })
    }
})
读取数据参数说明 说明 补充
serviceID 服务ID 字母大写
characteristicID 特征ID 字母大写(特征ID必须是上面服务中的特征ID)
  • 断开蓝牙
bluetooth.disconnectBluetooth();
  • 获取蓝牙所拥有的服务与特征(iOS与Android返回的数据有所不同)

iOS返回的服务与特征ID为:FFB1

Android返回的则为:"0000ffb1-0000-1000-8000-00805f9b34fb"

bluetooth.getBluetoothServiceAndCharacter((res)=>{
    if(res.status == 200){
      console.log(res.data);
    }
})
  • 完整示例
<template>
    <view style="display: flex;flex-direction: column;width: 750rpx;">
        <view class="header">
            <text style="margin-bottom: 40rpx;">{{weight}}kg</text>
            <text style="margin-bottom: 40rpx;">{{weight2}}</text>
            <view class="btn_view">
                <view class="btn" style="margin-right: 20rpx;" @click="connectBluetooth('BT04-A','')">
                    连接指定蓝牙
                </view>
                <view class="btn" style="margin-right: 20rpx;" @click="discovery">
                    获取蓝牙列表
                </view>
                <view class="btn" style="margin-right: 20rpx;" @click="disconnect">
                    断开蓝牙
                </view>
                <view class="btn" @click="sendData">
                    发送数据
                </view>
            </view>
            <view class="btn" style="margin-top: 10rpx;" @click="getServiceCharacter()">获取服务与特征</view>
        </view>
        <view class="list">
            <view class="cell" v-for="(item,index) in bluetoothList" :key="'bluetooth'+index"
                @click.stop="connectBluetooth(item.name,item.address)">
                <text style="color:blueviolet;">名称:{{item.name}}</text>
                <text style="color:blueviolet;">信号强度:{{item.rssi}}</text>
                <text
                    style="color:blueviolet;">蓝牙类型:{{item.blueType==1?'BT':(item.blueType == 2?'BLE':(item.blueType== 3?'DUAL':'UNKNOWN'))}}</text>
                <text style="color: blue;">地址:{{item.address}}</text>
                <view class="line" style="width: 750rpx;height: 1px;background-color: rgba(0, 0, 0, 0.4);"></view>
            </view>
        </view>
    </view>

</template>

<script>
    const bluetooth = uni.requireNativePlugin('LY-Bluetooth');
    export default {
        data() {
            return {
                weight: "",
                weight2: "",
                bluetoothList: [],
                isPrimitive: false
            }
        },
        onLoad() {
            console.log("初始化")
            bluetooth.initBluetooth({
                isPrimitive: this.isPrimitive
            })
        },
        methods: {
            getServiceCharacter() { //获取服务与特征
                bluetooth.getBluetoothServiceAndCharacter((res) => {
                    if (res.status == 200) {
                        console.log(res.data);
                    }
                })
            },
            sendData() { //发送数据
                bluetooth.sendDataToBluetooth({
                    serviceID: 'FFB0',
                    characteristicID: 'FFB1',
                    data: '86', //发送数据
                    charserType: "HEX", //用于设置编码HEX:16进制字符串、GBK:GBK字符串、UTF-8
                    writeResponse: false //写入数据是否有响应 默认false
                }, (res) => { //写入回调
                    if (res.status == 200) { //写入成功

                    } else if (res.status == 401) { //蓝牙未连接

                    } else if (res.status == 402) { //服务ID为空

                    } else if (res.status == 403) { //特征ID为空

                    } else if (res.status == 404) { //写入数据为空

                    } else if (res.status == 405) { //不支持响应Write

                    } else if (res.status == 406) { //不支持noResponseWrite

                    }
                    uni.showToast({
                        title: res.msg,
                        icon: 'none',
                        duration: 1500
                    })

                });
            },
            // 读取蓝牙数据
            readBluetooth() {
                bluetooth.readDataToBluetooth({
                    serviceID: 'FFB0',
                    characteristicID: 'FFB1'
                }, res => {
                    if (res.code == 200) {
                        console.log("读取数据:" + res.data)
                    }else{
                        uni.showToast({
                            title:res.msg,
                            icon:'none',
                            duration:1500
                        })
                    }
                })
            },
            // 连接蓝牙
            connectBluetooth(bluetoothName, peripheralUUID) {
                if (bluetoothName == "") {
                    uni.showToast({
                        title: '蓝牙名称为空',
                        icon: 'none'
                    })
                    return
                }
                console.log("蓝牙名称:" + bluetoothName + "address:" + peripheralUUID);
                // "0000xxxx-0000-1000-8000-00805f9b34fb"下面的服务ID和特征ID取xxxx部分一般是4位
                bluetooth.connectBlutoothWithName({
                    blutoothName: bluetoothName, //蓝牙名称  MinorFishScale
                    peripheralUUID: peripheralUUID, //外设UUID BLE有效(iOS:uuid,Android:mac)
                    notifyServiceIDs: 'FFB0', //外设notify对应服务ID
                    notifyCharacteristicIDs: 'FFB2', //外设notify特征
                }, (res) => {
                    console.log(res.status)
                    switch (parseInt(res.status)) {
                        case 0: {
                            uni.showToast({
                                title: '请先配对电子秤',
                                icon: 'error'
                            })
                        }
                        break;
                        case 1: { //经典蓝牙读取数据回调 与ble蓝牙notify回调
                            console.log(res.data)
                            this.weight2 = res.data;
                            if (this.isPrimitive) {
                                let subStr = res.data.slice(4, 8);
                                let weight1 = ""
                                if (subStr.charAt(0) == '8') { //为负数
                                    weight1 = 0.00
                                } else {
                                    weight1 = '0x' + subStr;
                                    weight1 = parseInt(weight1) * 0.01;
                                }
                                this.weight = weight1;
                            }
                        }
                        break;
                        case 2: {
                            uni.showToast({
                                title: '蓝牙连接成功',
                                icon: 'success'
                            })
                        }
                        break;
                        case 3: {
                            uni.showToast({
                                title: '蓝牙已断开',
                                icon: 'error'
                            })
                        }
                        break;
                        case 7: {
                            uni.showToast({
                                title: '连接失败',
                                icon: 'error'
                            })
                        }
                        break;
                        default: {

                        }

                    }
                })
            },
            discovery() {
                bluetooth.discoveryBluetooth((res) => {
                    if (res.status == 5) {
                        console.log(res.data)
                        this.bluetoothList = this.bluetoothList.concat(res.data)
                    }
                });

            },
            // 断开蓝牙
            disconnect() {
                bluetooth.disconnectBluetooth();
            }

        }
    }
</script>

<style>
    .header {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 750rpx;
        background-color: aqua;
        padding: 20rpx 0;
    }

    .btn_view {
        display: flex;
        align-items: center;
        flex-direction: row;
        justify-content: center;
    }

    .list {
        width: 750rpx;
        display: flex;
        flex-direction: column;
    }

    .cell {
        display: flex;
        flex-direction: column;
        justify-content: center;
        padding: 10rpx;
        box-sizing: border-box;
        background-color: antiquewhite;
    }

    .btn {
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 8px;
        padding: 15rpx 15rpx;
        background-color: coral;
        box-sizing: border-box;
        background-color: #004a6e;
    }
</style>

隐私、权限声明

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

android: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-feature android:name="android.hardware.bluetooth" /> iOS: Bluetooth Always Usage Description

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

插件不采集任何数据

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

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