更新记录
1.0.0(2026-10-14) 下载此版本
- 首次发布
- 提供商米内置扫码头、内置打印机、设备序列号适配
- 依赖 pro-device-core
平台兼容性
uni-app(5.06)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | - | √ | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
pro-device-adp-sunmi — 商米硬件适配层
商米(Sunmi)设备硬件适配层 UTS 插件,封装三类原生能力:
| 能力 | 说明 |
|---|---|
| 设备序列号 | 读取商米设备 SN |
| 内置扫码头 | 注册/注销红外扫码广播回调 |
| 内置打印机 | 连接、检查、原始打印原语(供业务层组合标签) |
依赖:
pro-device-core、pro-device-print(仅类型依赖)
平台:APP-PLUS(Android,minSdkVersion 21)
AAR:printerx-1.0.17.aar(Sunmi PrinterX SDK)
架构定位
pro-device-adp-sunmi (UTS 原生层)
↓ 被项目层 import
src/devices/scanner/sunmi.ts → SunmiScanner
src/devices/terminal/sunmi.ts → SunmiTerminal
src/devices/printer/sunmi/built-in.ts → SunmiBuiltInPrinter (SDKPrinterBase<LineDocument>)
↓
src/devices/printer/documents/ → 业务版式(按 PrintJob;商米用 LineDocument)
本插件是原生能力提供层,不包含业务逻辑。业务标签实现对应画布接口,放在 src/devices/printer/documents/。
目录结构
pro-device-adp-sunmi/
utssdk/
interface.uts — 公共 Options 类型
unierror.uts — UniErrorSubject / MyApiFailImpl
app-android/
AndroidManifest.xml — 声明 Sunmi 打印机 AIDL Service 查询(Android 11+)
config.json — minSdkVersion: 21
index.uts — 统一入口,export * 全部公共函数
device/
sn.uts — getDeviceSN()
printer/
built-in.uts — BuiltInPrinter 单例 + 生命周期 + 打印原语
scancode/
infrared.uts — InfraredScanCode BroadcastReceiver 单例
interface.uts — ScanResult / InfraredScanCodeOptions 类型
libs/
printerx-1.0.17.aar
API
设备序列号
import { getDeviceSN } from '@/uni_modules/pro-device-adp-sunmi'
// 读取商米设备 SN(通过 SystemProperties / Build 反射)
// 非商米设备返回空字符串
const sn = getDeviceSN() // 例:'SM-2026XXXXXX'
内置扫码头
registerInfraredScanCode(options)
注册红外扫码广播回调。每次扫码触发 onData。
import {
registerInfraredScanCode,
unRegisterInfraredScanCode,
} from '@/uni_modules/pro-device-adp-sunmi'
// ── 注册 ──────────────────────────────────────────────────────
// #ifdef APP-PLUS
registerInfraredScanCode({
onData: (result) => {
console.log('扫码结果:', result.data) // 条码/二维码内容字符串
console.log('原始字节:', result.sourceByte) // 十六进制字符串
},
success: () => console.log('扫码头注册成功'),
fail: (err) => console.error('注册失败', err.errMsg),
})
// #endif
// ── 注销 ──────────────────────────────────────────────────────
// #ifdef APP-PLUS
unRegisterInfraredScanCode({
success: () => console.log('扫码头已注销'),
})
// #endif
回调类型:
type ScanResult = {
data : string // 扫码内容(条码/二维码文本)
sourceByte : string // 原始字节(大写十六进制字符串)
}
onData在 Android 主线程回调,避免在回调中执行耗时操作。
内置打印机
生命周期
import {
initPrinter,
checkPrinter,
destroyPrinter,
printerBeginLabel,
printerAddLine,
printerAddLineCenter,
printerAddQrCode,
printerAddAutoOut,
printerCommitPrint,
} from '@/uni_modules/pro-device-adp-sunmi'
| 函数 | 说明 |
|---|---|
initPrinter(options) |
连接打印机,获取 PrinterX SDK 实例 |
checkPrinter(options) |
检查打印机就绪状态(不重连) |
destroyPrinter(options) |
释放打印机资源 |
// ── 初始化 ──────────────────────────────────────────────────
// #ifdef APP-PLUS
await new Promise<void>((resolve, reject) =>
initPrinter({ success: resolve, fail: (e) => reject(e.errMsg) })
)
// #endif
// ── 打印前检查 ────────────────────────────────────────────────
await new Promise<void>((resolve, reject) =>
checkPrinter({ success: resolve, fail: (e) => reject(e.errMsg) })
)
// ── 释放资源(页面 onUnmounted) ──────────────────────────────
destroyPrinter({ success: () => {}, fail: () => {} })
原始打印原语
重要: printerBeginLabel() 到 printerCommitPrint() 之间的所有调用必须在同一个 JS 微任务中同步顺序执行,不能跨 await 分散(PrinterX 事务模型限制)。
// ✅ 正确:全部同步执行后再 await commit
printerBeginLabel()
printerAddLineCenter('危险废物转运凭证')
printerAddQrCode('HW08-2026-001', 150, 150)
printerAddLineCenter('HW08-2026-001')
printerAddLine('废物类型:废矿物油(HW08)')
printerAddLine('重量:3.2 KG')
printerAddLine('收集人:张三')
printerAddLine('日期:2026-05-12')
printerAddAutoOut()
await new Promise<void>((resolve, reject) =>
printerCommitPrint({ success: resolve, fail: (e) => reject(e.errMsg) })
)
// ❌ 错误:中间有 await,会导致事务断裂
printerBeginLabel()
printerAddLine('第一行')
await somethingAsync() // ← 禁止
printerAddLine('第二行')
完整打印流程示例
// src/devices/printer/sunmi/built-in.ts 的 _sdkPrint() 实现参考
async function printLabel(doc: LineDocument): Promise<void> {
// 1. 检查打印机状态
await new Promise<void>((resolve, reject) =>
checkPrinter({ success: resolve, fail: (e) => reject(new Error(e.errMsg)) })
)
// 2. 同步执行打印事务
const canvas = new SunmiPrinterCanvas() // 实现 LineCanvas,缓存调用
doc.render(canvas) // 业务层填充内容
printerBeginLabel()
for (const op of canvas.operations) op() // 回放所有 printerAdd* 调用
printerAddAutoOut()
// 3. 提交打印
await new Promise<void>((resolve, reject) =>
printerCommitPrint({ success: resolve, fail: (e) => reject(new Error(e.errMsg)) })
)
}
在项目中使用
商米设备能力通过 app-device Store 统一管理,通常无需在业务组件中直接调用本包。
检查当前设备是否为商米终端
import { detectTerminalConfig } from '@/devices'
const config = detectTerminalConfig()
// config 非 null 且 config.brand === 'sunmi' → 商米终端
if (config?.brand === 'sunmi') {
console.log('当前为商米设备,内置外设可用')
}
通过 Store 获取内置打印机
内置商米打印机实现 IPrintable<LineDocument> + IPrintJobSupport。
业务标签须先声明对应 PrintJob 并构造 LineDocument;危废预印标签不属于商米 Job。
import { useAppDeviceStore } from '@/plugins/store/app-device'
const appDeviceStore = useAppDeviceStore()
async function printTest() {
const printer = appDeviceStore.printer
if (!printer) {
uni.showToast({ title: '打印机未初始化', icon: 'none' })
return
}
try {
await printer.printTest()
uni.showToast({ title: '打印成功', icon: 'success' })
} catch (e: any) {
uni.showToast({ title: e?.message ?? '打印失败', icon: 'none' })
}
}
通过 Store 获取内置扫码头
import { useAppDeviceStore } from '@/plugins/store/app-device'
const appDeviceStore = useAppDeviceStore()
let unsubScan: (() => void) | null = null
onMounted(() => {
const scannerEntry = appDeviceStore.devices.find(d => d.type === 'scanner')
const scanner = scannerEntry?.device
if (!scanner) return
unsubScan = (scanner as any).onScan?.((code: string) => {
form.value.code = code
uni.showToast({ title: `已扫:${code}`, icon: 'none' })
})
})
onUnmounted(() => unsubScan?.())
注意事项
- 事务模型限制:
printerBeginLabel到printerCommitPrint之间不能有await,所有原语调用必须同步完成。 - Android 11+ 权限:
AndroidManifest.xml中的<queries>声明了woyou.aidlservice.jiuiv5,Android 11+ 必须有此声明才能绑定商米 AIDL 服务。 checkPrinter不重连:只检查连接状态。若返回失败,应重新调用initPrinter。- 主线程回调:
registerInfraredScanCode.onData在 Android 主线程触发,不要在回调中执行网络请求或重度计算。 - 非商米设备防御:在非商米设备上调用任何打印/扫码函数均会触发
fail,务必处理fail回调。
平台支持
| 平台 | 支持 |
|---|---|
| APP-PLUS(Android 5.0+ / minSdk 21) | √ |
| APP-PLUS(iOS) | × |
| 微信/支付宝小程序 | × |
| H5 | × |
原生依赖
| 文件 | 说明 |
|---|---|
utssdk/app-android/libs/printerx-1.0.17.aar |
Sunmi PrinterX SDK,封装商米 AIDL 打印服务 |
此 AAR 已内置在插件目录中,HBuilderX 打包时自动引入,无需额外配置。

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 109
赞赏 0
下载 12681473
赞赏 1956
赞赏
京公网安备:11010802035340号