必须先调用uni.getBluetoothAdapterState检查蓝牙状态,再根据available/discovering决定是否开启或停止搜索;服务与特征值需动态获取并校验,CPCL指令须严格用\r\n换行且避免ZPL语法,每次打印前需checkConnection确保连接有效。

uni.openBluetoothAdapter 必须配合状态检查,否则安卓/iOS 都会静默失败
很多开发者调用 uni.openBluetoothAdapter 后直接开搜设备,结果在 iOS 上无响应、安卓上提示“搜索超时”——根本原因是没确认蓝牙适配器是否真正就绪。
真实场景下,iOS 首次调用需用户授权弹窗,安卓则可能因系统策略返回 available: false 或 discovering: true(已有其他应用在搜)。跳过状态检查等于把连接逻辑交给运气。
- 必须先调用
uni.getBluetoothAdapterState,在success回调里判断res.available和res.discovering - 若
res.discovering为 true,得先调用uni.stopBluetoothDevicesDiscovery再启动新搜索,否则新搜索不触发回调 - iOS 真机首次运行时,
getBluetoothAdapterState可能返回poweredOff: true,此时要引导用户去系统设置手动开启蓝牙,不能只靠uni.openBluetoothAdapter
服务 UUID 和特征值获取是 CPCL 打印失败的最高发环节
设备连上了、uni.createBLEConnection 成功了、控制台也打印出 deviceId,但 uni.writeBLECharacteristicValue 死活发不出去——八成卡在服务/特征值匹配上。
CPCL 打印机(如芝柯 ZJ-5890、精臣 Q1)普遍使用标准串口协议服务 00001101-0000-1000-8000-00805F9B34FB,但部分厂商固件会隐藏该服务,或要求先发现 0000FF00-0000-1000-8000-00805F9B34FB 再跳转。盲目硬编码 UUID 必翻车。
- 务必在
uni.getBLEDeviceServices回调里加判空:if (!res.services || res.services.length === 0),为空就重连,别往下走 - 拿到服务列表后,用
uni.getBLEDeviceCharacteristics查特征值,重点找properties.write === true且properties.notify === false的项(CPCL 是单向写入) - 红米 Note 系列等机型存在服务缓存延迟,建议
createBLEConnection成功后setTimeout800ms 再查服务,否则可能返回空数组
CPCL 指令拼接必须严格换行 + \r\n,少一个字符打印机就拒收
CPCL 不是自由格式文本,它是逐行解析的指令流。"TEXT 24 0 30 50 Hello" 单独一行能打,但拼成 "TEXT 24 0 30 50 Hello" + "BARCODE 128..." 中间没换行,打印机直接忽略第二条。
更隐蔽的是换行符类型:uni-app 在 H5 或小程序环境默认用 \n,但蓝牙底层 socket(尤其 Android 原生层)要求 \r\n。实测某款佳博打印机收到 \n 会吐纸不打印。
- 所有 CPCL 行末必须显式加
+'\r\n',包括首行! 0 200 200 350 1\r\n和末行PRINT\r\n - 避免用模板字符串多行书写,容易混入不可见空格或错误换行;统一用字符串累加 +
\r\n - 指令开头不要加
^XA或! U1——那是 ZPL/TSPL 语法,CPCL 起始是!,不是^
uni.writeBLECharacteristicValue 发送前必须 checkConnection + ensureConnected
用户点“打印”时,设备可能已断连、休眠或被系统回收连接句柄。直接发指令大概率报错 write characteristic fail, error: 100006(安卓)或 write failed: connection is invalid(iOS),但很多人没捕获这个错误,导致 UI 卡住无反馈。
关键不是“能不能发”,而是“当前连接是否还活着”。uni-app 的 BLE 连接状态不会自动同步,得靠缓存 + 主动探测。
- 每次打印前调用自定义函数
checkConnection(),检查uni.getStorageSync('deviceId')是否存在,再调用uni.getConnectedBluetoothDevices确认该设备仍在连接列表中 - 若不在列表中,不要尝试重连(耗时且易阻塞 UI),直接提示“打印机已断开,请重新连接”,并清空缓存的
serviceId和characteristicId - 发送指令后,务必监听
uni.onBLEConnectionStateChanged,设备断连时及时更新 UI 状态,避免用户重复点击



















