1 Star 0 Fork 12

小蜗牛的长征/蓝牙小票打印核心方法

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
devices.js 22.67 KB
一键复制 编辑 原始数据 按行查看 历史
幺月儿 提交于 2022-04-29 12:30 . 自动停止发现设备
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
let Devices = {
//错误码
errorCode: {
err_0: "正常",
err_10000: "未初始化蓝牙适配器",
err_10001: "当前蓝牙适配器不可用",
err_10002: "没有找到指定设备",
err_10003: "连接失败",
err_10004: "没有找到指定服务",
err_10005: "没有找到指定特征",
err_10006: "当前连接已断开",
err_10007: "当前特征不支持此操作",
err_10008: "其余所有系统上报的异常",
err_10009: "Android 系统特有,系统版本低于 4.3 不支持 BLE",
err_10012: "连接超时",
err_10013: "连接deviceId为空或格式不正确",
},
//获取错误码信息
getErrorMessage(error_code){
return Devices.errorCode[error_code] || "已连接|未知";
},
//是否已初始化过
hasStart: false,
//初始化
start(){
if(Devices.hasStart) return;
//监听发现低功耗蓝牙设备时需要做的处理
wx.onBluetoothDeviceFound(res => {
let device = res.devices[0];
if(device.name.toString().length > 0 && device.name.indexOf("未知") === -1){
//处理设备信息
let exists = Devices.deviceIndex(device.deviceId);
if(exists === -1) {
let new_device = {
name: device.name,
deviceId: device.deviceId,
RSSI: device.RSSI
};
Devices.list.push(new_device);
//仅在是真正的设备时,才回调
if(Devices.eventsOnDeviceFound.length > 0){
for(let i=0; i<Devices.eventsOnDeviceFound.length; i++){
if(typeof Devices.eventsOnDeviceFound[i] === "function"){
//执行事件
Devices.eventsOnDeviceFound[i](new_device);
}
}
}
}
}
});
//监听蓝牙模块状态改变
wx.onBluetoothAdapterStateChange(res => {
console.log("adapter change", res);
if(res.discovering !== Devices.discovering){
//Devices.discovering = res.discovering;
if(Devices.eventsOnAdapterStateChange.length > 0){
for(let i=0; i<Devices.eventsOnAdapterStateChange.length; i++){
if(typeof Devices.eventsOnAdapterStateChange[i] === "function"){
//执行事件
Devices.eventsOnAdapterStateChange[i](res);
}
}
}
}
});
//监听设备的连接情况(断开、连接成功)
wx.onBLEConnectionStateChange(res => {
//根据ID去获取
Devices.list.forEach((item, index) => {
if(item.deviceId === res.deviceId){
Devices.list[index].connected = res.connected;
if(Devices.eventsOnConnectionStateChange.length > 0){
for(let i=0; i<Devices.eventsOnConnectionStateChange.length; i++){
if(typeof Devices.eventsOnConnectionStateChange[i] === "function"){
//执行事件
Devices.eventsOnConnectionStateChange[i](res);
}
}
}
}
});
});
//
Devices.hasStart = true;
},
//发现设备时的回调,支持多个事件同时触发
eventsOnDeviceFound: [],
onDeviceFound(callback){
Devices.eventsOnDeviceFound.push(callback);
},
//蓝牙设备状态改变
eventsOnAdapterStateChange: [],
onAdapterStateChange(callback){
Devices.eventsOnAdapterStateChange.push(callback);
},
//连接状态改变
eventsOnConnectionStateChange: [],
onConnectionStateChange(callback){
Devices.eventsOnConnectionStateChange.push(callback);
},
//停止
stop(){
if(Devices.hasStart){
//停止监听
wx.offBluetoothAdapterStateChange();
wx.offBLEConnectionStateChange();
wx.offBluetoothDeviceFound();
Devices.list = [];
Devices.connected_list = [];
if(Devices.discovering){
Devices.stopDiscovery();
}
Devices.discovering = false;
Devices.eventsOnDeviceFound = [];
Devices.eventsOnAdapterStateChange = [];
Devices.eventsOnConnectionStateChange = [];
Devices.hasOpenAdapter = false;
Devices.hasStart = false;
}
},
//已发现的设备列表
list: [],
//已连接设备列表
connected_list: [],
//是否已初始化蓝牙模块
hasOpenAdapter: false,
//初始化蓝牙模块
openAdapter(callback){
wx.openBluetoothAdapter({
mode: "central",
success: res => {
Devices.hasOpenAdapter = res.errMsg.indexOf("ok") > 0;
if(typeof callback === "function") {
callback({
error: 0,
message: res.errMsg.indexOf("ok") === -1 ? res.errMsg : "打开成功"
});
}
},
fail: error => {
if (error.errMsg.indexOf("already opened") > 0) {
Devices.hasOpenAdapter = true;
if (typeof callback === "function") {
callback({
error: 0,
message: "已打开,无需重复执行"
});
}
} else {
Devices.hasOpenAdapter = false;
if (typeof callback === "function") {
callback({
error: 1,
message: "未能初始化蓝牙设备"
});
}
}
}
});
},
//是否正在搜索设备
discovering: false,
//搜索发现设备
discovery(callback){
if(Devices.discovering) return;
if(!Devices.hasOpenAdapter){
Devices.openAdapter(res => {
if(res.error > 0){
if(typeof callback === "function") {
callback(res);
}
}else{
Devices.discovery(callback);
}
});
}else{
wx.startBluetoothDevicesDiscovery({
success: res => {
Devices.discovering = res.isDiscovering;
if(typeof callback === "function") {
callback({
error: 0,
message: "搜索设备中"
});
}
},
fail: err => {
if(err.errMsg.indexOf("already discovering")){
Devices.discovering = true;
if(typeof callback === "function") {
callback({
error: 0,
message: "正在搜索,无需重复执行"
});
}
}else{
Devices.discovering = false;
if(typeof callback === "function") {
callback({
error: err.errCode,
message: err.errMsg
});
}
}
}
});
}
},
//停止搜寻附近的蓝牙外围设备,若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
stopDiscovery(callback){
if(Devices.discovering){
wx.stopBluetoothDevicesDiscovery({
success: res => {
Devices.discovering = false;
if(typeof callback === "function"){
callback({
error: 0,
message: "已停止搜索"
});
}
},
fail: err => {
if(typeof callback === "function") {
callback({
error: 1,
message: err.errMsg
});
}
}
});
}else{
callback({
error: 0,
message: "已停止搜索设备"
});
}
},
//连接设备
connectDevice(deviceId, callback){
let index = Devices.deviceIndex(deviceId);
if(index >= 0){
let device = Devices.list[index];
if(device.connected){
//已连接,查看服务状态
if(device.serviceId == undefined || device.serviceId == null || device.serviceId == ""){
//获取服务
Devices.getService(deviceId, res4 => {
if(res4.error){
if(typeof callback === "function"){ callback(res4); }
}else{
//附加信息
device.serviceId = res4.data.serviceId;
device.isPrimary = res4.data.isPrimary;
device.characteristicId = res4.data.characteristicId;
//更新信息
Devices.list[index] = device;
if(typeof callback === "function"){
callback({
error: 0,
device: device
});
}
}
});
}else if(device.characteristicId == undefined || device.characteristicId == null || device.characteristicId == ""){
//获取服务特征
Devices.getCharacteristic(deviceId, device.serviceId, res3 => {
if(res3.error){
if(typeof callback === "function"){
callback(res3);
}
}else{
device.characteristicId = res3.data.uuid;
Devices.list[index].characteristicId = device.characteristicId;
if(typeof callback === "function"){
callback({
error: 0,
device: device
});
}
}
});
}else{
//该设备已连接,并取得了相应的信息
callback({
error: 0,
device: device
});
}
}else{
//连接,并取得服务
Devices.openAdapter(() => {
wx.createBLEConnection({
deviceId: deviceId,
//超时设置为10秒
timeout: 10000,
//
success: res => {
if(res.errCode > 0){
//有错误
if(typeof callback === "function"){
callback({
error: res.errCode,
message: Devices.getErrorMessage(res.errCode)
});
}
}else{
//同时取得
Devices.getService(deviceId, res2 => {
if(res2.error){
if(typeof callback === "function"){ callback(res2); }
}else{
//附加信息
device.serviceId = res2.data.serviceId;
device.isPrimary = res2.data.isPrimary;
device.characteristicId = res2.data.characteristicId;
//更新信息
Devices.list[index] = device;
if(typeof callback === "function"){
callback({
error: 0,
device: device
});
}
}
});
}
},
fail: err => {
if(typeof callback === "function"){
callback({
error: 1,
message: "未能连接设备"
});
}
}
});
});
}
}
},
disconnect(deviceId){
let device = Devices.getDeviceById(deviceId);
if(device && device.connected){
wx.closeBLEConnection({
deviceId: deviceId,
success: () => {
},
fail: () => {
this.showMessage("无法断开连接");
}
});
}
},
//仅获取全服务特征的服务ID
getService(deviceId, callback){
wx.getBLEDeviceServices({
deviceId: deviceId,
success: res => {
if(res.services){
let hasCallback = false;
for(let i=0; i<res.services.length; i++){
if(hasCallback){
break;
}
let service = res.services[i];
Devices.getCharacteristic(deviceId, service.uuid, res2 => {
if(!res2.error){
//
let characteristic = res2.data || {};
let characteristicId = characteristic.uuid || null;
if(typeof callback === "function" && !hasCallback && characteristicId){
hasCallback = true;
callback({
error: 0,
data: {
serviceId: service.uuid,
isPrimary: service.isPrimary,
characteristicId: characteristicId
}
});
}
}
});
}
}else{
if(typeof callback === "function"){
callback({
error: 1,
message: "未能取得设备服务"
});
}
}
},
fail: err => {
if(typeof callback === "function"){
callback({
error: 1,
message: "无法获取服务"
});
}
}
});
},
//获取服务特征
getCharacteristic(deviceId, serviceId, callback){
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success: res => {
if(res.characteristics){
//只取属性值合适的特征
let characteristics = null;
for(let i = 0; i<res.characteristics.length; i++){
/*
read: boolean,
write: boolean,
notify: boolean,
indicate: boolean,
writeNoResponse: boolean, //不一定有
writeDefault: boolean
*/
let cs = res.characteristics[i];
if(cs.properties.read && cs.properties.write && cs.properties.notify && cs.properties.indicate){
characteristics = cs;
break;
}
}
if(typeof callback === "function"){
callback({
error: 0,
data: characteristics
});
}
}else{
if(typeof callback === "function"){
callback({
error: 1,
message: "未能取得设备的服务特征"
});
}
}
},
fail: err => {
if(typeof callback === "function"){
callback({
error: 1,
message: "无法获取特征"
});
}
}
});
},
//查找设备
deviceIndex(deviceId){
for(let i = 0; i < Devices.list.length; i++){
if(Devices.list[i].deviceId === deviceId){
return i;
}
}
return -1;
},
//根据ID获取设备信息
getDeviceById(deviceId){
let index = Devices.deviceIndex(deviceId);
if(index >= 0){
return Devices.list[index];
}
return null;
},
//设备传输单元最大值
setMTU(deviceId, mtu, callback){
let device = Devices.getDeviceById(deviceId);
if(device){
wx.setBLEMTU({
deviceId: deviceId,
mtu: mtu,
success: res => {
if(typeof callback === "function"){
callback({
error: 0,
mtu: res.mtu
});
}
},
fail: err => {
if(typeof callback === "function"){
callback({
error: 1,
message: "无法协商MTU"
});
}
}
});
}
},
//发送数据
writeCharacteristicValue(deviceId, buffer, mtu, callback){
let device = Devices.getDeviceById(deviceId);
if(device === null){
device = {
connected: false,
deviceId: deviceId,
RSSI: 0,
name: "指定设备"
};
Devices.list.push(device);
}
if(!device.connected){
Devices.connectDevice(deviceId, res => {
if(res.error){
callback({
error: 1,
message: "无法连接设备"
});
}else{
Devices.writeCharacteristicValue(deviceId, buffer, mtu, callback);
}
});
}else if(device.serviceId == null || device.serviceId == undefined || device.serviceId == ""){
Devices.getService(deviceId, res => {
if(res.error){
callback({
error: 1,
message: "未能获取设备服务"
});
}else{
Devices.writeCharacteristicValue(deviceId, buffer, mtu, callback);
}
});
}else if(device.characteristicId == null || device.characteristicId == undefined || device.characteristicId == ""){
Devices.getCharacteristic(deviceId, device.serviceId, res => {
if(res.error){
callback({
error: 1,
message: "未能获取设备服务特征"
});
}else{
if(res.data == null){
callback({
error: 1,
message: "该设备无法使用,不符合打印特征。"
});
}else{
Devices.writeCharacteristicValue(deviceId, buffer, mtu, callback);
}
}
});
}else {
//开始处理
let rows = buffer.byteLength;
let total = mtu;
let pages = Math.ceil(rows / total);
for(let page = 0; page < pages; page++){
//console.log(page, pages);
let offset = page * total;
let end = offset + total;
let _buffer = buffer.slice(offset, end > rows ? rows : end);
wx.writeBLECharacteristicValue({
deviceId: device.deviceId,
serviceId: device.serviceId,
characteristicId: device.characteristicId,
value: _buffer,
success: (res) => {
//发送成功
callback({
error: 0,
pages: pages,
page: page+1
});
//console.log("write success", (page+1) + "/" + pages);
},
fail: (err) => {
callback({
error: 1,
pages: pages,
page: page+1,
message: "未能发送打印数据"
});
console.log("write fail", (page+1) + "/" + pages);
}
})
}
}
}
};
exports.Devices = Devices;
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/xwn/BLETicketPrinter.git
[email protected]:xwn/BLETicketPrinter.git
xwn
BLETicketPrinter
蓝牙小票打印核心方法
master

搜索帮助