更新记录

1.0.0(2026-10-22) 下载此版本

首个版本:

  • 基于 Android 无障碍服务(AccessibilityService.onKeyEvent)实现 USB / 蓝牙 HID 扫码枪全局监听;
  • 无需输入框、无需焦点、不弹软键盘,支持后台回调;
  • 提供 start / stop / onBarcode / offBarcode / isAccessibility / openAccessibilitySettings / isServiceRunning 七个 API;
  • 以回车作为单条码结束符,支持退格容错、1.5 秒无输入自动丢弃缓存、单条最长 512 字符;
  • 停止监听后不再拦截按键,物理键盘恢复系统默认行为;
  • 非 Android 平台自动降级为空实现,保证工程可正常编译。

平台兼容性

uni-app(4.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× √ × × - - - - ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × - × × ×

uni-app x(5.0)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - - -

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × √ √

pos-usb-scan · USB扫码枪监听(Android)

基于 Android 无障碍服务的扫码枪全局监听插件。USB / 蓝牙 HID 扫码枪插上就能用,不需要输入框、不需要光标焦点、不弹软键盘,App 退到后台也能继续扫码。

适用于:收银台扫码、订单核销、仓储盘点、门票/取件码核验等一切「扫一下就要结果」的场景。


一、特性

能力 说明
全局监听 通过无障碍服务拦截硬件按键,页面无输入框、无焦点也能拿到条码
不弹软键盘 软键盘(IME 虚拟按键)不产生硬件 KeyEvent,因此不会互相干扰
后台可用 服务由系统持有,App 切到后台仍持续回调
不抢焦点 与业务输入框并存,不会把焦点从当前输入框抢走
停止即还原 调用 stop() 后不再拦截任何按键,物理键盘恢复系统默认行为
单次扫码聚合 以回车(Enter / 小键盘 Enter)作为一条码的结束符;支持退格容错、超时自动丢弃脏缓存

二、平台支持

平台 支持
Android App(vue / nvue 页面) ✅
iOS App ❌(iOS 无等价机制)
H5 / 小程序 ❌ 会降级为空实现,仅保证编译通过

环境要求

  • HBuilderX 4.25 及以上(插件含 Kotlin 原生混编代码)
  • 安装插件后必须使用自定义基座调试(插件包含 AndroidManifest.xml 与 res 资源,标准基座不含这些内容)
  • Android 4.4 (API 19) 及以上

三、安装

  1. 在插件市场点「导入插件」,HBuilderX 会自动把插件放到项目的 uni_modules/pos-usb-scan 目录;
  2. 制作自定义基座:菜单 运行 → 运行到手机或模拟器 → 制作自定义调试基座;
  3. 运行到 Android 真机,首次使用按下方「授权」步骤开启无障碍服务。

本插件不需要在 manifest.json 里勾选任何模块,也不需要申请任何系统权限。

四、无障碍授权(首次必做)

Android 出于安全考虑,无障碍服务必须由用户手动开启,代码无法自动打开。

流程建议:

  1. 页面加载后调用 isAccessibility() 判断是否已授权;
  2. 未授权时调用 openAccessibilitySettings() 跳转系统设置;
  3. 用户在「设置 → 无障碍 → 已下载的服务(或已安装的服务)」中找到 USB扫码枪监听服务,打开开关;
  4. 返回 App,再次 isAccessibility() 应返回 true,此时 start() 即可正常扫码。

start() 内部也会自动检测一次,未授权时会自动跳转设置页,所以最简用法是「先 onBarcode 再 start」。

五、快速开始

import {
    start,
    stop,
    onBarcode,
    offBarcode,
    isAccessibility,
    openAccessibilitySettings,
    isServiceRunning
} from '@/uni_modules/pos-usb-scan'

export default {
    onLoad() {
        // 1. 先注册回调(回调会持续有效,可多次扫码)
        onBarcode((res) => {
            console.log('条码:', res.barcode, '时间:', res.time)
            // res = { barcode: '6901234567890', time: 1761234567890 }
        })

        // 2. 开始监听(未授权时会自动跳无障碍设置页)
        start()
    },
    onUnload() {
        offBarcode()
        stop()
    }
}

nvue 页面同样可用(插件为纯 API 类型,不涉及 UI 组件)。

六、API

方法 返回值 说明
start() void 开始监听。未开启无障碍授权时会自动跳转设置页
stop() void 停止监听,不再拦截按键(物理键盘恢复默认行为)
onBarcode(callback) void 注册扫码回调,回调参数 { barcode, time }。后注册的会覆盖先注册的
offBarcode() void 移除扫码回调
isAccessibility() boolean 无障碍服务是否已授权
openAccessibilitySettings() void 打开系统「无障碍」设置页
isServiceRunning() boolean 无障碍服务是否已连接(服务进程是否在跑)

回调结构

type UsbScanResult = {
    barcode : string   // 条码内容(不含结尾回车)
    time : number      // 扫码完成时间戳(毫秒)
}

扫码枪设置建议

扫码枪出厂一般已配置「结束符 = 回车」。若你的扫码枪没有回车结尾,请用扫码枪说明书里的设置条码把结束符设置为 CR(回车),否则插件无法判断一条码是否结束。

七、注意事项

  • 国产 ROM 后台限制:小米 / 华为 / OPPO / vivo 等机型需在系统设置里允许本应用「自启动」「后台运行」,否则进程被清理后服务会掉线。
  • 人工键盘也会被识别:扫码枪在系统看来就是硬件键盘,因此外接物理键盘的输入同样会被回调。如需区分,可在业务层用「字符长度 + 输入速度」过滤。
  • 一个应用只允许一个实例:onBarcode 后注册覆盖先注册,避免多处监听导致重复处理。
  • 停止监听再退出页面:若页面退出后仍需扫码,请不要在 onUnload 里调用 stop(),只调用 offBarcode() 即可。

八、常见问题

Q:扫码没有任何反应?

  1. 确认 isAccessibility() 返回 true(系统设置里「USB扫码枪监听服务」已开启);
  2. 确认调用过 start();
  3. 确认扫码枪结束符是回车;
  4. 确认用的是自定义基座,不是标准基座。

Q:开启无障碍后,扫码枪还能在别的输入框里打字吗? 调用 start() 期间,按键会被插件拦截并用于组码,不再进入输入框;调用 stop() 后立即恢复。

Q:iOS 能用吗? 不能,iOS 没有等价的全局按键拦截机制。

九、更新日志

见插件目录下的 changelog.md。

十、许可

MIT

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无需申请运行时权限。功能依赖 Android 无障碍服务,需用户在系统设置中手动开启(服务由系统以 BIND_ACCESSIBILITY_SERVICE 权限绑定,插件不申请其他权限)。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件不收集、不上传任何用户数据。扫码内容仅在设备本地通过回调交给调用方页面,不写入存储、不联网、不含第三方统计 SDK。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

本插件不包含任何广告。

许可协议

MIT协议

暂无用户评论。