Files
qhmes/JeecgUniapp-master/docs/DT50扫描识别-广播参数与接入说明.md

137 lines
5.6 KiB
Markdown
Raw Normal View History

2026-07-20 17:31:54 +08:00
# DT50 扫描识别 —— 广播参数与接入说明
> 面向 APP「协作」页「扫描识别」功能。
> 设备:优博讯 UROVO **DT50**Android 11
> 参数来源:**设备实测 adb logcat 抓真实扫码** + **优博讯官方 ScanManager 文档** + **DCloud UniApp 官方示例** 三方交叉验证。
> 记录日期2026-07-20。
---
## 一、核心参数(最重要)
| 项目 | 值 | 说明 |
|---|---|---|
| 输出方式 | **Intent / 广播** | 设备当前**已是此模式**,无需在设置页切换 |
| 广播 Action | `android.intent.ACTION_DECODE_DATA` | 实测 + 官方一致 |
| 条码文本String | `barcode_string` | 官方常量 `BARCODE_STRING_TAG`**首选** |
| 原始字节byte[] | `barcode` | 官方常量 `DECODE_DATA_TAG`,兜底用 |
| 长度int | `length` | 官方常量 `BARCODE_LENGTH_TAG` |
| 码制int/String | `barcodeType` | 官方常量 `BARCODE_TYPE_TAG`,实测读出 `Code128` |
| 扫描键 keycode | `523` | KEYCODE_SCAN机身侧键 |
## 二、设备侧验证结论
- **硬件**:成像头正常,成功解出 Code128 条码 ✅
- **触发**:侧键 keycode = 523按下发 `ACTION_KEYCODE_SCAN_PRESSED`
- **广播**:成功解码时实测发出 `android.intent.ACTION_DECODE_DATA (has extras)` 并被接收 ✅
- **模式**:当前即广播输出(非键盘输出),**直接 registerReceiver 即可**
- **无需**:原生 `.aar` 插件 / 自定义基座 / USB 驱动 / 完整 AndroidStudio 套壳;标准基座即可
相关系统组件(备查):
- 扫描设置 App`com.ubx.barcodescanner.tool`
- 扫描服务:`com.ubx.uscanner`
- DataWedge 式配置:`com.ubx.datawedge`
## 三、UniApp 监听代码(标准基座,无需插件)
```js
let scanReceiver = null;
/** 开始监听 DT50 扫描广播 */
function startScanListener(onBarcode) {
const main = plus.android.runtimeMainActivity();
const IntentFilter = plus.android.importClass('android.content.IntentFilter');
const filter = new IntentFilter();
filter.addAction('android.intent.ACTION_DECODE_DATA'); // DT50 广播 Action
scanReceiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function (context, intent) {
plus.android.importClass(intent);
// 首选直接取字符串
let code = intent.getStringExtra('barcode_string');
// 兜底:部分场景用字节数组
if (!code) {
const bytes = intent.getByteArrayExtra('barcode');
if (bytes) code = plus.android.newObject('java.lang.String', bytes);
}
const type = intent.getStringExtra('barcodeType'); // 码制,可选
if (code) onBarcode(code, type);
}
});
main.registerReceiver(scanReceiver, filter);
}
/** 停止监听(务必在页面卸载时调用,避免重复注册 / 内存泄漏) */
function stopScanListener() {
if (scanReceiver) {
plus.android.runtimeMainActivity().unregisterReceiver(scanReceiver);
scanReceiver = null;
}
}
```
页面接入:
```js
onLoad() {
startScanListener((code, type) => {
this.barcode = code;
// TODO: 调 MES 后端接口 / 查料
});
},
onUnload() {
stopScanListener();
}
```
> 注意:仅 Appplus 环境下可用H5/小程序无 `plus`,接入时需做平台判断(`#ifdef APP-PLUS`)。
## 四、故障排查
| 现象 | 原因 / 处理 |
|---|---|
| 收不到广播 | 确认扫描设置里输出为「Intent/广播」而非「键盘/输入法」;确认 Action 拼写 |
| 扫描后文本框被输入内容 | 键盘输出模式也开了,去扫描设置关掉键盘输出 |
| `barcode_string` 为空 | 用兜底的 `barcode`(byte[]) 转 String |
| 一直解码失败(红光有但不出码) | 距离 15~20cm红光完整压住条码拿稳 1~2 秒;避免手机屏幕反光码 |
## 五、参考
- 优博讯官方 ScanManager 文档https://en.urovo.com/developer/android/device/ScanManager.html
- DCloud UniApp 监听优博讯扫码广播含示例https://ask.dcloud.net.cn/article/36468
## 六、本仓库接入位置2026-07-20
| 项 | 位置 |
|---|---|
| 菜单入口 | `src/common/work.ts` → 其他服务「合同」后「扫描识别」 |
| 页面 | `src/pages/scanIdentify/scanIdentify.vue` |
| 广播工具 | `src/utils/dt50Scan.ts` |
| 行为 | 仅广播展示条码/码制/时间,不调后端、不弹输入法 |
| 生命周期 | `onShow` 注册 / `onHide`+`onUnload` 注销;同码防抖 |
## 七、键盘输出 vs 广播输出
| | 键盘输出Keyboard / 楔入) | 广播输出Intent / Broadcast |
|---|---|---|
| 原理 | 把条码当成「敲键盘」打进当前焦点输入框 | 系统发广播App 用 `registerReceiver` 收 |
| App 是否要抢焦点 | 要,通常还会弹出软键盘 | **不需要**输入框焦点 |
| 适合场景 | 记事本、任意输入框快速验证 | 业务页稳定取码、拿码制等扩展字段 |
| 本页策略 | 已关闭楔入,避免弹输入法 | **本页只走广播** |
设备设置建议:扫描设置 → 关闭「键盘输出」开启「Intent/广播输出」。
本页进入时会主动 `hideKeyboard`,不自动聚焦任何输入框。
## 附:参数是如何抓到的(可复现)
```bash
# adb 路径(本机 Android SDK
ADB="C:/Users/hp/AppData/Local/Android/Sdk/platform-tools/adb.exe"
$ADB devices -l # 确认 DT50 已连USB 调试)
$ADB logcat -c # 清空日志缓冲
$ADB shell "timeout 40 logcat -v threadtime '*:V'" > scan.log # 抓 40s
# 抓取期间用 DT50 侧键扫几次条码,然后:
grep -E "ACTION_DECODE_DATA|barcodeType|DECODER" scan.log
```