1,首先判断手机是否开启蓝牙和定位,如未开启,提示用户开启。
2,搜索时间设为8秒,如未搜索到,提示用户无可用设备。(一旦开启搜索,则会一直进行搜索,要调用停止搜索事件才会停止)
3,如果搜索到设备,则进行连接,连接成功后停止搜索设备,并将设备连接状态置为true。
4,打印时,如果连接状态为true,直接打印,否则重新搜索及连接。
5,打印时,需要判断设备为安卓还是ios,安卓的最大长度为30,ios的最大长度是200。如果超出,则需要分段打印,打印时需要将字符串转化为16进制。
import { getInfoSync } from '@uni/system-info';
let ZPRINTER_SERVICE_UUID = ''; // Zebra Bluetooth LE Parser Service
let WRITE_TO_ZPRINTER_CHARACTERISTIC_UUID = ''; // Write to printer characteristic
let deviceList = [];
let barcodeValue = '';
let connectedDevice = false;
let timeout = null;
function FunTimeout() {
? timeout = setTimeout(() => {
? ? if (!connectedDevice) {
? ? ? dd.hideLoading();
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: '暂无可用打印机',
? ? ? });
? ? ? stopDiscovery();
? ? }
? }, 8000);
}
function getBarCode() {
? return (
? ? '! 0 200 200 250 1\r\n' +
? ? 'JOURNAL\r\n' +
? ? 'CENTER\r\n' +
? ? '; Annotate bar codes using font 5 size 2\r\n ' +
? ? '; and offset 7 dots from the bar code.\r\n' +
? ? 'BARCODE-TEXT 5 2 7\r\n' +
? ? 'BARCODE 128 2 1 100 0 20 ' +
? ? barcodeValue +
? ? '\r\n' +
? ? 'BARCODE-TEXT OFF\r\n' +
? ? 'PRINT\r\n'
? );
}
// 将字符串转换为十六进制字符串
function strToHex(str) {
? let hex = '';
? for (let i = 0; i < str.length; i++) {
? ? const charCode = str.charCodeAt(i).toString(16);
? ? hex += charCode.length < 2 '0' + charCode : charCode;
? }
? return hex;
}
// 初始化蓝牙接口
function initBluetoothAdapter() {
? return new Promise((resolve, reject) => {
? ? dd.openBluetoothAdapter({
? ? ? success: (res) => {
? ? ? ? const { isSupportBLE } = res;
? ? ? ? if (isSupportBLE) {
? ? ? ? ? resolve(res);
? ? ? ? } else {
? ? ? ? ? dd.hideLoading();
? ? ? ? ? dd.showToast({
? ? ? ? ? ? type: 'fail',
? ? ? ? ? ? content: '暂不支持打印',
? ? ? ? ? });
? ? ? ? ? reject(res);
? ? ? ? }
? ? ? },
? ? ? fail: (res) => {
? ? ? ? dd.hideLoading();
? ? ? ? const { errorMessage } = res;
? ? ? ? dd.showToast({
? ? ? ? ? type: 'fail',
? ? ? ? ? content: errorMessage,
? ? ? ? });
? ? ? ? reject(res);
? ? ? },
? ? ? complete: (res) => {
? ? ? ? console.log('initBluetoothAdapter', res);
? ? ? },
? ? });
? });
}
function initChangeListener() {
? dd.onBluetoothAdapterStateChange({
? ? success: (res) => {
? ? ? console.log('onBluetoothAdapterStateChange-success', res);
? ? ? // ? const { available = false } = res || {};
? ? ? // ? if (available) {
? ? ? // ? ? getDevices();
? ? ? // ? } else {
? ? ? // ? ? dd.showToast({
? ? ? // ? ? ? type: 'fail',
? ? ? // ? ? ? content: '手机蓝牙模块不可用!',
? ? ? // ? ? });
? ? ? // ? }
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('onBluetoothAdapterStateChange-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
? dd.onBluetoothDeviceFound({
? ? allowDuplicatesKey: true,
? ? success: (res) => {
? ? ? const { devices = [] } = res || {};
? ? ? const My_devices = devices.filter((i) => i?.deviceName && i?.deviceName.includes('JJKY')) || [];
? ? ? console.log(
? ? ? ? 'onBluetoothDeviceFound-success',
? ? ? ? connectedDevice,
? ? ? ? devices,
? ? ? ? My_devices,
? ? ? ? My_devices.length && My_devices?.[0].deviceId,
? ? ? );
? ? ? if (My_devices.length && My_devices?.[0].deviceId && !connectedDevice) {
? ? ? ? connectDevice(My_devices?.[0].deviceId);
? ? ? ? deviceList = My_devices;
? ? ? }
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('onBluetoothDeviceFound-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
? dd.onBLEConnectionStateChanged({
? ? success: (res) => {
? ? ? console.log('onBLEConnectionStateChanged-success', connectedDevice, res);
? ? ? const { connected, deviceId } = res || {};
? ? ? if (connected && !connectedDevice) {
? ? ? ? connectedDevice = true;
? ? ? ? stopDiscovery(deviceId);
? ? ? }
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('onBLEConnectionStateChanged-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
}
// 开始搜索设备
function startDiscovery() {
? dd.startBluetoothDevicesDiscovery({
? ? success: (res) => {
? ? ? console.log('startBluetoothDevicesDiscovery-success', res);
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('startBluetoothDevicesDiscovery-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
}
// 停止搜索设备
function stopDiscovery(val) {
? dd.stopBluetoothDevicesDiscovery({
? ? success: (res) => {
? ? ? console.log('stopBluetoothDevicesDiscovery-success', res);
? ? ? val && getBLEDeviceServices(val);
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? ? console.log('stopBluetoothDevicesDiscovery-fail', res);
? ? },
? });
}
// 连接设备
function connectDevice(val) {
? dd.connectBLEDevice({
? ? deviceId: val,
? ? success: (res) => {
? ? ? console.log('connectBLEDevice-success', res);
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('connectBLEDevice-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
}
// 获取服务
function getBLEDeviceServices(val) {
? dd.getBLEDeviceServices({
? ? deviceId: val,
? ? success: (res) => {
? ? ? console.log('getBLEDeviceServices-success', res);
? ? ? const { services = [] } = res || {};
? ? ? ZPRINTER_SERVICE_UUID = services[services.length - 1]?.serviceId || '';
? ? ? getBLEDeviceCharacteristics(val);
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('getBLEDeviceServices-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
}
// 获取特征值
function getBLEDeviceCharacteristics(val) {
? dd.getBLEDeviceCharacteristics({
? ? deviceId: val,
? ? serviceId: ZPRINTER_SERVICE_UUID,
? ? success: (res) => {
? ? ? console.log('getBLEDeviceCharacteristics-success', res);
? ? ? const { characteristics = [] } = res || {};
? ? ? WRITE_TO_ZPRINTER_CHARACTERISTIC_UUID =
? ? ? ? characteristics?.find((i) => i?.properties?.write)?.characteristicId || '';
? ? ? writeStringToPrinter(getBarCode());
? ? },
? ? fail: (res) => {
? ? ? dd.hideLoading();
? ? ? console.log('getBLEDeviceCharacteristics-fail', res);
? ? ? const { errorMessage } = res;
? ? ? dd.showToast({
? ? ? ? type: 'fail',
? ? ? ? content: errorMessage,
? ? ? });
? ? },
? });
}
// 写入值
async function writeStringToPrinter(str) {
? const sysInfo = getInfoSync();
? let maxChunk = 20; // Default is 20 bytes per write to characteristic
? if (sysInfo?.platform?.toLowerCase() === 'ios') {
? ? maxChunk = 300; // 300 bytes per write to characteristic works for iOS
? } else if (sysInfo?.platform?.toLowerCase() === 'android') {
? ? maxChunk = 20; // Adjusting for Android
? }
? if (str.length <= maxChunk) {
? ? writeStrToCharacteristic(str);
? } else {
? ? // Need to partion the string and write one chunk at a time.
? ? let j = 0;
? ? for (let i = 0; i < str.length; i += maxChunk) {
? ? ? let subStr = '';
? ? ? const middleStep = i + maxChunk <= str.length || false;
? ? ? if (middleStep) {
? ? ? ? subStr = str.substring(i, i + maxChunk);
? ? ? } else {
? ? ? ? subStr = str.substring(i, str.length);
? ? ? }
? ? ? setTimeout(() => writeStrToCharacteristic(subStr, middleStep), 250 * j); // Adjust the delay if needed
? ? ? j++;
? ? }
? }
}
function writeStrToCharacteristic(strData, middleStep) {
? console.log(
? ? middleStep,
? ? strData,
? ? strToHex(strData),
? ? deviceList,
? ? deviceList[0].deviceId,
? ? barcodeValue,
? ? 'writeStrToCharacteristic',
? );
? dd.writeBLECharacteristicValue({
? ? deviceId: deviceList[0].deviceId,
? ? serviceId: ZPRINTER_SERVICE_UUID,
? ? characteristicId: WRITE_TO_ZPRINTER_CHARACTERISTIC_UUID,
? ? // value: buf2hex(buffer),
? ? value: strToHex(strData),
? ? success(res) {
? ? ? console.log('ssi - success to send ZPL to printer:', res);
? ? ? !middleStep &&
? ? ? ? dd.showToast({
? ? ? ? ? type: 'success',
? ? ? ? ? content: '打印成功',
? ? ? ? });
? ? },
? ? fail(res) {
? ? ? console.log('ssi - Failed to send ZPL to printer:', res);
? ? ? const { errorMessage } = res;
? ? ? !middleStep &&
? ? ? ? dd.showToast({
? ? ? ? ? type: 'fail',
? ? ? ? ? content: errorMessage,
? ? ? ? });
? ? },
? ? complete: (res) => {
? ? ? console.log('[write res==>]', res);
? ? ? dd.hideLoading();
? ? },
? });
}
async function getBluetoothCode(val) {
? if (val) {
? ? dd.getLocation({
? ? ? success() {
? ? ? ? dd.showLoading({
? ? ? ? ? content: '打印中...',
? ? ? ? });
? ? ? ? barcodeValue = val;
? ? ? ? async function init() {
? ? ? ? ? await initBluetoothAdapter();
? ? ? ? ? await initChangeListener();
? ? ? ? ? startDiscovery();
? ? ? ? ? FunTimeout();
? ? ? ? }
? ? ? ? if (connectedDevice) {
? ? ? ? ? // 已连接
? ? ? ? ? writeStringToPrinter(getBarCode());
? ? ? ? } else {
? ? ? ? ? // 未连接
? ? ? ? ? init();
? ? ? ? }
? ? ? },
? ? ? fail() {
? ? ? ? dd.showToast({
? ? ? ? ? type: 'fail',
? ? ? ? ? content: '位置权限未开启!请给钉钉开启定位权限',
? ? ? ? });
? ? ? },
? ? });
? } else {
? ? dd.showToast({
? ? ? type: 'fail',
? ? ? content: '无数据打印',
? ? });
? }
}
function closeBluetooth() {
? // ? dd.disconnectBLEDevice({
? // ? ? deviceId: deviceList[0].deviceId,
? // ? });
? // ? dd.closeBluetoothAdapter();
? ZPRINTER_SERVICE_UUID = '';
? WRITE_TO_ZPRINTER_CHARACTERISTIC_UUID = '';
? deviceList = [];
? connectedDevice = false;
? barcodeValue = '';
? clearTimeout(timeout);
}
export { connectedDevice, getBluetoothCode, closeBluetooth };