123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /**
- * @export
- * @param {string} name 微信api的名称 ,如 uniAsyncPromise("getSystemInfo",options)
- * @param {object} options 除了success 和 fail 的其他参数
- * @returns
- */
- export function uniAsyncPromise(name, options) {
- return new Promise((resolve, reject) => {
- uni[name]({
- ...(options || {}),
- // ...options,
- success: (res) => {
- resolve(res);
- },
- fail: (err) => {
- reject(err);
- }
- });
- });
- }
- //微信小程序向蓝牙打印机发送数据进行打印的坑:
- //小程序api向蓝牙打印机发送数据打印,发送的任何内容都应该要转成二进制数据,而且蓝牙打印的文本编码是GBK的,发送中文需转成GBK编码再转成二进制数据发送
- //发送打印机指令也要转成二进制数据发送
- //蓝牙打印机一次接收的二级制数据有限制,不同的系统不同的蓝牙设备限制可能不同,微信建议一次20个字节,需做递归分包发送
- //发送完要打印的内容后,一定要发送一个打印的指令才能顺利打印 (有些指令就不需要)
- //一、初始化蓝牙、开始检索蓝牙设备
- // { allowDuplicatesKey: true, interval: 500}
- export function openBlue() {
- return uniAsyncPromise('openBluetoothAdapter')
- }
- export function startBluetoothDevicesDiscovery(option) {
- console.log('开始蓝牙扫描');
- uniAsyncPromise('startBluetoothDevicesDiscovery', option).then((res) => {
- console.log('正在搜寻蓝牙设备', res);
- });
- }
- export function getConnectedBluetoothDevices(option) {
- console.log('开始获取已连接设备');
- return uniAsyncPromise('getConnectedBluetoothDevices', option)
- }
- //二、
- /**
- *
- *
- * @export
- * @param {function} getDevices uni.getBluetoothDevices的监听回调函数
- */
- export function onfindBlueDevices(getDevices) {
- //监听寻找到新设备的事件
- uni.onBluetoothDeviceFound((devices)=>{
- //获取在蓝牙模块生效期间所有已发现的蓝牙设备
- uniAsyncPromise('getBluetoothDevices').then((res) => {
- getDevices && getDevices(res.devices);
- });
- });
- }
- /**
- * @export
- * @param {function} stopBlueDevicesDiscovery 关闭蓝牙扫描
- */
- export function stopBlueDevicesDiscovery() {
- //监听寻找到新设备的事件
- console.log('停止蓝牙扫描');
- return uniAsyncPromise('stopBluetoothDevicesDiscovery').then((res) => {
- console.log('停止搜寻蓝牙设备', res);
- });
- }
- //三、连接蓝牙设备
- /**
- * @export
- * @param {function} createBLEConnection
- * @param {number} deviceId 蓝牙设备id
- */
- export function createBLEConnection(deviceId, sucess, fail) {
- //连接蓝牙设备
- console.log('连接蓝牙设备', deviceId);
- uniAsyncPromise("createBLEConnection", {
- deviceId,
- timeout: 10000
- })
- .then(res => {
- //连接成功可选择停止搜索蓝牙
- stopBlueDevicesDiscovery();
- console.log('连接成功');
- sucess && sucess({
- res: res,
- });
- })
- .catch(res => {
- console.log('连接设备异常' + res);
- fail && fail({
- res: res,
- });
- })
- /*.finally(res=>{
- console.log('连接成功');
- sucess && sucess({
- res: res,
- });
- });*/
- }
- export function closeBLEConnection(deviceId) {
- console.log('断开蓝牙设备', deviceId);
- uniAsyncPromise("closeBLEConnection", {
- deviceId
- })
- .then(res => {
- console.log('BLEDisconnect complete', res);
- })
- .catch(res => {
- console.log('断开设备异常' + res);
- })
- /*.finally(res=>{
- console.log('BLEDisconnect complete', res);
- }); */
- }
- //四、连接成功后, 获取蓝牙设备的service服务
- // uniAsyncPromise("getBLEDeviceServices",{deviceId:""}).then(res=>{})
- export function getBLEDeviceServices(deviceId, success, fail) {
- console.log('获取ServiceId', deviceId);
- //加延迟避免取不到service
- setTimeout(()=>{
- uniAsyncPromise("getBLEDeviceServices", {
- deviceId:deviceId
- })
- .then(res => {
- console.log('服务', res);
- success && success({
- serviceId: res.services,
- });
- })
- .catch((res) => {
- //getBLEDeviceServices(deviceId, success, fail);
- console.log('获取ServiceId异常' + res);
- fail && fail({
- res: res,
- });
- });
- },1000)
- }
- //五、获取的service服务可能有多个,递归获取特征值(最后要用的是能读,能写,能监听的那个值的uuid作为特征值id)
- /**
- *
- *
- * @export
- * @param {number} deviceId 蓝牙设备id
- * @param {array} services uniAsyncPromise("getBLEDeviceServices",{deviceId:""}).then(res=>{})获取的res.services
- * @param {function} success 成功取得有用特征值uuid的回调函数
- */
- export function getDeviceCharacteristics(deviceId, services, success, fail) {
- //services = services.slice(0);
- console.log('获取Characteristics', deviceId, services);
- if (services.length) {
- const serviceId = services.shift().uuid;
- console.log('ServceID ', serviceId);
- uniAsyncPromise('getBLEDeviceCharacteristics', {
- deviceId,
- serviceId,
- })
- .then((res) => {
- console.log('getBLEDeviceCharacteristics', deviceId, serviceId, res);
- let finished = false;
- let write = false;
- let notify = false;
- let indicate = false;
- var readId;
- var writeId;
- //有斑马品牌的一款打印机中res.characteristics的所有uuid都是相同的,找所有的properties存在(notify || indicate) && write这种情况就说明这个uuid是可用的(不确保所有的打印机都能用这种方式取得uuid,在主要测试得凯盛诺打印机res.characteristic只有一个uuid,所以也能用这个方式)
- for (var i = 0; i < res.characteristics.length; i++) {
- if (!notify) {
- notify = res.characteristics[i].properties.notify;
- if (notify) readId = res.characteristics[i].uuid;
- }
- if (!indicate) {
- indicate = res.characteristics[i].properties.indicate;
- if (indicate) readId = res.characteristics[i].uuid;
- }
- if (!write) {
- write = res.characteristics[i].properties.write;
- writeId = res.characteristics[i].uuid;
- }
- if ((notify || indicate) && write) {
- /* 获取蓝牙特征值uuid */
- success &&
- success({
- serviceId,
- writeId: writeId,
- readId: readId,
- });
- finished = true;
- break;
- }
- }
- if (!finished) {
- getDeviceCharacteristics(deviceId, services, success, fail);
- }
- })
- .catch((res) => {
- getDeviceCharacteristics(deviceId, services, success, fail);
- });
- } else {
- fail && fail();
- }
- }
- //六、启动notify 蓝牙监听功能 然后使用 uni.onBLECharacteristicValueChange用来监听蓝牙设备传递数据
- /**
- * @export
- * @param {object} options
- * {
- deviceId,//蓝牙设备id
- serviceId,//服务id
- characteristicId,//可用特征值uuid
- }
- * @param {function} onChange 监听蓝牙设备传递数据回调函数
- */
- export function onGetBLECharacteristicValueChange(options, onChange = function() {}) {
- console.log('deviceId ', options.deviceId);
- console.log('serviceId ', options.serviceId);
- console.log('characteristicId ', options.characteristicId);
- uniAsyncPromise('notifyBLECharacteristicValueChange', {
- state: true,
- ...options,
- }).then((res) => {
- console.log('onBLECharacteristicValueChange ');
- uni.onBLECharacteristicValueChange(onChange);
- });
- }
- //七、发送数据(递归分包发送)
- /**
- * @export
- * @param {object} options
- * {
- deviceId,
- serviceId,
- characteristicId,
- value [ArrayBuffer],
- lasterSuccess,
- }
- */
- export function senBlData(deviceId, serviceId, characteristicId,uint8Array,lasterSuccess,lasterError) {
- console.log('************deviceId = [' + deviceId + '] serviceId = [' + serviceId + '] characteristics=[' +characteristicId+ "]")
- var uint8Buf = Array.from(uint8Array);
- function split_array(datas,size){
- var result = {};
- var j = 0
- if(datas.length < size) {
- size = datas.length
- }
- for (var i = 0; i < datas.length; i += size) {
- result[j] = datas.slice(i, i + size)
- j++
- }
- return result
- }
- var sendloop = split_array(uint8Buf, 20);
- console.log(sendloop.length)
- function realWriteData(sendloop, i) {
- var data = sendloop[i]
- if(typeof(data) == "undefined"){
- lasterSuccess()
- return
- }
- //console.log("第【" + i + "】次写数据"+data)
- var buffer = new ArrayBuffer(data.length)
- var dataView = new DataView(buffer)
- for (var j = 0; j < data.length; j++) {
- dataView.setUint8(j, data[j]);
- }
- uni.writeBLECharacteristicValue({
- deviceId,
- serviceId,
- characteristicId,
- value: buffer,
- success(res) {
- console.log('发送成功',i)
- setTimeout(()=>{
- realWriteData(sendloop, i + 1);
- },100)
- },
- fail(e) {
- console.log('发送数据失败',e)
- lasterError(e)
- }
- })
- }
- var i = 0;
- realWriteData(sendloop, i);
- }
- // cpcl 发送数据
- export function sendDataToDevice(options) {
- let byteLength = options.value.byteLength;
- //这里默认一次20个字节发送
- //#ifdef APP-PLUS
- const speed = plus.os.name != 'Android' ? 180 : 20; //20;
- //#endif
- console.log("send data 20");
- console.log(options,byteLength,options.value);
- if (byteLength > 0) {
- uniAsyncPromise('writeBLECharacteristicValue', {
- ...options,
- value: options.value.slice(0, byteLength > speed ? speed : byteLength),
- })
- .then((res) => {
- if (byteLength > speed) {
- setTimeout(()=>{
- sendDataToDevice({
- ...options,
- value: options.value.slice(speed, byteLength),
- });
- },100)
- } else {
- options.lasterSuccess && options.lasterSuccess();
- }
- })
- .catch((res) => {
- console.log(res);
- options.lasterError && options.lasterError(res);
- });
- }
- }
- /**
- * toast显示捕获的蓝牙异常
- */
- export function catchToast(err) {
- const errMsg = {
- 10000: '未初始化蓝牙模块',
- 10001: '蓝牙未打开,请打开蓝牙开关',
- 10002: '没有找到指定设备',
- 10003: '连接失败',
- 10004: '没有找到指定服务',
- 10005: '没有找到指定特征值',
- 10006: '当前连接已断开',
- 10007: '当前特征值不支持此操作',
- 10008: '系统上报异常',
- 10009: '系统版本低于 4.3 不支持BLE',
- 10012: '连接超时,请重试'
- };
- let coode = err.errCode ? err.errCode.toString() : '';
- let msg = errMsg[coode];
- //#ifdef APP-PLUS
- plus.nativeUI.toast(msg || coode, {
- align: 'center',
- verticalAlign: 'center',
- duration:'long'
- });
- //#endif
- }
|