更新记录
1.3.0(2026-09-04)
1.3.0(2026-08-29)
新增
scanStyle.cornerStyle新增rounded完整圆角边框和rounded-corner四角圆角边框。- 新增
scanStyle.cornerRadius,单位 dp,范围0 ~ 160,默认20。 - 两种圆角扫描框启用遮罩时,遮罩缺口和扫描线同步按同一圆角路径裁剪。
兼容性
- 保留
corner四角边框与full完整矩形边框的原有绘制和调用方式。 - 圆角半径会自动限制在扫描框短边的一半以内,适配窄条码扫描框。
1.2.0(2026-08-28)
新增
- 新增独立的
scanStyle配置,不再将视觉表现与scanRegion识别区域混合。 - 支持
showMask,可控制扫描框外遮罩的显示与隐藏。 - 支持
showBeam,可控制扫描线的显示与隐藏。 - 支持
borderColor、maskColor、beamColor自定义边框、遮罩和扫描线颜色。 - 支持
beamDuration配置扫描线移动周期,原生层限制为100 ~ 60000毫秒。 - 支持
cornerStyle:corner四角边框、full完整矩形边框。 - README 补充扫描区域、视觉样式、扫码页交互、生命周期回调和错误码说明。
- 新增
9021005 ~ 9021011细化错误码,覆盖相机占用/初始化、相册读取与无条码、非法formats和单次扫码超时。 - 新增可选
scanTimeout,单次扫码可设置1000 ~ 600000毫秒超时;连续扫码不启用超时。
兼容性
- 保持原有
openCodeScan调用方式不变。 - 未传
scanStyle时使用默认样式:绿色边框、半透明黑色遮罩、绿色扫描线、四角边框。 scanStyle仅影响 Android 扫描页绘制,不改变条码识别逻辑。- 同屏多码定格后的绿色点选标记增加呼吸波纹动画,帮助用户快速定位可点击目标。
平台兼容性
uni-app(5.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | - | - | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | √ | × |
mas-code-scan
Android 端扫码 UTS API 插件(非 Vue 组件)。
基于 CameraX + Google ML Kit,支持全格式条码/二维码、多码同屏点选、识别区域过滤、扫描框视觉配置、智能变焦、手势缩放、相册识图、连续扫码、手电筒策略、结果确认和暂停控制。
插件对外只提供 openCodeScan 一个 UTS API。扫码页由原生 Android Activity 提供,识别结果通过 success、fail、complete 回调返回。
支持:Android App(uni-app Vue2/Vue3)。
暂不支持:iOS / 鸿蒙 / H5 / 小程序 / nvue。
依赖原生三方库,必须使用自定义调试基座或正式云打包后才能真机调用。
插件定位与工作流程
mas-code-scan 是一个打开原生 Android 扫码 Activity 的 UTS API 插件,不是 Vue 组件,也不是对 uni.scanCode 的简单包装。一次扫码流程如下:
- 业务页面调用
openCodeScan(options)。 - 插件启动全屏竖屏原生扫码页,并根据参数初始化 CameraX、ML Kit 和界面控件。
- 相机帧交给 ML Kit 识别;如果配置了
scanRegion,实时结果还会经过扫描框中心点过滤。 - 单码按照
resultMode返回;多码进入定格点选;连续模式通过success多次上报。 - Activity 结束后通过
complete收尾;失败场景同时通过fail和complete通知。
能力边界
- 识别引擎:Google ML Kit Barcode Scanning。
- 相机管线:CameraX,使用后置摄像头,预览采用
FILL_CENTER填充显示。 - 图片来源:实时相机帧、系统相册图片。
- 原生页面:全屏、竖屏、无标题栏;关闭、相册、手电筒和连续扫码暂停按钮由插件绘制。
- 生命周期:每次调用创建一个扫码会话;关闭、成功、权限失败、超时或初始化失败后会话结束。
目录
功能一览
| 能力 | 说明 |
|---|---|
| 全格式识别 | QR / EAN / CODE_128 / PDF417 / AZTEC 等 |
| 码制过滤 | formats 只扫指定类型 |
| 扫描区域 | scanRegion 配置扫描框尺寸、位置,并过滤框外条码 |
| 扫描框样式 | scanStyle 配置遮罩、扫描线、边框颜色、动画周期、边框形态和圆角大小 |
| 单码自动返回 | 识别成功后关闭并回调 |
| 多码点选 | 同屏多个码定格,点选其中一个 |
| 智能变焦 | smartZoom:码偏小时自动放大 |
| 手势缩放 | 双指捏合 |
| 手电筒 | 扫码页右下角开关,支持关闭、启动时开启和低照度自动补光 |
| 相册识图 | 页内相册按钮,或 fromAlbum: true |
| 连续扫码 | continuous: true,多次 success,点关闭结束;可显示暂停/继续按钮 |
| 结果处理 | 单次扫码支持立即返回、确认后返回、暂停后选择 |
| 成功震动 | vibrate,可关 |
| 错误码区分 | 权限拒绝 9021002 ≠ 用户取消 9021003 |
| 原生回收 | 页面结束时停止分析、释放相机、关闭 ML Kit Scanner、关闭手电筒并清理临时图片 |
安装
将插件拷贝到业务项目:
你的项目/uni_modules/mas-code-scan/
UTS 插件需 import 后调用,不会 easycom 自动注册组件。
要求:
- HBuilderX ≥ 3.6.8(建议较新版本)
- uni-app Vue2 / Vue3 均可
- 仅 Android;需制作自定义基座
本仓库演示页:/pages/scan/prototype.vue`,用于在 Android 自定义基座中验证插件能力。页面包含:
- 智能变焦、成功震动、手电筒策略、结果处理模式和连续扫码暂停按钮。
- 扫码页标题、扫描引导语、成功提示语、无结果提示语自定义。
- 连续扫码成功提示停留时长、单次扫码超时配置。
- 二维码正方形框、横向条码框和全屏识别三种识别区域预设;横向条码框支持上/中/下位置、自定义上下微调和三档高度。
- 扫描框遮罩、扫描线、边框颜色、遮罩颜色、扫描线颜色、扫描线周期、四种边框形态和圆角半径配置。
- 二维码、CODE 128、EAN-13 码制筛选,相册识图、单次扫码、连续扫码和本地结果列表。
演示页的“最近结果”仅保存在当前页面内,用于展示回调结果,不会提交业务接口。
制作自定义基座(必做)
插件依赖:
androidx.camera:*1.4.1com.google.mlkit:barcode-scanning17.3.0
标准基座不含上述库,不制作自定义基座会调用失败 / 编译不过。
步骤
- HBuilderX 菜单:运行 → 运行到手机或模拟器 → 制作自定义调试基座
- 选择当前项目,填写 Android 包名、证书(可用公共测试证书)
- 云打包,等待完成并安装到手机
- 之后每次运行选择 「自定义调试基座」,再打开演示页或业务页调试扫码
正式发版:使用 云打包 / 本地打包 生成安装包即可(打包流程会带上 UTS 原生依赖)。
快速上手
1. uni-app(Vue3 <script setup>)
<template>
<view>
<button type="primary" @click="doScan">扫码</button>
<text>{{ tip }}</text>
</view>
</template>
<script setup>
import { ref } from 'vue'
import { openCodeScan } from '@/uni_modules/mas-code-scan'
const tip = ref('')
const doScan = () => {
openCodeScan({
success: (res) => {
tip.value = res.content + ' / ' + res.format
},
fail: (err) => {
tip.value = err.errMsg + '(' + err.errCode + ')'
}
})
}
</script>
2. uni-app(Options API)
import { openCodeScan } from '@/uni_modules/mas-code-scan'
export default {
methods: {
doScan() {
openCodeScan({
success: (res) => {
console.log(res.content, res.format, res.fromAlbum)
},
fail: (err) => {
console.log(err.errCode, err.errMsg)
},
complete: () => {
console.log('扫码流程结束')
}
})
}
}
}
3. 最少参数
import { openCodeScan } from '@/uni_modules/mas-code-scan'
openCodeScan({
success: (res) => console.log(res.content)
})
进阶用法
自定义扫码页文案
以下参数只影响原生扫码页显示文字,不影响识别逻辑:
openCodeScan({
title: '扫描商品码',
hint: '请将商品条码放入框内',
successHint: '识别成功',
emptyHint: '图片中没有商品条码',
success: (res) => console.log(res.content)
})
title:顶部标题,默认扫一扫。hint:扫描框下方引导语,默认请将条码放入扫描框内。successHint:连续扫码成功提示层标题,也用于部分原生提示,默认扫码成功。emptyHint:相册图片未识别到条码时的提示,默认未识别到有效条码。- 空字符串或全空格会回退到默认文案;原生层会去除首尾空格。
只扫二维码
openCodeScan({
formats: ['QR_CODE'],
success: (res) => console.log(res.content)
})
手电筒和结果处理
openCodeScan({
torch: 'auto', // 'off' | 'on' | 'auto'
resultMode: 'confirm', // 'immediate' | 'confirm' | 'pause'
success: (res) => console.log(res.content)
})
confirm 会弹出结果确认框;pause 会暂停识别并提供“继续扫描/确认”操作。两种模式下,点击确认才会结束并触发 success、complete;点击重新扫描或继续扫描会恢复相机识别,不会触发失败回调。
设置单次扫码超时
openCodeScan({
scanTimeout: 15000,
success: (res) => console.log(res.content),
fail: (err) => {
if (err.errCode === 9021011) console.log('15 秒内未识别到条码')
}
})
scanTimeout 单位为毫秒。只有单次扫码且值在 1000 ~ 600000 时启用;不传、传 0 或小于 1000 时不启用。连续扫码始终不启用单次超时。
关闭智能变焦 / 震动
openCodeScan({
smartZoom: false,
vibrate: false,
success: (res) => console.log(res.content)
})
配置扫描区域
scanRegion 同时决定扫描框的位置和实时识别过滤区域。宽度、高度、中心点均使用 0 ~ 1 的比例值;宽高以预览宽度为参考,越界值会由原生层收敛到可显示范围。scanRegion 只作用于实时相机,不裁剪或过滤相册图片。
openCodeScan({
scanRegion: {
width: 0.96,
height: 0.24,
centerX: 0.5,
centerY: 0.5
},
success: (res) => console.log(res.content)
})
- 不传
scanRegion:保持全屏识别,同时保留默认扫描框显示。 scanRegion: { fullScreen: true }:整画面识别,不显示扫描框,也不进行区域过滤。- 配置扫描区域后,条码中心点必须落在扫描框内才会被实时相机识别结果接受。
- 相册识图不受
scanRegion限制。
配置扫描框视觉样式
scanStyle 只控制扫描页视觉表现,不改变识别区域。颜色支持 #RRGGBB、#AARRGGBB;遮罩还支持 rgba(r, g, b, a)。
openCodeScan({
scanRegion: {
width: 0.96,
height: 0.24,
centerX: 0.5,
centerY: 0.5
},
scanStyle: {
showMask: true,
showBeam: true,
borderColor: '#19be6b',
maskColor: 'rgba(0, 0, 0, 0.45)',
beamColor: '#12e880',
beamDuration: 1800,
cornerStyle: 'rounded',
cornerRadius: 20
},
success: (res) => console.log(res.content)
})
showMask: false仅隐藏框外遮罩,不会扩大或改变识别范围。showBeam: false隐藏扫描线;扫描线周期beamDuration单位为毫秒,原生层限制在100 ~ 60000。cornerStyle: 'corner'显示直角四角边框,'full'显示完整矩形边框,'rounded'显示完整圆角边框,'rounded-corner'显示四角圆角边框。cornerRadius为圆角半径,单位为 dp,范围0 ~ 160,在两种圆角边框样式下均生效;圆角遮罩缺口和扫描线会同步裁剪为相同圆角。rounded是四边完整的圆角边框;rounded-corner只绘制四个带圆弧过渡的角,中间不连接四条边。- 圆角半径最终还会限制在扫描框短边的一半以内,适合二维码框和横向条码框。
- 当未启用
scanRegion时,视觉样式仅作用于默认扫描框;fullScreen: true时不会显示扫描框。
打开后直接进相册
openCodeScan({
fromAlbum: true,
success: (res) => {
console.log(res.content, res.fromAlbum) // fromAlbum === true
}
})
扫码页内也可随时点左下角 相册 按钮选图识别。
连续扫码
页内不关闭,每识别一次触发一次 success;用户点左上角关闭(或系统返回)后走 complete(若已有命中,不会再走 fail)。
const list = []
openCodeScan({
continuous: true,
showPauseButton: true,
vibrate: true,
success: (res) => {
list.push(res.content)
console.log('命中', res.content, res.format)
},
fail: (err) => {
// 一次都没扫到就关闭 → 一般是 9021003 取消
console.log('失败', err.errCode, err.errMsg)
},
complete: (res) => {
if (res && res.closed) {
console.log('结束,共', res.hitCount, '次', list)
}
}
})
组合:仅二维码 + 连续扫 + 相册入口
openCodeScan({
formats: ['QR_CODE'],
continuous: true,
smartZoom: true,
vibrate: true,
success: (res) => console.log(res),
complete: (res) => console.log('done', res)
})
API
openCodeScan(options?)
打开全屏扫码页。
CodeScanOptions
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
title |
string |
否 | 扫一扫 |
原生扫码页顶部标题 |
hint |
string |
否 | 请将条码放入扫描框内 |
扫描框下方引导语 |
successHint |
string |
否 | 扫码成功 |
连续扫码成功提示层标题 |
emptyHint |
string |
否 | 未识别到有效条码 |
图片无条码时提示语 |
smartZoom |
boolean |
否 | true |
条码占画面较小时自动平滑放大;最多尝试 6 次 |
formats |
string[] |
否 | 全部 | 限定码制,见下方取值表;空/不传 = 全格式 |
vibrate |
boolean |
否 | true |
识别成功后是否短震动约 40ms |
scanRegion |
ScanRegion |
否 | 未启用 | 实时相机识别区域,控制扫描框尺寸、位置和中心点过滤 |
scanStyle |
CodeScanStyle |
否 | 见下表 | 扫描框视觉样式,不改变识别区域 |
torch |
'off' \| 'on' \| 'auto' |
否 | 'off' |
手电筒策略;on 启动后开启,auto 低照度连续满足条件后自动开启 |
resultMode |
'immediate' \| 'confirm' \| 'pause' |
否 | 'immediate' |
单次扫码结果处理方式;连续扫码固定按立即上报处理 |
continuous |
boolean |
否 | false |
连续扫:页内不关闭,每次命中触发一次 success |
continuousSuccessDuration |
number |
否 | 1000 |
连续扫码成功提示停留时长,单位毫秒,范围 0 ~ 600000 |
showPauseButton |
boolean |
否 | false |
仅 continuous: true 时显示右上角暂停/继续按钮 |
fromAlbum |
boolean |
否 | false |
true 时打开扫码页后立即拉起系统相册 |
scanTimeout |
number |
否 | 不启用 | 单次扫码超时,单位毫秒,范围 1000 ~ 600000 |
success |
(res: CodeScanSuccess) => void |
否 | - | 成功;连续模式下可多次触发 |
fail |
(err: CodeScanFail) => void |
否 | - | 失败或取消;连续模式已有命中后关闭时不触发 |
complete |
(res: any) => void |
否 | - | 会话结束;成功、失败、取消和连续扫码关闭都会触发 |
ScanRegion
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
fullScreen |
boolean |
false |
为 true 时整画面识别,不显示扫描框,也不做中心点过滤;优先级高于其他区域参数 |
width |
number |
0.74 |
扫描框宽度相对预览宽度的比例,原生限制在 0.1 ~ 1 |
height |
number |
0.74 |
扫描框高度相对预览宽度的比例,原生限制在 0.1 ~ 1 |
centerX |
number |
0.5 |
扫描框中心横坐标比例,范围 0 ~ 1,越界会收敛 |
centerY |
number |
0.5 |
扫描框中心纵坐标比例,范围 0 ~ 1,越界会收敛 |
区域映射会补偿 PreviewView 的 FILL_CENTER 裁剪偏移和图像旋转;最终判断的是 ML Kit 包围盒的中心点是否在区域内,而不是要求整个条码完全位于框内。
建议:二维码使用接近正方形的区域,横向条码使用较宽且较矮的区域;如果业务只需要识别、不需要框选提示,可使用 fullScreen: true。
组合约束与默认行为
| 组合 | 实际行为 |
|---|---|
不传 scanRegion |
实时相机按全画面识别;使用原生默认扫描框布局 |
scanRegion.fullScreen: true |
全画面识别,不显示扫描框,不过滤框外结果 |
fromAlbum: true |
先打开相册;选图识别失败后,在相机可用时仍可继续相机扫码 |
continuous: true |
页内持续识别,resultMode 不参与单码确认;关闭页结束会话 |
continuous: true + showPauseButton: true |
右上角显示暂停/继续按钮,暂停期间不处理相机帧 |
continuous: true + scanTimeout |
忽略 scanTimeout,连续扫码没有会话超时 |
continuous: true + resultMode |
连续扫码固定立即上报,每次命中通过 success 返回 |
formats 含未知值和有效值 |
忽略未知值,使用有效码制 |
formats 非空且全部未知 |
立即失败并返回 9021010 |
| 单次识别到多个有定位框的条码 | 定格当前画面,显示绿色点选标记,点击后返回选中条码 |
| 连续扫码短时间重复同一内容 | 约 1.2 秒内去重,避免重复触发 success |
CodeScanStyle
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
showMask |
boolean |
true |
是否显示扫描框外遮罩 |
showBeam |
boolean |
true |
是否显示扫描线 |
borderColor |
string |
#19be6b |
边框颜色,支持 #RRGGBB、#AARRGGBB |
maskColor |
string |
rgba(0, 0, 0, 0.45) |
遮罩颜色和透明度,支持 rgba() |
beamColor |
string |
#12e880 |
扫描线颜色,支持 #RRGGBB、#AARRGGBB |
beamDuration |
number |
1800 |
扫描线移动周期,单位为毫秒,范围 100 ~ 60000 |
cornerStyle |
'corner' \| 'full' \| 'rounded' \| 'rounded-corner' |
'corner' |
corner 为直角四角边框,full 为完整边框,rounded 为完整圆角边框,rounded-corner 为四角圆角边框 |
cornerRadius |
number |
20 |
圆角半径,单位 dp,范围 0 ~ 160,两种圆角样式均生效 |
默认值:showMask: true、showBeam: true、borderColor: '#19be6b'、maskColor: 'rgba(0, 0, 0, 0.45)'、beamColor: '#12e880'、beamDuration: 1800、cornerStyle: 'corner'、cornerRadius: 20。非法颜色会回退到默认值,beamDuration 会限制在 100 ~ 60000 毫秒,cornerRadius 会限制在 0 ~ 160 dp。
示例:
openCodeScan({
scanRegion: {
width: 0.96,
height: 0.24,
centerX: 0.5,
centerY: 0.5
},
scanStyle: {
showMask: true,
showBeam: true,
borderColor: '#19be6b',
maskColor: 'rgba(0, 0, 0, 0.45)',
beamColor: '#12e880',
beamDuration: 1800,
cornerStyle: 'rounded',
cornerRadius: 20
},
success: (res) => console.log(res.content)
})
scanRegion 控制实时识别区域,scanStyle 只控制扫描页的视觉表现;两者可以独立配置。不传 scanRegion 时实时相机按全画面识别,但仍显示原生默认扫描框;需要隐藏扫描框时请传 scanRegion: { fullScreen: true }。
回调返回值与生命周期
单次扫码成功:
success({ content: '...', format: 'QR_CODE', fromAlbum: false })
complete({ content: '...', format: 'QR_CODE', fromAlbum: false })
单次扫码失败或用户取消:
fail({ errCode: 9021003, errMsg: '用户取消扫码', errSubject: 'mas-code-scan' })
complete({ errCode: 9021003, ... })
连续扫码关闭:
complete({ closed: true, hitCount: 3 })
连续扫码如果一次命中都没有就关闭,通常会先触发 fail(9021003),随后触发 complete({ closed: true, hitCount: 0, failed: true, errCode: 9021003 })。已有命中后关闭只触发 complete,不会触发 fail。
| 回调 | 触发时机 | 注意 |
|---|---|---|
success |
单次确认成功;或连续模式每次命中 | 多码点选只有点击某个码后触发 |
fail |
Activity 无法启动、权限失败、相机失败、相册失败、超时、用户取消等 | 用户取消错误码为 9021003 |
complete |
每次会话结束 | 不能只依赖 success 清理页面状态 |
CodeScanSuccess
| 字段 | 类型 | 说明 |
|---|---|---|
content |
string |
识别到的文本内容 |
format |
string |
码制名,如 QR_CODE、CODE_128 |
fromAlbum |
boolean |
是否来自相册识图(可选) |
CodeScanFail
继承 UniError:
| 字段 | 类型 | 说明 |
|---|---|---|
errCode |
number |
见错误码表 |
errMsg |
string |
错误描述 |
errSubject |
string |
固定 "mas-code-scan" |
回调规则:
- 单次扫码成功:依次调用
success、complete,成功对象包含content、format和fromAlbum。 - 单次扫码失败或取消:依次调用
fail、complete。 - 连续扫码:每次命中调用一次
success;关闭页面时调用complete({ closed: true, hitCount })。 - 连续扫码在已有命中后关闭:不会再调用
fail,只调用complete。 - 相册识图成功:
fromAlbum为true;相机实时识别成功时为false。
类型定义(摘录)
type CodeScanOptions = {
title?: string
hint?: string
successHint?: string
emptyHint?: string
smartZoom?: boolean
formats?: string[]
vibrate?: boolean
torch?: 'off' | 'on' | 'auto'
resultMode?: 'immediate' | 'confirm' | 'pause'
continuous?: boolean
continuousSuccessDuration?: number
showPauseButton?: boolean
fromAlbum?: boolean
scanRegion?: {
fullScreen?: boolean
width?: number
height?: number
centerX?: number
centerY?: number
}
scanStyle?: {
showMask?: boolean
showBeam?: boolean
borderColor?: string
maskColor?: string
beamColor?: string
beamDuration?: number
cornerStyle?: 'corner' | 'full' | 'rounded' | 'rounded-corner'
cornerRadius?: number
}
// 单次扫码超时(毫秒);小于 1000 或不传则不启用,最大 600000;连续扫码不启用超时
scanTimeout?: number
success?: (res: CodeScanSuccess) => void
fail?: (res: CodeScanFail) => void
complete?: (res: any) => void
}
type CodeScanSuccess = {
content: string
format: string
fromAlbum?: boolean
}
错误码
| 错误码 | 说明 | 常见场景 |
|---|---|---|
9021001 |
无法获取页面 Activity / 平台不支持 | 非 Android、页面上下文异常 |
9021002 |
相机权限被拒绝 | 用户拒绝相机权限(非「仅相册」场景) |
9021003 |
用户取消扫码 | 点关闭、系统返回、未扫就退出 |
9021004 |
未获取到有效扫码结果 | 成功关页但内容为空(少见) |
9021005 |
相机被其他应用占用或当前不可用 | 相机被其他应用、系统功能或设备状态占用 |
9021006 |
设备不支持手电筒 | 点击手电筒时提示;不结束当前扫码会话 |
9021007 |
相机初始化失败 | CameraX 初始化、绑定预览或分析管线失败 |
9021008 |
相册图片无法读取 | 所选 URI 无法读取、复制或解码图片 |
9021009 |
图片中未识别到条码 | fromAlbum: true 且无可回退相机时,图片中不存在有效码 |
9021010 |
指定码制不支持 | formats 非空但其中没有插件支持的码制 |
9021011 |
扫码超时 | 单次扫码设置了有效 scanTimeout 且超时未成功;连续扫码不启用 |
说明:
9021001~9021004为已有错误码,含义保持不变;新增错误码从9021005开始。fail与complete在失败时都会触发(连续扫「已有命中后关闭」除外:只complete)。- 打开即相册且无相机权限时,仍可用相册;点关闭且无命中 → 一般为
9021003。 - 无闪光灯不影响扫码,因此
9021006仅通过扫码页提示展示,不会触发fail。
扫码页交互说明
| 控件 / 手势 | 说明 |
|---|---|
| 左上关闭 | 退出;连续扫时结束会话 |
| 左下相册 | 选图识别;多码时同样可点选 |
| 右下手电筒 | 有闪光灯时可用;可由 torch 设置初始策略,auto 会在低照度时自动开启 |
| 右上暂停按钮 | 仅连续扫码且 showPauseButton: true 时显示,暂停/继续识别 |
| 结果确认框 | resultMode: 'confirm' 或 'pause' 时,确认返回或继续扫描 |
| 双指捏合 | 手动变焦 |
| 多码绿点 | 同屏多个有效码时定格,显示绿色呼吸波纹,点击选中 |
| 系统返回键 | 等同关闭 |
码制 formats 取值
传入字符串数组;空/缺省时按全格式。若 formats 非空但全部不受支持,调用失败并返回 9021010。
| 取值 | 说明 |
|---|---|
QR_CODE / QR |
二维码 |
EAN_13 / EAN_8 |
商品条码 |
CODE_128 / CODE_39 / CODE_93 |
一维码 |
CODABAR |
Codabar |
DATA_MATRIX |
Data Matrix |
UPC_A / UPC_E |
UPC |
ITF |
ITF |
PDF417 |
PDF417 |
AZTEC |
Aztec |
ALL |
全格式(与具体码制混用时按全格式处理) |
补充规则:插件会忽略未知 token;只要数组中存在一个有效 token 就使用有效 token。数组非空但全部无效时返回 9021010。ALL 与其他有效码制同时传入时最终使用全格式。
示例:
formats: ['QR_CODE', 'CODE_128', 'EAN_13']
常见问题
1. 点击没反应 / 报找不到类?
未使用自定义基座。请按上文制作并选择「自定义调试基座」再运行。
2. 提示相机权限被拒绝(9021002)?
到系统设置打开应用相机权限后重试。
3. 连续扫只回调一次?
确认传了 continuous: true。同一内容约 1.2 秒内会去重,避免狂刷;换个码或稍等再扫。
4. 相册选了图但提示未识别?
图中可能没有清晰条码,或被 formats 过滤掉。可先不传 formats 试全格式;打开即相册且没有可用相机时,会以 9021009 返回无条码错误。
5. 为什么会提示扫码超时(9021011)?
仅在单次扫码传入 scanTimeout(1000 ~ 600000 毫秒)后启用。超时不会影响连续扫码;不需要限制时不传该参数或传 0。
6. iOS / 鸿蒙能用吗?
当前版本仅 Android。目录未包含 iOS/鸿蒙实现。
7. 能否当组件标签用?
不能。这是 UTS API,请 import { openCodeScan } from '@/uni_modules/mas-code-scan' 后调用。
8. 演示页可以直接当业务页面使用吗?
prototype.vue 是能力验证页面,结果列表是本地状态,不包含业务接口提交、权限引导和业务字段转换。正式业务建议复制 openScan 调用方式,在自己的页面中处理 success、fail 和 complete,并在 complete 中恢复 loading、页面状态等资源。
9. scanStyle 不生效怎么办?
确认调用的是包含当前插件的自定义调试基座或正式打包应用。修改 UTS 原生代码后需要重新制作自定义基座或重新云打包,普通标准基座不会加载插件原生依赖和最新实现。
10. 扫描框显示了但框外条码没有识别?
这是 scanRegion 的预期行为。扫描框不仅是视觉提示,也会作为实时识别过滤区域;如需整屏识别,请不传 scanRegion 或传入 fullScreen: true。
11. resultMode 和 continuous 一起传会怎样?
连续扫码以连续模式为准,不显示单次扫码确认框,每次识别成功都会通过 success 上报;如需单个结果确认,请不要传 continuous: true。
12. fromAlbum 和相机权限有什么关系?
Android 13 及以上优先使用系统 Photo Picker;Android 12 及以下使用系统图片选择器,可能需要读取相册权限。打开即相册时,即使没有相机权限,也可以先完成相册识图;相册无结果且无法继续使用相机时返回 9021009。
13. 为什么识别框位置和相机画面看起来不完全一致?
预览采用 FILL_CENTER,相机画面会按比例填充并裁剪边缘;插件会在识别过滤时补偿裁剪和旋转,但不同设备的相机传感器比例、状态栏和厂商裁剪策略可能存在少量视觉差异。
注意事项
- 仅 Android App-Plus;发布市场包请走正式打包,勿依赖标准基座调试结果。
- 首次使用实时相机需要相机权限;插件不会主动跳转系统设置,权限被拒绝后由业务决定是否引导用户开启。
- 震动权限由插件 Manifest 声明;设置
vibrate: false可关闭成功震动。 - 相册选图走系统选择器;Android 12 及以下可能需要读取相册权限,Android 13 及以上优先使用 Photo Picker。
scanRegion只过滤实时相机,且按条码包围盒中心点判断;相册识图始终分析整张图片。- 连续扫依赖原生命中队列和 UTS 桥接轮询,业务应在
complete中收尾,不要只在success中恢复状态。 - 多码点选依赖 ML Kit 返回定位框;多码中只有一个可解码码时会直接返回,无法定位的结果不能作为可点击目标。
- 智能变焦和双指缩放共享相机变焦能力;不支持变焦的设备会保持原始比例。
- 大尺寸相册图片会先缩放到最长边约 1920 像素再识别,以降低内存压力。
- 文档与演示不保证覆盖所有机型相机差异,建议使用真实目标机型回归。
目录结构
mas-code-scan/
├── package.json
├── readme.md
├── changelog.md
└── utssdk/
├── interface.uts # 对外类型与 API 声明
├── unierror.uts # 错误实现
└── app-android/
├── index.uts # JS/UTS 桥接
├── config.json # 原生依赖
├── AndroidManifest.xml
├── CodeCaptureActivity.kt
├── MultiCodePickView.kt
├── ScanFrameDecorView.kt
├── YuvFrames.kt
├── SymbologyUtil.kt
├── CodeScanHitBus.kt
└── res/drawable/ # 关闭/相册等资源
版本
| 版本 | 说明 |
|---|---|
| 1.3.0 | 新增 rounded 完整圆角边框、rounded-corner 四角圆角边框和自定义 cornerRadius,遮罩与扫描线同步适配圆角 |
| 1.2.0 | 新增 scanStyle 扫描框视觉配置,支持遮罩、扫描线、颜色、动画周期、四角/完整边框;完善 scanRegion 与回调说明 |
| 1.1.0 | 权限码区分、关闭/相册、码制过滤、震动、连续扫、Kotlin 拆分 |
| 1.0.0 | Android 扫码初版 |
更多变更见 changelog.md。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 0
赞赏 0
下载 12561228
赞赏 1948
赞赏
京公网安备:11010802035340号