更新记录
1.0.1(2026-07-22)
更新插件使用demo等
1.0.0(2026-07-22)
插件首次发布
平台兼容性
uni-app(4.71)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | × | × | √ | 1.0.0 | √ | 1.0.0 | 6.0 | 1.0.0 | 12 | 1.0.0 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.71)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|---|
| × | × | 6.0 | 1.0.0 | 12 | 1.0.0 | × | × |
gt-scan
面向 uni-app 与 uni-app x 的 Android、iOS UTS 扫码插件。提供原生全屏扫码页,支持单次扫码、连续扫码、同帧多码、相册/本地图片识别、运行时相机控制和二维码生成。
平台与依赖
| 平台 | 最低版本 | 原生实现 |
|---|---|---|
| Android | Android 6.0(API 23) | CameraX 1.5.3、bundled ML Kit Barcode Scanning 17.3.0、ZXing Core 3.5.4 |
| iOS | iOS 12.0 | AVFoundation、Core Media、Vision、Core Image |
仅实现 App-Android 和 App-iOS。Web、小程序、HarmonyOS 不支持。
UTS 原生插件必须制作包含本插件的自定义调试基座;标准基座不包含插件的原生依赖和代码。
功能
- 单次扫码,调用方式接近
uni.scanCode。 - 连续扫码,多次触发
onScan。 - 同一帧返回多个码,单批最多 10 个。
- 按内容和码制去重,可设置去重与回调间隔。
- 扫描区域、前后摄像头、手势缩放、闪光灯、相机切换。
- 原生扫码页标题、提示语、颜色和按钮显隐配置。
- 扫码页内从相册选择图片,或直接调用
decodeImage识别本地图片。 - 生成自定义尺寸、颜色、容错级别和静区的二维码 PNG。
- 相机权限状态查询与主动请求。
- 全部识别能力离线运行,不上传相机画面、图片或结果。
快速开始
import {
scanCode,
GtScanResult
} from '@/uni_modules/gt-scan'
scanCode({
formats: ['QR_CODE', 'BAR_CODE'],
onlyFromCamera: false,
enableVibrate: true,
timeoutMs: 30000,
success: (res : GtScanResult) => {
console.log('内容:', res.result)
console.log('码制:', res.scanType)
},
fail: (error) => {
if (error.errCode != 9012010) {
console.error('扫码失败:', error)
}
}
})
BAR_CODE 是输入时可用的条形码集合别名,不会作为结果中的 scanType 返回。
连续扫码
import {
startScan,
stopScan,
GtScanBatchResult
} from '@/uni_modules/gt-scan'
let batchCount = 0
startScan({
formats: ['QR_CODE', 'CODE_128', 'EAN_13'],
multi: true,
maxResults: 5,
duplicateIntervalMs: 1200,
scanIntervalMs: 180,
onScan: (res : GtScanBatchResult) => {
batchCount += 1
console.log('本批结果:', res.results)
if (batchCount >= 5) {
stopScan()
}
},
onStateChange: (res) => {
console.log('会话状态:', res.state)
},
fail: (error) => {
console.error('会话失败:', error)
},
complete: (res) => {
console.log('扫码会话结束:', res)
}
})
startScan.success 在相机进入 running 时执行一次;onScan 可执行多次;complete 在会话结束时执行一次。用户点击取消时,fail 和 complete 都会收到 9012010。
识别本地图片
import { decodeImage } from '@/uni_modules/gt-scan'
uni.chooseImage({
count: 1,
success: (chooseResult) => {
if (chooseResult.tempFilePaths.length == 0) return
decodeImage({
path: chooseResult.tempFilePaths[0],
maxResults: 10,
success: (res) => {
console.log('图片中的码:', res.results)
}
})
}
})
Android 支持普通文件路径、file:// 和 content://;iOS 支持沙盒内的普通文件路径和 file://。
生成二维码
import { createQRCode } from '@/uni_modules/gt-scan'
createQRCode({
content: 'https://example.com/product?id=100',
width: 640,
height: 640,
margin: 4,
correctionLevel: 'M',
foregroundColor: '#111827',
backgroundColor: '#FFFFFF',
success: (res) => {
console.log('二维码临时文件:', res.tempFilePath)
}
})
输出为应用缓存目录下的临时 PNG,应用或系统清理缓存后可能失效。需要长期保存时,请由业务代码复制到持久目录。margin 单位为二维码模块数,范围 0...32。
支持的码制
| 名称 | 说明 |
|---|---|
QR_CODE |
QR Code |
AZTEC |
Aztec |
DATA_MATRIX |
Data Matrix |
PDF_417 |
PDF417 |
CODABAR |
Codabar;iOS 15.0+ |
CODE_39 |
Code 39 |
CODE_93 |
Code 93 |
CODE_128 |
Code 128 |
EAN_8 |
EAN-8 |
EAN_13 |
EAN-13 |
ITF |
Interleaved 2 of 5 / ITF-14 |
UPC_A |
UPC-A;iOS Vision 以带前导 0 的 EAN-13 识别,插件会映射为 UPC_A |
UPC_E |
UPC-E |
BAR_CODE |
仅输入别名,表示全部一维条形码 |
运行时可调用 getSupportedFormats() 获取公共格式列表。iOS 12 至 14 传入 CODABAR 会返回 9012007。
API
| 方法 | 说明 |
|---|---|
scanCode(options) |
打开单次扫码页,返回离扫描框中心最近的结果 |
startScan(options) |
打开连续扫码页,通过 onScan 多次返回结果 |
stopScan(options?) |
关闭当前扫码会话 |
pauseScan(options?) |
暂停帧识别,保留预览和相机 |
resumeScan(options?) |
恢复帧识别 |
setTorch(options) |
开关当前摄像头闪光灯 |
setZoom(options) |
设置当前摄像头缩放倍数 |
switchCamera(options?) |
切换前后摄像头 |
decodeImage(options) |
识别本地图片,最多返回 10 个结果 |
createQRCode(options) |
生成二维码临时 PNG |
getCameraPermissionStatus() |
同步返回相机权限状态字符串 |
requestCameraPermission(options) |
请求相机权限并返回最终状态 |
getScanState() |
同步返回当前扫码会话状态 |
getSupportedFormats() |
同步返回公共支持格式列表 |
GtScanCodeOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
formats |
string[] |
全部 | 允许识别的码制,可使用 BAR_CODE 别名 |
onlyFromCamera |
boolean |
false |
是否隐藏相册入口并只允许相机扫码 |
camera |
string |
back |
back 或 front |
scanArea |
GtScanRect |
{x:0.12,y:0.25,width:0.76,height:0.38} |
归一化扫描区域 |
enableBeep |
boolean |
false |
成功识别后播放提示音 |
enableVibrate |
boolean |
true |
成功识别后振动 |
enableZoom |
boolean |
true |
是否允许双指手势缩放 |
timeoutMs |
number |
0 |
超时时间;0 表示不自动超时 |
ui |
GtScanUiOptions |
- | 原生扫码页样式和按钮配置 |
success/fail/complete |
function |
- | 单次调用回调 |
GtStartScanOptions
包含 GtScanCodeOptions 的扫码、相机、反馈和 UI 参数,并增加:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
multi |
boolean |
false |
是否返回同一帧中的多个码 |
maxResults |
number |
10 |
单批最大结果数,范围 1...10 |
duplicateIntervalMs |
number |
1200 |
相同 scanType + result 再次回调前的等待时间 |
scanIntervalMs |
number |
180 |
两批结果回调的最小间隔 |
onScan |
function |
必填 | 连续结果回调 |
onStateChange |
function |
- | 状态变化回调 |
GtScanUiOptions
| 参数 | 默认值 | 说明 |
|---|---|---|
title |
扫码 |
页面标题 |
hintText |
将二维码或条形码放入框内 |
扫描框下方提示 |
cancelText |
取消 |
取消按钮文字 |
albumText |
相册 |
相册按钮文字 |
torchOnText/torchOffText |
关闭闪光灯/打开闪光灯 |
闪光灯按钮文字 |
scanLineColor |
#22C55E |
扫描线颜色 |
frameColor |
#FFFFFF |
扫描框颜色 |
maskColor |
#99000000 |
扫描框外遮罩颜色 |
backgroundColor |
#000000 |
页面背景色 |
statusBarColor |
#000000 |
Android 状态栏颜色;iOS 全屏页以背景色显示 |
statusBarDarkMode |
false |
状态栏使用深色图标 |
showAlbum |
true |
显示相册入口;onlyFromCamera=true 时强制隐藏 |
showTorch |
true |
显示闪光灯按钮 |
showSwitchCamera |
false |
显示前后摄像头切换按钮 |
showScanLine |
true |
显示扫描线动画 |
颜色参数支持 #RRGGBB 和与 Android Color.parseColor 一致的 #AARRGGBB。
返回结果
GtScanResult 和 GtScanItem 的主要字段:
| 字段 | 说明 |
|---|---|
result |
解码后的文本内容 |
scanType |
规范化码制名称 |
rawData |
Base64;Android 为识别器原始字节,iOS 为结果文本的 UTF-8 字节 |
charSet |
字符集;识别器无法提供时为空 |
valueType |
内容类型提示。Android 来自 ML Kit,iOS 由文本前缀推断 |
boundingBox |
归一化边界框,坐标范围 0...1 |
cornerPoints |
归一化角点,坐标范围 0...1 |
timestamp |
Unix 毫秒时间戳 |
source |
camera、album 或调用方传给 decodeImage 的 source |
扫码页使用 scanArea 过滤相机识别结果;decodeImage 不按扫描区域过滤。
会话与权限状态
getScanState() 返回:idle、opening、running、paused、closing。
getCameraPermissionStatus() 与 requestCameraPermission() 的 status 返回:
notDetermined:尚未请求。granted:已授权。denied:Android 已拒绝但仍可再次请求。permanentlyDenied:已永久拒绝,需要进入系统设置。restricted:系统限制或上下文不可用。
权限请求 API 本身成功不等于用户授权,应检查返回值的 granted。扫码页也会在需要时主动请求相机权限。
原生配置与隐私
插件自动声明:
- Android:
android.permission.CAMERA、android.permission.VIBRATE。 - iOS:
NSCameraUsageDescription、NSPhotoLibraryUsageDescription。
正式发布前应在应用配置中使用与你的业务一致的权限说明,并在隐私政策中说明相机、相册以及扫码结果的实际用途。
Android 使用 bundled ML Kit 模型,首次运行不需要下载识别模型,也不需要 INTERNET 权限。相册通过系统文档选择器读取用户主动选择的单张图片,不申请广泛存储权限。
Google 官方给出的 bundled 条码模型包体增量约为 2.4 MB;CameraX、ZXing、代码压缩和已有依赖还会影响最终 APK/AAB 大小,请以正式构建产物为准。iOS 仅使用系统 Framework,不内置第三方识别模型。
注意事项
- 同一时间只允许一个全屏扫码会话,重复启动返回
9012005。 setTorch、setZoom和switchCamera只在扫码页已打开时有效;无会话返回9012006。- 前置摄像头通常没有闪光灯;内置扫码页会自动隐藏闪光灯按钮,直接调用
setTorch则会失败并返回原生原因。 - 控制 API 的成功表示控制请求已被原生相机接受,不承诺硬件状态同步完成。
- 用户点击返回或取消属于正常交互,但通过
fail返回9012010,业务通常可静默处理。 - iOS 的 Vision 不提供原始条码字节和 ML Kit 同级的结构化内容类型,相关字段按上文降级。
- 请至少使用一台 Android 真机和一台 iPhone 验证权限、旋转、前后摄像头、相册和连续扫码,再将插件市场平台标记改为支持。
错误码
| 错误码 | 含义 |
|---|---|
9012001 |
参数无效 |
9012002 |
相机权限被拒绝或受限制 |
9012003 |
相机权限永久拒绝 |
9012004 |
没有可用摄像头或相机无法启动 |
9012005 |
已有扫码会话运行 |
9012006 |
没有运行中的扫码会话 |
9012007 |
不支持的码制 |
9012008 |
图片中未识别到条码 |
9012009 |
图片读取失败 |
9012010 |
用户取消扫码 |
9012011 |
无法打开扫码页面 |
9012012 |
原生识别或相机操作失败 |
9012013 |
当前平台不支持 |
9012014 |
扫描超时 |
9012015 |
扫码资源已经释放 |

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 105
赞赏 0
下载 12451542
赞赏 1935
赞赏
京公网安备:11010802035340号