更新记录
1.0.1(2026-06-14)
调整兼容说明
1.0.0(2026-06-14)
第一次提交
平台兼容性
uni-app(4.71)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.71)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | √ | √ | √ | × |
w-scankit
uni-app UTS 原生扫码插件 — 支持单次扫码、连续扫码、图片识码、多码识别,覆盖 Android / iOS / HarmonyOS NEXT 三端。
目录
平台兼容性
| 平台 | 支持版本 | 底层实现 |
|---|---|---|
| Android | API 21+ | HMS ScanKit(华为统一扫码服务) |
| iOS | iOS 12+ | AVFoundation + CIDetector |
| HarmonyOS NEXT | API 12+ | @kit.ScanKit(鸿蒙扫码服务) |
注意:小程序平台不支持本插件,请使用 uni-app 内置的
uni.scanCode()API。
功能特点
- ✅ 单次扫码 — 打开系统扫码界面,识别后自动返回结果
- ✅ 连续扫码 — 持续扫描,每次识别触发回调,手动结束返回全部结果
- ✅ 图片单码识别 — 从本地图片文件中识别单个二维码/条形码
- ✅ 图片多码识别 — 从本地图片文件中一次性识别所有二维码/条形码
- ✅ 闪光灯控制 — 打开 / 关闭 / 切换闪光灯
- ✅ 权限管理 — 检查与请求相机权限
- ✅ 多种码类型 — 支持 QR 码、EAN 系列、Code 系列、Data Matrix、Aztec、PDF417 等
- ✅ 三端统一 API — Android / iOS / HarmonyOS 调用方式完全一致
快速开始
1. 安装插件
在 HBuilderX 中,通过 uni_modules 市场搜索 w-scankit 并导入项目,或将 uni_modules/w-scankit/ 目录放入项目根目录下。
2. 基础用法
// 导入插件
import {
checkPermission,
requestPermission,
startScan,
scanImage,
startContinuousScan,
scanImageMulti,
openFlash,
closeFlash,
toggleFlash
} from '@/uni_modules/w-scankit';
// 单次扫码
startScan({
success(res) {
console.log('扫码结果:', res.text); // 码内容
console.log('码类型:', res.format); // 如 "QR_CODE"
},
fail(err) {
console.error('扫码失败:', err.message);
}
});
权限配置
Android
manifest.json 中已声明 android.permission.CAMERA 权限。运行时会动态请求。
iOS
manifest.json 中需配置相机使用描述:
{
"app-plus": {
"distribute": {
"ios": {
"privacyDescription": {
"NSCameraUsageDescription": "需要使用相机进行扫码"
}
}
}
}
}
HarmonyOS
config.json 中已配置:
{
"permissions": ["ohos.permission.CAMERA"]
}
API 文档
权限相关
checkPermission(): boolean
同步检查相机权限是否已授权。
返回值: true — 已授权,false — 未授权。
if (checkPermission()) {
startScan({ ... });
} else {
requestPermission({ ... });
}
requestPermission(options: RequestPermissionOptions): void
请求相机权限。
RequestPermissionOptions:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
success |
(granted: boolean) => void |
否 | 权限请求完成回调,true 表示已授权 |
fail |
(err: ScanError) => void |
否 | 请求失败回调 |
complete |
(res: any) => void |
否 | 完成回调(成功/失败均触发) |
扫码相关
startScan(options: ScanCodeOptions): void
打开系统扫码界面,单次扫码后自动关闭并返回结果。
ScanCodeOptions:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
vibrate |
boolean |
否 | true |
扫码成功时是否震动 |
showFlashButton |
boolean |
否 | true |
是否显示闪光灯按钮 |
autoClose |
boolean |
否 | true |
扫码成功后是否自动关闭扫码界面 |
success |
(res: ScanResult) => void |
否 | — | 扫码成功回调 |
fail |
(err: ScanError) => void |
否 | — | 扫码失败/取消回调 |
complete |
(res: any) => void |
否 | — | 完成回调(成功/失败均触发) |
ScanResult:
| 字段 | 类型 | 说明 |
|---|---|---|
text |
string |
码内容(原始值) |
format |
string |
码类型,如 "QR_CODE"、"CODE_128" 等 |
图片识码
scanImage(options: ScanImageOptions): void
从本地图片文件中识别第一个二维码/条形码。
ScanImageOptions:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
imagePath |
string |
是 | 图片文件路径,支持 file:// 前缀或沙箱绝对路径 |
success |
(res: ScanResult) => void |
否 | 识别成功回调 |
fail |
(err: ScanError) => void |
否 | 识别失败回调 |
complete |
(res: any) => void |
否 | 完成回调 |
连续扫码
startContinuousScan(options: ScanContinuousCodeOptions): void
打开扫码界面并持续识别。每次扫到新码触发 onResult 回调,用户手动结束(点击完成或返回)后触发 success 返回所有已识别结果。
ScanContinuousCodeOptions:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
vibrate |
boolean |
否 | true |
每次扫码成功时是否震动 |
showFlashButton |
boolean |
否 | true |
是否显示闪光灯按钮 |
onResult |
(res: ScanResult) => void |
否 | — | 每次识别到新码时触发(不触发震动去重) |
success |
(res: ScanMultiResult) => void |
否 | — | 用户结束扫码时返回所有结果 |
fail |
(err: ScanError) => void |
否 | — | 扫码取消/失败回调 |
complete |
(res: any) => void |
否 | — | 完成回调 |
ScanMultiResult:
| 字段 | 类型 | 说明 |
|---|---|---|
results |
ScanResult[] |
所有已识别的码结果列表 |
图片多码识别
scanImageMulti(options: ScanImageMultiOptions): void
从本地图片文件中一次性识别所有二维码/条形码。
ScanImageMultiOptions:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
imagePath |
string |
是 | 图片文件路径 |
success |
(res: ScanMultiResult) => void |
否 | 识别成功,返回所有码结果 |
fail |
(err: ScanError) => void |
否 | 识别失败回调 |
complete |
(res: any) => void |
否 | 完成回调 |
闪光灯控制
| 方法 | 返回值 | 说明 |
|---|---|---|
openFlash() |
void |
打开闪光灯 |
closeFlash() |
void |
关闭闪光灯 |
toggleFlash() |
boolean |
切换闪光灯状态,返回切换后的状态(true=开,false=关) |
⚠️ 闪光灯依赖硬件支持,仅在设备有实体闪光灯且扫码界面激活时可用。
支持的码类型
format 值 |
码类型 | 说明 |
|---|---|---|
QR_CODE |
QR 码 | 二维码 |
EAN_8 |
EAN-8 | 商品条码 |
EAN_13 |
EAN-13 | 商品条码 |
CODE_128 |
Code 128 | 一维条码 |
CODE_39 |
Code 39 | 一维条码 |
CODE_93 |
Code 93 | 一维条码 |
CODABAR |
Codabar | 一维条码 |
ITF |
ITF-14 | 一维条码 |
PDF_417 |
PDF417 | 二维条码 |
DATA_MATRIX |
Data Matrix | 二维条码 |
AZTEC |
Aztec | 二维条码 |
UPC_A |
UPC-A | 商品条码 |
UPC_E |
UPC-E | 商品条码 |
错误码
| 错误码 | 常量名 | 说明 |
|---|---|---|
1001 |
CAMERA_DENIED |
相机权限被用户拒绝 |
1002 |
CAMERA_UNAVAILABLE |
相机硬件不可用 |
1003 |
SCAN_CANCELLED |
用户主动取消扫码 |
1004 |
SCAN_FAILED |
扫码识别失败(未识别到条码) |
1005 |
IMAGE_NOT_FOUND |
图片文件不存在或无法加载 |
1006 |
IMAGE_DECODE_FAILED |
图片中未识别到二维码/条形码 |
也可以在代码中使用错误码常量:
import { SCAN_CANCELLED } from '@/uni_modules/w-scankit';
startScan({
fail(err) {
if (err.code === SCAN_CANCELLED) {
// 用户取消,不做提示
return;
}
uni.showToast({ title: err.message, icon: 'none' });
}
});
代码示例
示例 1:单次扫码(完整权限流程)
<template>
<view>
<button @click="doScan">扫码</button>
<text>结果:{{ result }}</text>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { checkPermission, requestPermission, startScan } from '@/uni_modules/w-scankit';
const result = ref('');
const doScan = () => {
if (!checkPermission()) {
requestPermission({
success(granted) {
if (granted) launchScan();
else uni.showToast({ title: '需要相机权限', icon: 'none' });
}
});
return;
}
launchScan();
};
const launchScan = () => {
startScan({
vibrate: true,
success(res) {
result.value = `${res.format}: ${res.text}`;
uni.showToast({ title: '扫码成功', icon: 'success' });
},
fail(err) {
if (err.code !== 1003) {
uni.showToast({ title: err.message, icon: 'none' });
}
}
});
};
</script>
示例 2:连续扫码(多码批量收集)
<template>
<view>
<button @click="startContinuous">{{ scanning ? '扫码中...' : '连续扫码' }}</button>
<view v-for="(item, i) in codes" :key="i">
<text>[{{ item.format }}] {{ item.text }}</text>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { startContinuousScan } from '@/uni_modules/w-scankit';
const codes = ref([]);
const scanning = ref(false);
const startContinuous = () => {
codes.value = [];
scanning.value = true;
startContinuousScan({
vibrate: true,
onResult(res) {
// 每扫到一个码实时追加到列表
codes.value.unshift(res);
},
success(res) {
scanning.value = false;
uni.showToast({
title: `共识别 ${res.results.length} 个码`,
icon: 'success'
});
},
fail(err) {
scanning.value = false;
if (err.code !== 1003) {
uni.showToast({ title: err.message, icon: 'none' });
}
}
});
};
</script>
示例 3:从相册选图识码
import { scanImage, scanImageMulti } from '@/uni_modules/w-scankit';
// 选择单张图片,识别单个码
uni.chooseImage({
count: 1,
success(res) {
const imagePath = res.tempFilePaths[0];
scanImage({
imagePath,
success(result) {
uni.showModal({
title: '识别结果',
content: `类型: ${result.format}\n内容: ${result.text}`
});
},
fail(err) {
uni.showToast({ title: err.message, icon: 'none' });
}
});
}
});
// 选择单张图片,识别所有码
uni.chooseImage({
count: 1,
success(res) {
scanImageMulti({
imagePath: res.tempFilePaths[0],
success(multiRes) {
const items = multiRes.results
.map((r, i) => `${i + 1}. [${r.format}] ${r.text}`)
.join('\n');
uni.showModal({
title: `识别到 ${multiRes.results.length} 个码`,
content: items
});
},
fail(err) {
uni.showToast({ title: err.message, icon: 'none' });
}
});
}
});
示例 4:闪光灯控制
import { openFlash, closeFlash, toggleFlash } from '@/uni_modules/w-scankit';
// 打开闪光灯
openFlash();
// 切换闪光灯
const isOn = toggleFlash();
console.log('闪光灯状态:', isOn ? '开' : '关');
// 关闭闪光灯
closeFlash();
注意事项
-
Android 依赖 HMS Core Android 端基于华为 HMS ScanKit 实现。首次使用时会自动检查 HMS Core 版本。若设备不支持 HMS(如非华为设备且未安装 HMS Core),需引导用户安装 HMS Core。
-
iOS 隐私描述 iOS 端必须在
manifest.json中配置NSCameraUsageDescription,否则打包时会校验失败。部分场景下还需要配置NSPhotoLibraryUsageDescription(相册识码时)。 -
HarmonyOS NEXT 要求 鸿蒙端基于
@kit.ScanKit实现,要求 HarmonyOS API 12+。图片识码需要@kit.CoreFileKit进行路径转换。 -
图片路径格式 支持
file://开头的 URI 和沙箱绝对路径(如/data/storage/...)。Android 端会自动去除file://前缀,iOS 端直接使用路径。 -
连续扫码去重 HarmonyOS 连续扫码模式下,同一码内容在 2 秒内不会重复触发
onResult回调,避免频繁重复上报。 -
小程序不支持 本插件仅支持 App 原生平台(Android / iOS / HarmonyOS)。小程序端请使用 uni-app 内置的
uni.scanCode()。 -
模拟器限制 扫码功能依赖真实相机硬件,模拟器/虚拟机中通常无法使用,请在真机上调试。
版本
当前版本:1.0.0
许可
MIT License

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