ARTICLE · 1144872
UniApp-Android-Plugins:打通uni-app 硬件通信的多功能百宝箱
一个开源的 Android 原生插件集合,让 uni-app 真正掌控陀螺仪、扫码枪、标签打印机、身份证识别、售货机、Office 预览等硬件能力

一、项目概述 📋
项目地址:https://github.com/luomor/UniApp-Android-Plugins
核心定位:这是一个基于 Java 开发的 uni-app Android 原生插件工程集合,解决了 uni-app 默认无法直接调用 Android 硬件能力(如陀螺仪传感器、USB 扫码枪、USB 标签打印机、身份证读卡器等)的痛点。
适用场景:
二、项目结构 📁
UniApp-Android-Plugins/├── UniPlugin-Android/ # Android 插件工程(插件源码)├── uniplugin_Demo/ # uni-app 插件实例工程(演示用)│ └── nativeplugins/ # 插件存放路径│ ├── Huiy-Card/ # 身份证识别插件│ ├── Huiy-Office/ # Office 文件预览插件│ ├── Huiy-Printer/ # 标签打印机插件│ ├── Huiy-Sale/ # 售货机插件│ ├── Huiy-Scanner/ # 扫码枪插件│ └── Huiy-Sensor/ # 陀螺仪插件├── LICENSE # 许可证文件├── README.md # 项目说明└── TscCommand说明_Android.pdf # 打印机 TSC 指令集说明文档架构设计思路:

三、六大插件详解 🔧
3.1 陀螺仪插件(Huiy-Sensor) 🧭
解决的痛点:uni-app 自带的 uni.onAccelerometerChange 只能获取加速度计数据(含重力),无法获取真正的陀螺仪角速度数据(rad/s),且采样率低(约 10-20Hz)、数据抖动大,无法满足需要精确姿态检测的场景。
适配能力:直接调用 Android Sensor.TYPE_GYROSCOPE,获取三轴角速度原始数据。
API 一览:
registerSensorAFunc(callback) | |
unRegisterSensorFunc() | |
toDegree180Func() | |
toDegree360Func() | |
getSensorInfoFunc() |
返回参数:
{ degree: 45, // 当前方向角度,0~360(0-北 90-东 180-南 270-西) x: 0.12, // X 轴角速度 (rad/s),范围 -π~π y: -0.05, // Y 轴角速度 (rad/s) z: 0.08 // Z 轴角速度 (rad/s)}使用示例:
export default { data() { return { degree: 0, x: 0, y: 0, z: 0 } }, onLoad() { // 引入原生模块 const sensorModule = uni.requireNativePlugin("Huiy-SensorModule") // 注册陀螺仪监听 sensorModule.registerSensorAFunc((ret) => { this.degree = ret.degree this.x = ret.x this.y = ret.y this.z = ret.z }) }, onUnload() { // 页面卸载时取消注册,避免内存泄漏 const sensorModule = uni.requireNativePlugin("Huiy-SensorModule") sensorModule.unRegisterSensorFunc() }}3.2 扫码枪插件(Huiy-Scanner) 🔫
解决的痛点:uni-app 内置的 uni.scanCode 只能调用系统相机扫码(需要打开相机界面),无法实现后台静默扫码(无需相机界面、无需输入框焦点)。工业 PDA 和 USB 扫码枪是仓储、零售场景的核心输入设备,必须通过原生 SDK 对接。
硬件适配:
架构亮点:采用 globalEvent 事件总线模式,扫码结果通过全局事件回调,无需聚焦输入框,真正实现"后台静默扫码"。
API 一览:
initScannerAFunc() | |
connectScannerAFunc() | |
disconnectScannerAFunc() | |
globalEvent.addEventListener('scannerEvent', callback) |
回调数据:
{ scannerId: "device_001", // 扫码枪设备 ID type: 1, // 消息类型 msg: "success", // 消息内容 barcode: "6901234567890", // 扫码内容 barType: "EAN13" // 条码类型(QR_CODE / EAN13 / CODE128 等)}使用示例:
export default { onLoad() { const scannerModule = uni.requireNativePlugin("Huiy-ScannerModule") // 1. 初始化扫码枪 scannerModule.initScannerAFunc() // 2. 连接设备 scannerModule.connectScannerAFunc() // 3. 注册全局事件监听 uni.$on('scannerEvent', (e) => { console.log('扫码结果:', e.barcode) console.log('条码类型:', e.barType) // 处理业务逻辑... }) }, onUnload() { const scannerModule = uni.requireNativePlugin("Huiy-ScannerModule") scannerModule.disconnectScannerAFunc() uni.$off('scannerEvent') }}3.3 标签打印机插件(Huiy-Printer) 🏷️
解决的痛点:uni-app 无法直接发送 TSPL/TSC 指令到标签打印机。仓储管理、商品标价、物流面单等场景都需要精确的标签排版打印,必须下沉到 Native 层实现。
硬件适配:
核心 API:
getUsbDevListFunc() | |
connectUsbDevFunc({ name }) | |
printerLabel(json) |
JSON 报文结构:
const labelJson = { // = 标签全局属性 = "direction": 0, // 打印方向:0-不旋转 1-旋转90° 2-旋转180° 3-旋转270° "gap": 20, // 标签间隙(单位:mm) "width": 40, // 标签宽度(mm) "height": 30, // 标签高度(mm) "mirror": 0, // 镜像打印:0-关闭 1-开启 "x": 0, // 起始 X 坐标 "y": 0, // 起始 Y 坐标 // = 打印内容列表 = "printInfoList": [ { // 文本类型:type=1 "type": 1, // 内容类型:1-文本 2-二维码 3-条码 "text": "悠悠奶茶", // 文本内容 "font": "TSS24.BF2", // 字体名称 "x": 60, // X 坐标(dots) "y": 10, // Y 坐标(dots) "height": 100, // 字体高度 "rotation": 0, // 旋转角度 "scaleX": 2, // 水平缩放 "scaleY": 2, // 垂直缩放 "cellWidth": 5, // 单元格宽度 "readable": 0 // 人类可读:0-否 1-是 }, { // 二维码类型:type=2 "type": 2, "text": "barcode1234567", "x": 200, "y": 75, "height": 100, // 二维码大小 "level": "L", // 纠错等级:L/M/Q/H "rotation": 0, "cellWidth": 3, "readable": 0 }, { // 条码类型:type=3 "type": 3, "text": "7654321", "x": 30, "y": 160, "barType": "128", // 条码类型:128/39/EAN13 等 "height": 50, // 条码高度 "cellWidth": 5, // 条码宽度 "rotation": 0, "scaleX": 0, "scaleY": 0, "readable": 1 // 显示可读文本 } ]}使用示例:
export default { methods: { // 获取设备列表 getDeviceList() { const printerModule = uni.requireNativePlugin("Huiy-PrinterModule") const ret = printerModule.getUsbDevListFunc() console.log('USB 设备列表:', ret) }, // 连接打印机 connectPrinter() { const printerModule = uni.requireNativePlugin("Huiy-PrinterModule") const ret = printerModule.connectUsbDevFunc({ 'name': 'Gainscha_GP-1324D' }) console.log('连接结果:', ret) }, // 打印标签 printLabel() { const printerModule = uni.requireNativePlugin("Huiy-PrinterModule") const ret = printerModule.printerLabel(labelJson) if (ret.code === 0) { uni.showToast({ title: '打印成功' }) } else { uni.showToast({ title: '打印失败: ' + ret.msg, icon: 'none' }) } } }}3.4 身份证识别插件(Huiy-Card) 🆔
解决的痛点:uni-app 无法通过 JS 直接读取身份证读卡器硬件。政务大厅、银行开户、酒店入住等场景需要读取实体身份证芯片信息(姓名、身份证号、住址、头像等),必须通过原生 SDK 对接。
技术路径:基于百度 OCR / 华视读卡器等 SDK 封装,通过 USB 或蓝牙连接身份证阅读器,读取身份证芯片数据。
⚠️ 具体 API 参数需参考项目源码及百度 OCR SDK 授权配置。使用时需注意:
• Android 6.0+ 需要动态申请存储权限 • 百度 OCR 需要申请 License 授权文件 • 头像数据以 Base64 格式返回,可直接用于 <image>标签展示
3.5 售货机插件(Huiy-Sale) 🤖
解决的痛点:自助售货机需要精确控制货道电机、检测货物掉落、处理支付回调等硬件级操作。uni-app 的 JS 层无法直接操作 GPIO、串口等硬件接口。
技术路径:通过 Android 原生串口通信(UART/Serial Port)控制售货机主板,实现货道选择、电机驱动、掉落检测、状态回传等功能。
⚠️ 该插件与具体售货机硬件方案强绑定,集成时需根据实际硬件协议进行适配。建议联系售货机厂商获取通信协议文档。
3.6 Office 文件预览插件(Huiy-Office) 📄
解决的痛点:Android 端 uni-app 无法直接预览 Word/Excel/PPT 文件。虽然 DCloud 插件市场有基于 TBS 的方案,但本项目提供了另一种集成思路。
技术方案:基于腾讯浏览服务(TBS) 内核实现 Office 文档预览,需要联网下载 TBS 内核。
核心特性:
.docx、.xlsx、.pptx、.pdf 等格式 📦width / height 控制大小 📐组件使用:
<template> <view> <officeFrame ref="officeView" officeUrl="/storage/emulated/0/excel001.xlsx" @onInit="onInit" @click="officeClick" /> </view></template><script>export default { methods: { onInit(e) { const { type, msg, progress, isSuccess } = e.detail // type: 1-内核下载中 2-内核下载完成 3-内核安装完成 4-控件初始化完成 console.log(`状态: ${msg}, 进度: ${progress}%, 成功: ${isSuccess}`) }, // 加载 Android 本地文件 loadLocalFile() { this.$refs.officeView.loadFile('/storage/emulated/0/document.docx') } }}</script>四、集成指南 📦
4.1 环境要求
4.2 集成步骤
Step 1:拷贝插件到项目
将 uniplugin_Demo/nativeplugins/ 下的对应插件文件夹拷贝到你的 uni-app 项目的 nativeplugins/ 目录下Step 2:配置 manifest.json
{ "app-plus": { "plugins": { "Huiy-Sensor": {}, "Huiy-Scanner": {}, "Huiy-Printer": {}, "Huiy-Card": {}, "Huiy-Office": {}, "Huiy-Sale": {} } }}Step 3:编译原生插件
# 使用 Android Studio 打开 UniPlugin-Android 工程# 编译生成 .aar 文件# 将 .aar 放入对应插件目录的 android/ 文件夹下Step 4:在页面中调用
const module = uni.requireNativePlugin("Huiy-XXXModule")module.xxxMethod(params, callback)4.3 权限配置
在 manifest.json 中添加必要权限:
{ "app-plus": { "distribute": { "android": { "permissions": [ "<uses-permission android:name=\"android.permission.CAMERA\" />", "<uses-permission android:name=\"android.permission.USB_PERMISSION\" />", "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />", "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />", "<uses-permission android:name=\"android.permission.BLUETOOTH\" />", "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" />", "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />" ] } } }}五、方案对比:为什么选择原生插件? 🆚

核心优势:
uni.requireNativePlugin 统一调用,代码风格一致 🔌六、注意事项与最佳实践 ⚠️
6.1 开发注意事项
| 离线打包 | |
| 真机调试 | |
| 资源释放 | onUnload 时必须取消注册/断开连接,避免内存泄漏 |
| USB 权限 | |
| 厂商 SDK |
6.2 选型建议

6.3 扩展建议
本项目的架构设计非常值得借鉴 —— 将硬件 SDK 封装为 uni-app 原生插件的模式可以复用到任何硬件设备。如果你需要对接其他品牌的扫码枪(如霍尼韦尔 Honeywell)、打印机(如汉印、芯烨)或读卡器,只需:
UniPlugin-Android 工程中新建 Module 🔧WXModule,通过 @JSMethod 暴露方法 📝nativeplugins/ 对应目录 🏗️uni.requireNativePlugin 调用 🚀七、总结 🎯
UniApp-Android-Plugins 虽然 Star 数不多,但含金量极高 —— 它解决的是 uni-app 生态中最硬核的问题:如何让一套 Vue 代码真正驾驭 Android 硬件。
对于从事工业 PDA、智能零售、自助终端、政务设备开发的团队来说,这个项目提供了一套经过验证的硬件集成范式:
uni-app 负责 UI 和业务逻辑,原生插件负责硬件通信,两者通过
uni.requireNativePlugin桥接。
这种模式既保留了 uni-app "一套代码多端运行"的跨平台优势,又不牺牲对硬件的精确控制力,是真正意义上的 "跨平台 + 原生能力"双剑合璧。 🔥