1
0
forked from dyf/APP
Files
APP/utils/BleHelper.js

1267 lines
29 KiB
JavaScript
Raw Normal View History

2025-08-18 16:30:44 +08:00
import receivTool from "@/utils/BleReceive.js"
var recei = null;
2025-08-05 13:14:22 +08:00
class BleHelper {
constructor() {
this.StorageKey = "linkedDevices";
2025-08-18 16:30:44 +08:00
recei = receivTool.getBleReceive();
2025-08-05 13:14:22 +08:00
this.init();
}
init() {
let key = this.StorageKey;
var store = uni.getStorageInfoSync();
var f = store.keys.find(function(v) {
return v == key;
});
var linkedDevices = [];
if (f) {
2025-08-12 15:27:14 +08:00
linkedDevices = uni.getStorageSync(key);
2025-08-05 13:14:22 +08:00
}
2025-08-12 15:27:14 +08:00
if (linkedDevices && linkedDevices.length && linkedDevices.length > 0) {
console.log("111111", linkedDevices);
linkedDevices.filter((v) => {
v.Linked = false;
v.notifyState = false;
});
}
2025-08-05 13:14:22 +08:00
setTimeout(() => {
this.linkAllDevices();
}, 10);
this.data = {
isOpenBlue: false, //蓝牙模块是否开启
available: false, //蓝牙状态是否可用
discovering: false, //蓝牙是否正在搜索
searchList: [], //已搜索到的设备列表,
isSubscribe: false, //是否开启了订阅
LinkedList: linkedDevices, //已连接的设备列表
}
this.cfg = {
onDeviceFound: [], //发现新设备的事件
receivDataCallback: [] //接收到数据的事件
}
2025-08-18 16:30:44 +08:00
this.addReceiveCallback((a,b,c)=>{
recei.ReceiveData(a,b,c);
}, "BleReceiveData");
2025-08-05 13:14:22 +08:00
this.dic = {
errRemarks: [{
key: '10000',
remark: '未初始化蓝牙适配器'
},
{
key: '10001',
remark: '当前蓝牙适配器不可用'
},
{
key: '10002',
remark: '没有找到指定设备'
},
{
key: '10003',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备连接失败'
2025-08-05 13:14:22 +08:00
},
{
key: '10004',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备没有找到指定服务'
2025-08-05 13:14:22 +08:00
},
{
key: '10005',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备没有找到指定特征值'
2025-08-05 13:14:22 +08:00
},
{
key: '10006',
2025-08-14 17:25:53 +08:00
remark: '蓝牙连接已断开'
2025-08-05 13:14:22 +08:00
},
{
key: '10007',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备当前特征值不支持此操作'
2025-08-05 13:14:22 +08:00
},
{
key: '10008',
remark: '其余所有系统上报的异常'
},
{
key: '10009',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备不支持BLE低功耗蓝牙'
2025-08-05 13:14:22 +08:00
},
{
key: '10010',
remark: '已连接'
},
{
key: '10011',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备配对设备需要配对码'
2025-08-05 13:14:22 +08:00
},
{
key: '10012',
2025-08-14 17:25:53 +08:00
remark: '蓝牙设备连接超时'
2025-08-05 13:14:22 +08:00
},
{
key: '10013',
remark: '连接 deviceId 为空或者是格式不正确'
}
]
}
}
linkAllDevices() {
console.log("模块启动时,自动连接已连接过的设备", this.data.LinkedList);
if (this.data.LinkedList && this.data.LinkedList.length > 0) {
for (var i = 0; i < this.data.LinkedList.length; i++) {
let device = this.data.LinkedList[i];
console.log("自动连接:" + device.deviceId);
this.LinkBlue(device.deviceId, device.writeServiceId, device.wirteCharactId, device
.notifyCharactId);
}
} else {
console.log("无设备连接");
}
}
getCurrentPagePath() {
const pages = getCurrentPages();
if (pages.length === 0) {
2025-08-14 17:25:53 +08:00
return "";
2025-08-05 13:14:22 +08:00
}
const currentPage = pages[pages.length - 1];
2025-08-15 16:39:00 +08:00
console.log("currentPage=", currentPage.route);
2025-08-05 13:14:22 +08:00
return currentPage.route;
}
//设置发现新设备的回调
2025-08-18 16:30:44 +08:00
addDeviceFound(callback, currKey) {
let key = currKey ? currKey : this.getCurrentPagePath();
2025-08-15 16:39:00 +08:00
if (!key) {
key = new Date().getTime();
2025-08-14 17:25:53 +08:00
}
2025-08-05 13:14:22 +08:00
if (key) {
2025-08-15 16:39:00 +08:00
console.log("key=" + key);
2025-08-05 13:14:22 +08:00
let f = this.cfg.onDeviceFound.findIndex((v) => {
return v.key == key;
});
if (f > -1) {
this.cfg.onDeviceFound[f].callback = callback;
return;
}
this.cfg.onDeviceFound.push({
key: key,
callback: callback
});
}
}
2025-08-07 08:48:02 +08:00
//移除发现新设备的回调
2025-08-18 08:38:28 +08:00
removeDeviceFound(currKey) {
2025-08-18 16:30:44 +08:00
let key = currKey ? currKey : this.getCurrentPagePath();
2025-08-15 16:39:00 +08:00
2025-08-07 08:48:02 +08:00
if (key) {
2025-08-15 16:39:00 +08:00
console.log("key=" + key);
2025-08-07 08:48:02 +08:00
let f = this.cfg.onDeviceFound.findIndex((v) => {
return v.key == key;
});
if (f > -1) {
this.cfg.onDeviceFound.splice(f, 1);
}
2025-08-15 16:39:00 +08:00
} else {
if (this.cfg.onDeviceFound.length > 0) {
this.cfg.onDeviceFound.splice(this.cfg.onDeviceFound.length - 1, 1);
2025-08-14 17:25:53 +08:00
}
2025-08-15 16:39:00 +08:00
2025-08-07 08:48:02 +08:00
}
}
2025-08-05 13:14:22 +08:00
2025-08-07 08:48:02 +08:00
//添加接收到数据的回调
2025-08-18 16:30:44 +08:00
addReceiveCallback(callback, currKey) {
let key = currKey ? currKey : this.getCurrentPagePath();
2025-08-15 16:39:00 +08:00
if (!key) {
key = new Date().getTime();
2025-08-14 17:25:53 +08:00
}
2025-08-05 13:14:22 +08:00
if (key) {
2025-08-18 16:30:44 +08:00
console.log("订阅消息回调,key=" + key);
2025-08-05 13:14:22 +08:00
let f = this.cfg.receivDataCallback.findIndex((v) => {
return v.key == key;
});
if (f > -1) {
this.cfg.receivDataCallback.callback = callback;
return;
}
this.cfg.receivDataCallback.push({
key: key,
callback: callback
});
}
}
2025-08-07 08:48:02 +08:00
2025-08-05 13:14:22 +08:00
//设置接收到数据的回调
2025-08-18 16:30:44 +08:00
removeReceiveCallback(currKey) {
let key = currKey ? currKey : this.getCurrentPagePath();
2025-08-05 13:14:22 +08:00
if (key) {
2025-08-18 16:30:44 +08:00
console.log("移除消息回调:" + key);
2025-08-05 13:14:22 +08:00
let f = this.cfg.receivDataCallback.findIndex((v) => {
return v.key == key;
});
if (f > -1) {
this.cfg.receivDataCallback.splice(f, 1);
}
2025-08-15 16:39:00 +08:00
} else {
if (this.cfg.receivDataCallback.length > 0) {
this.cfg.receivDataCallback.splice(this.cfg.receivDataCallback.length - 1, 1);
}
2025-08-05 13:14:22 +08:00
}
}
2025-08-05 13:14:22 +08:00
getError(ex) {
let code = ex.code;
ex.msg = "未知的异常"
let f = this.dic.errRemarks.find((v) => {
return v.key == code;
});
if (f) {
ex.msg = f.remark;
}
return ex;
}
//引导到设置中打开蓝牙
showBlueSetting(showTip) {
let platform = process.env.UNI_PLATFORM;
var openBlueSetting = function() {
// 判断平台类型
if (platform === 'mp-weixin') {
uni.openSetting();
} else if (platform === 'app-plus' || platform === 'app') {
//----------------------------------------------------------------
const osName = plus.os.name;
if (osName === 'iOS') {
// iOS 平台打开蓝牙设置
plus.runtime.openURL('App-Prefs:root=Bluetooth', function() {
////console.log('成功打开蓝牙设置');
}, function(err) {
console.error('打开蓝牙设置失败:' + err.message);
uni.showModal({
title: '提示',
content: '无法自动打开蓝牙设置,请手动前往设置 > 蓝牙 进行操作。',
showCancel: false
});
});
} else if (osName === 'Android') {
// Android 平台打开蓝牙设置
try {
const Intent = plus.android.importClass('android.content.Intent');
const Settings = plus.android.importClass('android.provider.Settings');
const main = plus.android.runtimeMainActivity();
const intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
main.startActivity(intent);
} catch (e) {
console.error('打开蓝牙设置失败:' + e.message);
// 尝试使用通用设置页面作为备选方案
plus.runtime.openURL('settings://', function() {
////console.log('打开系统设置成功,请手动找到蓝牙选项');
}, function() {
uni.showModal({
title: '提示',
content: '无法自动打开蓝牙设置,请手动前往设置页面开启蓝牙。',
showCancel: false
});
});
}
} else {
uni.showModal({
title: '提示',
content: '当前系统不支持自动打开蓝牙设置,请手动操作。',
showCancel: false
});
}
//--------------------------------------------------------------------
} else if (platform === 'mp-alipay') {
uni.openSetting();
}
}
if (showTip !== undefined) {
openBlueSetting();
return;
}
if (platform === 'mp-weixin' || platform === 'app-plus' ||
platform === 'mp-alipay' || platform === 'app') {
uni.showModal({
title: '蓝牙未开启',
content: '请在系统设置中打开蓝牙以使用此功能',
success: (res) => {
if (res.confirm) {
openBlueSetting();
}
}
});
} else {
////console.log("当前平台不支持打开系统设置" + platform);
}
}
//获取蓝牙适配器状态
CheckBlue() {
return new Promise((resolve, reject) => {
if (this.data.available) {
resolve({
available: this.data.available,
discovering: this.data.discovering
});
return;
}
if (!this.data.isOpenBlue) {
resolve({
available: false,
discovering: false
});
return;
}
uni.getBluetoothAdapterState({
success: (info) => {
resolve(info);
},
fail: (ex1) => {
////console.log("ex1", ex1);
let res1 = {
available: false,
discovering: false
}
resolve(res1);
}
});
});
}
//打开蓝牙适配器
OpenBlue() {
var init = () => {
return new Promise((resolve, reject) => {
if (this.data.isOpenBlue) {
console.log("蓝牙状态已可用,提前返回");
resolve(false);
return;
}
uni.openBluetoothAdapter({
success: (args) => {
console.log("蓝牙初始化成功:" + JSON.stringify(args));
this.data.isOpenBlue = true;
resolve(true);
if (this.data.isSubscribe) { //整个App生命周期只订阅一次
return;
}
console.log("开始订阅各类变化消息");
this.data.isSubscribe = true;
var bytesToHexString = (bytes) => {
2025-08-12 15:27:14 +08:00
return bytes.map(byte => byte.toString(16).padStart(2,
'0'));
2025-08-05 13:14:22 +08:00
}
uni.onBluetoothAdapterStateChange((state) => {
console.log('蓝牙状态发生变化:' + JSON.stringify(state));
this.data.available = state.available;
this.data.discovering = state.discovering;
if (this.data.available && this.data
.isOpenBlue) { //蓝牙状态再次可用,重连所有设备
}
if (!state.available) { //蓝牙状态不可用了,将所有设备标记为断开连接
this.data.LinkedList.filter((v) => {
v.Linked = false;
v.notifyState = false;
2025-08-05 13:14:22 +08:00
return true;
});
uni.setStorageSync(this.StorageKey, this.data
.LinkedList);
}
});
uni.onBLEConnectionStateChange((res) => {
2025-08-05 13:14:22 +08:00
if (!res.connected) {
console.log("蓝牙连接已断开", res);
this.data.LinkedList.find((v) => {
if (v.deviceId == res.deviceId) {
v.Linked = false;
v.notifyState = false;
return true;
}
return false;
});
uni.setStorageSync(this.StorageKey, this.data
.LinkedList);
} else {
console.log("蓝牙连接已恢复,", res);
2025-08-05 13:14:22 +08:00
}
});
uni.onBluetoothDeviceFound((devices) => {
// ////console.log("发现新设备:" + JSON.stringify(devices));
this.data.searchList = this.data.searchList.concat(
devices);
if (this.cfg.onDeviceFound) {
if (this.cfg.onDeviceFound.length > 0) {
this.cfg.onDeviceFound.forEach((found) => {
found.callback(devices);
});
}
}
});
uni.onBLECharacteristicValueChange((receive) => {
2025-08-18 16:30:44 +08:00
//订阅消息
let f=this.data.LinkedList.find((v) => {
return v.deviceId == receive.deviceId;
})
2025-08-05 13:14:22 +08:00
let dataView = new DataView(receive.value);
// 转换为字节数组
let bytes = [];
for (let i = 0; i < dataView.byteLength; i++) {
bytes.push(dataView.getUint8(i));
}
let hexs = bytesToHexString(bytes);
let str = '';
try {
let uint8Array = new Uint8Array(receive.value);
for (let i = 0; i < uint8Array.length; i++) {
// 将每个字节转换为对应的字符
str += String.fromCharCode(uint8Array[i]);
}
2025-08-15 16:39:00 +08:00
let header = "mac address:";
if (str.indexOf(header) == 0) { //650以文本传输mac
2025-08-12 15:27:14 +08:00
this.data.LinkedList.find((v) => {
2025-08-15 16:39:00 +08:00
if (v.deviceId == receive
.deviceId) {
v.macAddress = str.replace(
header, "");
2025-08-18 16:30:44 +08:00
// console.log("收到mac地址:", str)
2025-08-12 15:27:14 +08:00
}
});
uni.setStorageSync(this.StorageKey, this.data
.LinkedList);
2025-08-18 16:30:44 +08:00
}
if (bytes[0] == 0xFC) { //6155以0xFC开头代表mac地址
// console.log("收到mac地址:", bytes)
if (bytes.length >= 7) {
let mac = hexs.slice(1, 7).join(":")
.toUpperCase();
2025-08-15 16:39:00 +08:00
this.data.LinkedList.find((v) => {
if (v.deviceId == receive
.deviceId) {
v.macAddress = mac;
2025-08-18 16:30:44 +08:00
// console.log("收到mac地址:", str)
2025-08-15 16:39:00 +08:00
}
});
uni.setStorageSync(this.StorageKey, this
.data.LinkedList);
}
2025-08-12 15:27:14 +08:00
}
2025-08-05 13:14:22 +08:00
} catch (ex) {
////console.log("将数据转文本失败", ex);
}
let recData = {
2025-08-18 16:30:44 +08:00
deviceId: receive.deviceId,
serviceId: receive.serviceId,
characteristicId: receive.characteristicId,
2025-08-05 13:14:22 +08:00
bytes: bytes,
str: str,
hexs: hexs
};
console.log("监听到特征值:" + JSON.stringify(recData));
if (this.cfg.receivDataCallback) {
2025-08-18 16:30:44 +08:00
2025-08-05 13:14:22 +08:00
if (this.cfg.receivDataCallback.length > 0) {
2025-08-18 16:30:44 +08:00
let path = this.getCurrentPagePath();
2025-08-05 13:14:22 +08:00
this.cfg.receivDataCallback.forEach((rec) => {
2025-08-18 16:30:44 +08:00
if (rec.callback) {
}
rec.callback(recData, f, path);
2025-08-05 13:14:22 +08:00
})
}
} else {
2025-08-18 16:30:44 +08:00
console.log("无人订阅receivDataCallback,不处理数据");
2025-08-05 13:14:22 +08:00
}
});
},
fail: (ex2) => {
console.log("蓝牙模块启动失败", ex2);
reject(this.getError(ex2));
}
});
});
}
return new Promise((resolve, reject) => {
if (this.data.isOpenBlue) {
resolve();
return;
}
this.CheckBlue().then((res) => {
console.log("res=", res)
return init();
}).then(resolve).catch((ex) => {
console.log("22222");
reject(ex);
});
});
}
//关闭蓝牙适配器
CloseBlue() {
return new Promise((resolve, reject) => {
this.data.available = false;
this.data.discovering = false;
this.data.isOpenBlue = false;
this.data.searchList = [];
this.StopSearch();
this.disconnectDevice();
uni.closeBluetoothAdapter({
success: () => {
console.log("蓝牙模块已关闭");
this.data.isOpenBlue = false;
},
fail: (ex) => {
ex = this.getError(ex);
////console.log(msg);
},
complete: () => {
resolve();
}
});
});
}
//开始搜索新设备
StartSearch() {
this.data.searchList = [];
var these = this;
//开始搜索
var Search = () => {
2025-08-12 15:27:14 +08:00
console.log("Search........");
2025-08-05 13:14:22 +08:00
return new Promise((resolve, reject) => {
uni.startBluetoothDevicesDiscovery({
services: [],
2025-08-15 16:39:00 +08:00
allowDuplicatesKey: true,
2025-08-05 13:14:22 +08:00
success: (res) => {
//console.log('开始搜索蓝牙设备成功');
resolve(res);
},
fail: (err) => {
2025-08-12 15:27:14 +08:00
console.log(`搜索蓝牙设备失败:`, err);
2025-08-05 13:14:22 +08:00
reject(this.getError(err));
}
});
});
}
return this.OpenBlue().then((res) => {
2025-08-12 15:27:14 +08:00
console.log("蓝牙适配器状态", res)
2025-08-05 13:14:22 +08:00
return Search();
});
}
//停止搜索
StopSearch() {
return new Promise((resolve, reject) => {
uni.stopBluetoothDevicesDiscovery({
success: (res) => {
//console.log("停止搜索蓝牙设备成功");
resolve();
},
fail: (ex) => {
//console.log("无法停止蓝牙搜索");
reject(this.getError(ex));
}
});
})
}
//获取已连接的设备
getLinkBlue(callback) {
return new Promise((resolve, reject) => {
uni.getConnectedBluetoothDevices({
success: (res) => {
resolve(res);
},
fail: (ex) => {
////console.log("获取已连接设备异常", ex);
reject({
devices: []
});
}
});
});
}
//订阅消息
subScribe(deviceId, state) {
return new Promise((resolve, reject) => {
setTimeout(() => {
let c = this.data.LinkedList.find((v) => {
return v.deviceId == deviceId;
});
if (state) {
if (c.notifyState) {
resolve();
return;
}
}
2025-08-12 15:27:14 +08:00
console.log("c=", c);
let startSubScribe = (id, serviceId, characteristicId) => {
2025-08-15 16:39:00 +08:00
2025-08-12 15:27:14 +08:00
return new Promise((succ, err) => {
uni.notifyBLECharacteristicValueChange({
deviceId: id,
serviceId: serviceId,
characteristicId: characteristicId,
state: state,
success: (res) => {
if (state) {
console.log("订阅消息成功", res);
} else {
console.log("取消订阅成功", res);
}
this.data.LinkedList.find((v) => {
if (v.deviceId == deviceId) {
v.notifyState = state;
}
});
succ();
},
fail: (ex) => {
2025-08-15 16:39:00 +08:00
2025-08-12 15:27:14 +08:00
err(this.getError(ex));
}
});
});
}
let promies = new Array();
for (var i = 0; i < c.Characteristics.length; i++) {
let item = c.Characteristics[i];
let serviceId = item.serviceId;
let characteristicId = item.uuid;
if (item.properties.notify) {
promies.push(startSubScribe(deviceId, serviceId, characteristicId));
}
}
if (promies.length > 0) {
Promise.allSettled(promies).then((results) => {
2025-08-05 13:14:22 +08:00
2025-08-12 15:27:14 +08:00
results.forEach((result, index) => {
if (result.status === "fulfilled") {
2025-08-15 16:39:00 +08:00
//console.log(`操作${index + 1}成功:`, result.value);
2025-08-12 15:27:14 +08:00
} else {
2025-08-15 16:39:00 +08:00
// console.log(`操作${index + 1}失败:`, result.reason
// .message);
2025-08-05 13:14:22 +08:00
}
});
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
resolve();
2025-08-12 15:27:14 +08:00
}).catch((ex) => {
reject(ex);
});
} else {
resolve();
}
2025-08-05 13:14:22 +08:00
}, 20);
});
}
//获取服务
getService(id, targetServiceId, writeCharId, notifyCharId) {
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
if (!targetServiceId) {
2025-08-12 15:27:14 +08:00
targetServiceId = "xx"; // "FFE0";
2025-08-05 13:14:22 +08:00
}
return new Promise((resolve, reject) => {
var repeatCnt = 0;
var startgetService = () => {
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
uni.getBLEDeviceServices({
deviceId: id,
success: (res) => {
if (res.services && res.services.length > 0) {
2025-08-12 15:27:14 +08:00
console.log("获取到服务:" + JSON.stringify(res));
2025-08-05 13:14:22 +08:00
this.data.LinkedList.find((v) => {
if (v.deviceId == id) {
v.services = res.services;
}
});
uni.setStorageSync(this.StorageKey,
this.data.LinkedList);
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
var promises = [];
2025-08-12 15:27:14 +08:00
let se = res.services.find((v) => {
return v.uuid.indexOf(targetServiceId) > -1;
});
if (se) {
promises.push(this.getFeatrus(id, se.uuid, writeCharId,
notifyCharId));
} else {
for (var i = 0; i < res.services.length; i++) {
let service = res.services[i];
2025-08-05 13:14:22 +08:00
promises.push(this.getFeatrus(id, service.uuid,
writeCharId, notifyCharId));
}
}
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
if (promises.length == 0) {
2025-08-12 15:27:14 +08:00
console.log("未找到主服务");
2025-08-05 13:14:22 +08:00
reject({
msg: "未找到主服务",
code: -1
});
} else {
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
Promise.all(promises)
.then(results => {
2025-08-12 15:27:14 +08:00
return this.subScribe(id, true);
})
.then((res) => {
2025-08-15 16:39:00 +08:00
console.log('设备连接成功,初始化完成', res);
2025-08-12 15:27:14 +08:00
console.log("LinkedList=", this.data
.LinkedList);
2025-08-05 13:14:22 +08:00
resolve();
})
.catch(error => {
2025-08-12 15:27:14 +08:00
console.log("errrr", error);
2025-08-05 13:14:22 +08:00
reject(error);
});
}
} else {
repeatCnt++;
if (repeatCnt > 5) {
reject({
msg: "获取设备服务失败",
code: -1
});
return;
}
setTimeout(function() {
startgetService(id);
}, 100);
}
},
fail: (ex) => {
reject(this.getError(ex));
}
})
}
setTimeout(function() {
startgetService(id);
}, 100);
});
}
//获取特征
getFeatrus(id, serviceId, writeCharId, notifyCharId) {
var promise = new Promise((resolve, reject) => {
uni.getBLEDeviceCharacteristics({
deviceId: id,
serviceId: serviceId,
success: (res) => {
2025-08-12 15:27:14 +08:00
console.log("获取到特征:" + JSON.stringify(res));
res.characteristics.forEach((v) => {
v.serviceId = serviceId;
});
2025-08-05 13:14:22 +08:00
//写特征
2025-08-12 15:27:14 +08:00
let writeChar = res.characteristics.find(char => {
return char.uuid.indexOf(writeCharId) > -1
});
if (!writeChar) {
writeChar = res.characteristics.find(char => {
return char.properties.write;
});
}
2025-08-05 13:14:22 +08:00
//通知特征
2025-08-12 15:27:14 +08:00
let notiChar = res.characteristics.find(char => {
return char.uuid.indexOf(notifyCharId) > -1;
});
if (!notiChar) {
notiChar = res.characteristics.find(char => {
return char.properties.notify;
});
}
2025-08-05 13:14:22 +08:00
this.data.LinkedList.find(function(v) {
if (v.deviceId == id) {
if (!v.Characteristics) {
v.Characteristics = [];
}
2025-08-12 15:27:14 +08:00
for (var i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
let flag = false;
for (var j = 0; j < v.Characteristics.length; j++) {
let charact = v.Characteristics[j];
if (charact.uuid == item.uuid) {
flag = true;
break;
}
}
if (!flag) {
v.Characteristics.push(item);
}
}
2025-08-15 16:39:00 +08:00
2025-08-05 13:14:22 +08:00
if (writeChar) {
v.writeServiceId = serviceId;
v.wirteCharactId = writeChar.uuid;
}
if (notiChar) {
v.notifyServiceid = serviceId;
v.notifyCharactId = notiChar.uuid;
}
2025-08-12 15:27:14 +08:00
return true;
2025-08-05 13:14:22 +08:00
}
2025-08-12 15:27:14 +08:00
return false;
2025-08-05 13:14:22 +08:00
});
2025-08-12 15:27:14 +08:00
2025-08-05 13:14:22 +08:00
uni.setStorageSync(this.StorageKey, this.data.LinkedList);
resolve(res);
},
fail: (ex) => {
////console.log("获取特征出现异常:" + JSON.stringify(ex));
reject(ex);
}
});
});
return promise;
}
//连接某个设备
LinkBlue(deviceId, targetServiceId, writeCharId, notifyCharId) {
2025-08-15 16:39:00 +08:00
2025-08-05 13:14:22 +08:00
if (!writeCharId) {
2025-08-12 15:27:14 +08:00
writeCharId = "xxxx"; // "FFE1";
2025-08-05 13:14:22 +08:00
}
if (!notifyCharId) {
2025-08-12 15:27:14 +08:00
notifyCharId = "xxxxx"; // "FFE2";
2025-08-05 13:14:22 +08:00
}
let fIndex = -1;
let f = this.data.LinkedList.find((v, index) => {
if (v.deviceId == deviceId) {
fIndex = index;
return true;
}
return false;
});
////console.log("findex=" + fIndex);
var these = this;
//连接设备
var linkDevice = () => {
return new Promise((resolve, reject) => {
if (fIndex > -1 && f?.Linked) {
2025-08-12 15:27:14 +08:00
console.log("当前已连接,跳过其他步骤")
2025-08-05 13:14:22 +08:00
resolve(false);
return;
}
console.log("正在连接" + deviceId);
uni.createBLEConnection({
deviceId: deviceId,
2025-08-14 17:25:53 +08:00
timeout: 3000,
2025-08-05 13:14:22 +08:00
success: (info) => {
2025-08-12 15:27:14 +08:00
console.log("新连接成功", this.data.LinkedList);
2025-08-05 13:14:22 +08:00
this.getLinkBlue().then((arr) => {
let cr = arr.devices.find(c => {
if (c.deviceId == deviceId) {
c.Linked = true;
return true;
}
return false;
});
if (fIndex > -1) {
this.data.LinkedList[fIndex].Linked = true;
} else {
this.data.LinkedList.push(cr);
}
uni.setStorageSync(this.StorageKey, this.data
.LinkedList);
let os = plus.os.name;
if (os == 'android') {
uni.setBLEMTU({
deviceId: deviceId,
mtu: 512,
success: (mtu) => {
////console.log("mtu设置成功");
},
fail: () => {
////console.log("mtu设置失败")
}
});
}
resolve(true);
}).catch((ex) => {
reject(this.getError(ex));
});
},
fail: (ex) => {
ex = this.getError(ex)
console.log("蓝牙连接失败" + JSON.stringify(ex));
reject(ex);
}
});
});
}
return new Promise((resolve, reject) => {
this.OpenBlue().then((res) => {
////console.log("2222222");
return linkDevice(deviceId);
}).then((res) => {
////console.log("11111111");
if (res) { //新连接
2025-08-18 16:30:44 +08:00
if (fIndex == -1) {
console.log("开始获取服务", targetServiceId)
return this.getService(deviceId, targetServiceId, writeCharId,
2025-08-05 13:14:22 +08:00
notifyCharId); //获取服务
2025-08-18 16:30:44 +08:00
} else {
if (!f.notifyState) {
this.subScribe(deviceId, true);
}
return Promise.resolve(true);
}
2025-08-05 13:14:22 +08:00
} else { //已连接过,直接订阅消息
if (fIndex > -1 && f && !f.notifyState) {
this.subScribe(deviceId, true);
}
return Promise.resolve(true); //已连接过的设备无需获取服务
}
}).then(() => {
2025-08-15 16:39:00 +08:00
setTimeout(() => {
2025-08-14 17:25:53 +08:00
resolve();
2025-08-15 16:39:00 +08:00
}, 500);
2025-08-05 13:14:22 +08:00
}).catch((ex) => {
////console.log("出现异常", ex);
reject(ex);
});
});
}
//断开连接
disconnectDevice(deviceId) {
var disconnect = (id) => {
return new Promise((resolve, reject) => {
uni.closeBLEConnection({
deviceId: id,
success: (res) => {
////console.log("蓝牙连接已断开:" + id);
this.subScribe(id, false);
resolve();
},
fail: (ex) => {
reject(this.getError(ex));
}
});
});
}
if (deviceId) {
disconnect(deviceId);
this.data.LinkedList.find(v => {
if (v.deviceId === deviceId) {
return true;
}
return false;
});
return;
}
if (this.data.LinkedList.length > 0) {
let arr = [];
for (var i = 0; i < this.data.LinkedList.length; i++) {
let item = this.data.LinkedList[i];
if (item.Linked) {
arr.push(disconnect(item.deviceId));
}
}
if (arr.length == 0) {
return;
}
Promise.allSettled(arr).then((results) => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
////console.log(`第${index + 1}个Promise成功:`, result.value);
} else {
////console.log(`第${index + 1}个Promise失败:`, result.reason.message);
}
});
});
} else {
////console.log("无已连接设备");
}
}
2025-08-07 08:48:02 +08:00
//向蓝牙设备发送数据,如果没连接将自动连接后再发
2025-08-05 13:14:22 +08:00
sendData(deviceid, buffer, writeServiceId, wirteCharactId, ms) {
2025-08-14 17:25:53 +08:00
// console.log("deviceid=" + deviceid + ",writeServiceId=" + writeServiceId + ",wirteCharactId=" +
// wirteCharactId + ",timeout=" + ms)
2025-08-05 13:14:22 +08:00
if (ms === undefined) {
ms = 50;
}
let c = this.data.LinkedList.find((v) => {
return v.deviceId == deviceid;
});
let device = {
deviceId: deviceid,
writeServiceId: null,
wirteCharactId: null
};
if (writeServiceId) {
device.writeServiceId = writeServiceId;
}
if (wirteCharactId) {
device.wirteCharactId = wirteCharactId;
}
if (!device.writeServiceId || !device.wirteCharactId) {
//console.log("从已连接中找设备")
if (c) {
device = c;
}
}
let sendBuffer = () => {
return new Promise(async (resolve, reject) => {
var promise = new Promise((succ, err) => {
if (!c) {
err(this.getError({
code: 10002
})); //没有找到指定设备
return;
}
2025-08-15 16:39:00 +08:00
console.log("device=", device);
2025-08-05 13:14:22 +08:00
uni.writeBLECharacteristicValue({
deviceId: device.deviceId,
serviceId: device.writeServiceId,
characteristicId: device.wirteCharactId,
value: buffer,
success: () => {
console.log("发送数据成功");
succ();
},
fail: (ex) => {
ex = this.getError(ex);
console.log("发送数据失败", ex);
err(ex);
}
});
});
if (plus.os.name == 'iOS') {
function timeOut(ms) {
return new Promise((_, err) => {
setTimeout(() => {
err({
code: -1,
errMsg: '超时了'
})
}, ms);
});
}
Promise.race([timeOut(ms), promise]).then(resolve).catch((ex) => {
console.log("ex=", ex);
if (ex.code == -1) {
2025-08-14 17:25:53 +08:00
resolve(ex);
2025-08-05 13:14:22 +08:00
} else {
reject(ex);
}
}).finally(() => {
//console.log("完成了")
});
} else {
promise.then(resolve).catch(reject);
}
});
}
if (c.Linked) {
2025-08-14 17:25:53 +08:00
// console.log("蓝牙已连接,直接发送");
2025-08-05 13:14:22 +08:00
return sendBuffer();
} else {
2025-08-14 17:25:53 +08:00
// console.log("先连接蓝牙再发送");
2025-08-05 13:14:22 +08:00
return new Promise((resolve, reject) => {
2025-08-15 16:39:00 +08:00
let f = this.data.LinkedList.find((v) => {
return v.deviceId == deviceid;
2025-08-14 17:25:53 +08:00
});
2025-08-15 16:39:00 +08:00
if (!f) {
reject({
code: '-9',
msg: '蓝牙未连接过此设备,请重新使用蓝牙添加该设备'
});
2025-08-14 17:25:53 +08:00
retrn;
}
2025-08-15 16:39:00 +08:00
this.LinkBlue(f.deviceId, f.writeServiceId, f.wirteCharactId, f.notifyCharactId).then((
res) => {
2025-08-05 13:14:22 +08:00
console.log("连接成功");
return sendBuffer();
}).then(() => {
//console.log("发送成功")
resolve();
}).catch((ex) => {
//console.log("出现异常", ex);
reject(this.getError(ex));
});
});
}
}
2025-08-07 08:48:02 +08:00
//将点阵数据转换成RGB565
convertToRGB565(pixels, type) {
2025-08-18 16:30:44 +08:00
if (!type) {
type = 'rgb';
}
const result = new Uint16Array(pixels.length / 4);
2025-08-12 15:27:14 +08:00
let index = 0;
2025-08-07 08:48:02 +08:00
for (let i = 0; i < pixels.length; i += 4) {
let r = pixels[i];
let g = pixels[i + 1];
let b = pixels[i + 2];
2025-08-18 16:30:44 +08:00
let a = pixels[i + 3];
2025-08-12 15:27:14 +08:00
if (type == 'bgr') {
2025-08-18 16:30:44 +08:00
result[index++] = (b >> 3) | ((g & 0xFC) << 3) | ((r & 0xF8) << 8);
2025-08-12 15:27:14 +08:00
} else {
2025-08-18 16:30:44 +08:00
result[index++] = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
2025-08-12 15:27:14 +08:00
2025-08-07 08:48:02 +08:00
}
2025-08-07 08:48:02 +08:00
return result;
}
2025-08-18 16:30:44 +08:00
setBleData() {
uni.setStorageSync(this.StorageKey, this.data.LinkedList);
}
2025-08-05 13:14:22 +08:00
}
let instance = null;
export default {
getBleTool: function(found, receive) {
if (!instance) {
instance = new BleHelper();
2025-08-15 16:39:00 +08:00
2025-08-05 13:14:22 +08:00
} else {
////console.log("调用现有实例");
}
return instance;
}
}