ly.js
// import { TextDecoder } from 'text-encoding-utf-8';
let bluetoothOpen = false; // 手机蓝牙是否打开
let bluetoothConnect = false; // 设备和蓝牙是否连接
let isHaveDevice = false; // 是否查找到设备
let deviceId = null; // 设备id
let serviceId = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'; // 服务id
let notify = null; // 监听uuid
let writeId = null; // 写入uuid
/**
* 获取手机蓝牙是否打开
*/
const checkPermission=(permissions, permissionName, success)=>{
return new Promise((resolve,reject)=>{
plus.android.requestPermissions(permissions, function(e) {
// console.log(e);
if (e.deniedAlways.length > 0) { //权限被永久拒绝
// 弹出提示框解释为何需要读写手机储存权限,引导用户打开设置页面开启
uni.showModal({
title: permissionName + '权限',
content: '您可能拒绝了' + permissionName + '权限或您的设备无需设置权限',
success: function(res) {
if (res.confirm) {
// console.log('用户点击确定');
} else if (res.cancel) {
// console.log('用户点击取消');
}
}
});
reject(false)
}
if (e.deniedPresent.length > 0) { //权限被临时拒绝
plus.android.requestPermissions(permissions)
reject(false)
}
if (e.granted.length > 0) { //权限被允许
if (success) {
success();
resolve(true)
}
}
}, function(e) {
uni.showToast({
title: '请打开蓝牙',
icon: 'none'
})
// plus.android.requestPermissions(permissions)
console.log('checkPermission error:', e);
});
})
}
const getBluetoothState = () => {
// 主机模式
return new Promise((resolve, reject) => {
// mode: 'central',
uni.openBluetoothAdapter({
success: (r) => {
console.log("蓝牙初始化成功");
// 获取蓝牙的匹配状态
uni.getBluetoothAdapterState({
success: function(row) {
console.log('蓝牙状态:', row.available);
if (row.available) {
bluetoothOpen = true;
resolve();
} else {
// 请开启蓝牙
// uni.showToast({
// title: '请打开蓝牙',
// icon: 'none'
// })
bluetoothOpen = false;
bluetoothConnect = false;
reject();
}
},
fail: function(err) {
// 请开启蓝牙
// uni.showToast({
// title: '请打开蓝牙',
// icon: 'none'
// })
bluetoothOpen = false;
bluetoothConnect = false;
reject();
}
})
},
fail: () => {
// 请开启蓝牙
checkPermission()
// uni.showToast({
// title: '蓝牙打开失败',
// icon: 'none'
// })
bluetoothOpen = false;
bluetoothConnect = false;
reject();
}
});
});
};
/**
* 开始搜索蓝牙设备
*/
const discoveryBluetooth = () => {
return new Promise((resolve) => {
uni.startBluetoothDevicesDiscovery({
success(res) {
console.log('搜索蓝牙外围设备完成', res)
setTimeout(() => {
resolve();
}, 2000);
}
});
})
};
// 关闭蓝牙搜索
const stopDiscoveryBluetooth = () => {
uni.stopBluetoothDevicesDiscovery({
success(r) {
console.log("停止搜索蓝牙设备", r);
}
});
};
/**
* 获取搜索到的设备信息
*/
const getBluetoothDevices = (deviceName) => {
return new Promise((resolve, reject) => {
uni.getBluetoothDevices({
success(res) {
console.log('获取搜索到的设备信息', res.devices);
bluetoothConnect = false;
// 过滤掉name为空或者未知设备的设备
let devices = res.devices.filter(function(obj) {
return obj.name !== "" && obj.name !== "未知设备"
});
console.log('有名称蓝牙列表', devices, deviceName);
devices && devices.forEach(item => {
if (item.name && item.name === deviceName) {
deviceId = item.deviceId;
isHaveDevice = true;
resolve(isHaveDevice);
console.log('设备ID', deviceId, item);
}
});
},
fail: function() {
console.log('搜索蓝牙设备失败');
bluetoothConnect = false;
isHaveDevice = false;
reject(isHaveDevice);
},
complete: function() {
console.log("蓝牙搜索完成");
// // 是否具有当前设备
if (deviceId) {
isHaveDevice = true;
} else {
isHaveDevice = false;
}
resolve(isHaveDevice);
}
});
});
}
/**
* 连接蓝牙
* deviceId 蓝牙设备id
*/
const connectBluetooth = () => {
console.log(deviceId);
return new Promise((resolve, reject) => {
uni.createBLEConnection({
deviceId: deviceId, // 设备id
success() {
bluetoothConnect = true;
console.log('连接蓝牙成功', deviceId);
// 蓝牙连接成功后关闭蓝牙搜索
stopDiscoveryBluetooth();
resolve();
getServiceId();
// 获取服务id
},
fail() {
bluetoothConnect = false;
console.log("蓝牙连接失败");
reject();
}
});
});
};
// 获取服务id
const getServiceId = () => {
console.log(deviceId);
setTimeout(()=>{
uni.getBLEDeviceServices({
deviceId: deviceId,
success(res) {
console.log("获取服务Id", res)
// let model = res.services[4];
// serviceId = model.uuid;
// 调用蓝牙监听和写入功能
getCharacteId();
}
})
},1000)
};
// 获取蓝牙低功耗设备某个服务中所有特征
const getCharacteId = () => {
console.log(deviceId,serviceId);
uni.getBLEDeviceCharacteristics({
deviceId: deviceId, // 蓝牙设备id
serviceId: serviceId, // 蓝牙服务UUID
success(res) {
console.log('数据监听', res);
res.characteristics.forEach(item => {
// 003
if (item.properties.notify === true) {
// 监听
notify = item.uuid;
startNotice();
}
// 002
if (item.properties.write === true) {
// 写入
let writeId = item.uuid;
uni.setStorageSync("writeId", item.uuid);
}
});
},
fail(err) {
console.log("数据监听失败", err)
}
})
};
// 启用低功耗蓝牙设备特征值变化时的notify功能
const startNotice = () => {
uni.notifyBLECharacteristicValueChange({
characteristicId: notify,
deviceId: deviceId,
serviceId: serviceId,
state: true,
success(res) {
// 监听低功耗蓝牙设备的特征值变化
uni.onBLECharacteristicValueChange(result => {
function ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
}
function hexToAscii(hexString) {
let result = "";
let hexArr = hexString.match(/.{1,2}/g);
hexArr.forEach(hex => {
let charCode = parseInt(hex, 16);
let char = String.fromCharCode(charCode);
result += char;
});
return result;
}
function utf8to16(str) {
var out, i, len, c;
var char2, char3;
out = "";
len = str.length;
i = 0;
while(i < len) {
c = str.charCodeAt(i++);
switch(c >> 4){
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
out += str.charAt(i-1);
break;
case 12: case 13:
char2 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
char2 = str.charCodeAt(i++);
char3 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
// console.log(out,'out')
return out;
}
var value = ab2hex(result.value);
// console.log(value);
console.log(utf8to16(hexToAscii(value)));
// console.log("监听低功耗蓝牙设备的特征值变化", result);
// if (result.value) {
// let decoder = new TextDecoder('utf-8');
// let data = decoder.decode(result.value);
// // let data = result.value;
// console.log('帽子返回数据', data)
// }
})
}
});
};
// 蓝牙发送数据
const writeData = (buffer) => {
console.log(buffer,uni.getStorageSync("writeId"),deviceId,serviceId);
return new Promise((resolve, reject) => {
uni.writeBLECharacteristicValue({
characteristicId: uni.getStorageSync("writeId"),
deviceId: deviceId,
serviceId: serviceId,
value: buffer,
success(res) {
console.log("writeBLECharacteristicValue success", res);
resolve();
},
fail(err) {
console.log("报错了", err);
reject();
}
});
});
};
const createBlec = () => {
uni.createBLEConnection({
deviceId:deviceId,
success(res) {
console.log(res, '断开成功')
},
fail(err) {
console.log("断开失败", err);
}
})
}
// closeBLEConnection deviceId 断开蓝牙
export default {
checkPermission,
getBluetoothState,
discoveryBluetooth,
stopDiscoveryBluetooth,
getBluetoothDevices,
connectBluetooth,
getServiceId,
getCharacteId,
startNotice,
writeData,
createBlec
};
使用
var utf8 = unescape(encodeURIComponent('code=0.1.1'));
console.log(utf8.length);
initBluetooth() {
let _this = this;
// 初始化蓝牙
bluetooth.checkPermission(["android.permission.BLUETOOTH_CONNECT"],"蓝牙",function(){
console.log('蓝牙权限已获取!');
}).then((res)=>{
if(res){
bluetooth.getBluetoothState().then(
() => {
// 搜索外围蓝牙设备
bluetooth.discoveryBluetooth().then(() => {
this.discoveryLoading = true;
// 获取蓝牙设备
// 'RFstar_EE4E'
bluetooth.getBluetoothDevices('设备001').then(
(isHaveDevice) => {
console.log(isHaveDevice);
if (isHaveDevice) {
// 搜索到指定设备,连接蓝牙
bluetooth.connectBluetooth().then(
() => {
setTimeout(()=>{
_this.writeBlueData()
},5000)
_this.bluetoothStatus = true;
},
() => {
_this.bluetoothStatus = false;
}
);
} else {
// 未搜到设备
_this.bluetoothStatus = false;
}
},
() => {
// 蓝牙搜索失败
_this.bluetoothStatus = false;
}
);
});
},
() => {
// 未开启蓝牙
_this.bluetoothStatus = false;
}
);
}
})
},
// 向设备发送数据
writeBlueData() {
//针头=0xAA55 T=0x01 - 0xFF L=0x01 – 0xFF V=0x00 - N
let v ="AT+NAME=设备001";
// let v ="AT+NAME?";
bluetooth.writeData(this.string2buffer(v));
},
// buffer 数据拼接
string2buffer (str) {
// 首先将字符串转换为UTF-8编码的字节
var utf8 = unescape(encodeURIComponent(str));
console.log(utf8.length);
// 创建一个ArrayBuffer来存储字节
var buffer = new ArrayBuffer(utf8.length);
// 创建一个视图来操作ArrayBuffer
var view = new Uint8Array(buffer);
// 将字符串的每个字符的UTF-8编码填充到ArrayBuffer中
for (var i = 0; i < utf8.length; i++) {
view[i] = utf8.charCodeAt(i);
}
// 返回转换后的ArrayBuffer
return buffer;
},