更新记录
1.0.0(2026-10-20) 下载此版本
首次发布:三端统一的原生扫码
- 对外 API 两个,都是 uni 风格(
options入参带success / fail / complete,返回void,不返回 Promise):scan(options)拉起当前端的原生扫码界面并回一个码值;getEnvInfo()同步查询端标识、系统版本、相机可用性与授权状态。Web 与小程序走utssdk/index.uts兜底,getEnvInfo照常降级返回、scan回9050009。 - 三端实现:Android 走华为 ScanKit
com.huawei.hms:scanplus:2.12.0.301(ScanUtil.startScan+ Activity result 解析,原生细节留在混编scankit.kt);iOS 走插件内置的ScanKitFrameWork.framework(HmsDefaultScanViewController,桥接层HmsScanKit.swift);HarmonyOS 走系统@kit.ScanKit的scanBarcode.startScanForResult,零厂商配置。 - 契约收敛为「一次交互一个码值」:连续扫码/多码结果在三端的界面与回调时序差异过大,强行对齐会让业务侧仍需判端,因此由业务侧循环调用,插件保证每次调用都是一个完整的用户交互。
- 三端行为归一(跨端纯逻辑集中在
core.uts,无任何平台 API):三端之间只对接归一化码型名,scanTypeCode用的是本插件统一编号(取自鸿蒙scanCore.ScanType,与 iOSHmsScanFormat位序 +1 一致;华为 Android 的HmsScan.*_SCAN_TYPE是另一套位掩码,换算全部封闭在app-android/scankit.kt内,入参走setHmsScanTypes);鸿蒙侧因ScanOptions.scanTypes是名义枚举,另写「名字 ↔ 枚举成员」显式对照表;iOS 把框架短名映射回归一化名并按位掩码过滤。厂商原始码一律归类到9050段位、原值拼进errMsg,业务侧可不分端地写switch。 - 权限最小化:Android 由
scan内部按机型 API 与宿主targetSdkVersion的较低档分档申请(≥34 选择性媒体访问三件套、≥33 只要READ_MEDIA_IMAGES、更低用READ_EXTERNAL_STORAGE),enableAlbum: false时只申请相机;取较低档是因为系统判定媒体权限能否申请看的是宿主 targetSdk,在targetSdk < 33的宿主上申请READ_MEDIA_IMAGES会抛IllegalStateException并被框架转成 JS 异常(fail不回、单飞槽位卡死),所以低 target 的宿主自动走旧权限并对申请调用做了try/catch复位;iOS 同样由scan代管——notDetermined时直接弹系统授权框(授权 API 走混编层,info.plist随插件提供NSCameraUsageDescription,文件名必须小写),被拒或denied/restricted才回9050003并给出去设置里的路径;HarmonyOS 的相机与相册权限由系统扫码界面自理,宿主无需声明ohos.permission.*。 - 错误码占
9050段位,9050001–9050007+9050009全部登记文案,序号009固定表示平台不支持。ScanFailImpl的入参是number并在唯一收口点判段内/段外(段外归9050006、原始数留在errMsg),因为数字字面量联合类型只有 ArkTS 会硬判。 - iOS 端两条框架级限制如实记录在 readme,不做假成功:①
DefaultScanDelegate无取消回调,用户返回/侧滑关闭界面时插件收不到任何信号,只能在下一次调用时用「上一会话仍挂着」回9050005;② 内置框架版本不开放相册识别入口,enableAlbum在 iOS 上不生效、getEnvInfo().albumSupported固定false。 - 案例页
example/index.vue首屏是「最近扫码内容」大字块:每次成功的码值原文直接显示在顶部,副标题带码型名、统一编号与长度;下面是环境检测块与按本端能力显示的扫码按钮(相册按钮只在albumSupported的 Android/HarmonyOS 出现,一码多物只在 HarmonyOS 出现,iOS 只有实时扫码)。本插件是原生模态「一次交互一个结果」,取消与失败由界面自己收,因此按规则 §7 的scenario-exempt豁免单独演示失败路径与生命周期,但每个按钮下方仍如实显示fail回来的errCode/errMsg。 - 补
license.txt:免费 + 插件市场广告解锁口径,写明使用权与源码权、禁止再分发、支持边界(宿主包名/签名/开放平台资质不在支持范围)与免责;条款内不写死任何价格数字。 - 上架前需人工补齐:
package.json的repository与contact.qq;Android 验收必须用云端自定义调试基座(本地标准基座不解析 Maven 依赖,报「找不到名称 com.huawei」属环境限制)。
平台兼容性
uni-app(4.75)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | √ | √ | 9.0 | √ | 12 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.75)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | 9.0 | √ | 12 | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
bear-scan
一行调用拉起原生扫码界面,回一个码值:Android 走华为 ScanKit(com.huawei.hms:scanplus)、
iOS 走内置的华为 ScanKit Framework、HarmonyOS 走系统 @kit.ScanKit,Web / 小程序返回「平台不支持」而不是崩。
是对华为统一扫码服务薄封装:界面、解码、权限全部由各端的 ScanKit 承担,插件只做统一契约 + 错误码归一 + 三端行为对齐。
本插件免费,以插件市场的「观看广告解锁下载」方式提供(广告位由市场承载,插件内不含任何广告 SDK 与请求);
权利边界、支持范围与免责见 license.txt。
兼容性
| 端 | 支持 | 实现方式 | 最低版本 | 相册选图 | 备注 |
|---|---|---|---|---|---|
| Android | √ | 华为 ScanKit com.huawei.hms:scanplus:2.12.0.301 |
API 28(Android 9) | √ | 需云端自定义基座,见「使用前提」1 |
| iOS | √ | 插件内置 ScanKitFrameWork.framework |
iOS 11 | × | 框架无取消回调,见「实现要点」2 |
| HarmonyOS | √ | 系统 @kit.ScanKit startScanForResult |
API 12 | √(系统界面自带) | 无需任何厂商配置 |
| Web | x | utssdk/index.uts 兜底 |
— | — | scan 返回 9050009,getEnvInfo 照常返回 |
| 各小程序 | x | 同上 | — | — | 同上 |
版本数值与 package.json 的平台矩阵、各端 config.json 逐项一致;uni-app 与 uni-app-x 共用同一份原生实现,矩阵取值相同。
使用前提
- Android 必须用云端自定义调试基座验收。
config.json声明了 Maven 依赖(scanplus),本地标准基座不解析这类依赖, 直接「运行到手机或模拟器」会在生成的index.kt报找不到名称“com.huawei”并附官方 known-issue 链接——这是环境限制, 不要为此改动依赖声明(依据:DCloud 官方「带第三方依赖的 UTS 插件需云端编译」口径)。 - 包名与签名:Android 的
AndroidManifest.xml里package="com.bear.plugins.scan"只是插件的清单片段名,会被合并进宿主清单, 不需要与宿主applicationId一致;ScanKit 的本地解码不校验应用身份,无需agconnect-services.json。 如果你同时要接华为登录/支付等要求应用注册的服务,请在宿主工程侧配置,与本插件无关。 - 相机权限:Android 与 iOS 都由本插件在
scan()内部申请,无需宿主重复申请。 Android 清单已声明、含相册选图所需的媒体权限分档;iOS 在「从未申请过」时直接弹系统授权框(info.plist随插件提供NSCameraUsageDescription),被拒后系统不会再弹,此时回9050003并在文案里给出去设置里开启的路径; HarmonyOS 的相机与相册权限由系统扫码界面自理,宿主无需声明任何ohos.permission.*。 - iOS 模拟器不可用:内置 framework 只含真机架构,扫码这类相机能力本身也必须真机验收。
- Android 相册选图依赖媒体权限:
enableAlbum为true(默认)时才会申请图片/视频读取权限;只用实时扫码时传enableAlbum: false可以只申请相机权限,做到权限最小化。 权限档位按机型 API 与宿主targetSdkVersion中较低的那一档取:宿主targetSdkVersion ≥ 33才申请READ_MEDIA_IMAGES(≥ 34再加READ_MEDIA_VIDEO+READ_MEDIA_VISUAL_USER_SELECTED),低于 33 时自动退回READ_EXTERNAL_STORAGE(系统按兼容模式授予媒体读取,相册选图仍可用)。因此低 targetSdk 的老宿主也能直接用, 不需要为接入本插件而升级;想让高版本机型走选择性媒体访问(用户可只勾选部分照片),就把宿主targetSdkVersion提到 34。
快速开始
<template>
<button @click="doScan">扫码</button>
<text>{{ text }}</text>
</template>
<script setup>
import { ref } from 'vue'
import { scan, getEnvInfo } from '@/uni_modules/bear-scan'
const text = ref('未扫码')
function doScan() {
scan({
enableAlbum: true,
success: (res) => {
text.value = `${res.data.scanType}|${res.data.originalValue}`
},
fail: (err) => {
text.value = `code=${err.errCode}:${err.errMsg}`
}
})
}
// 进入页面先看清自己在哪个端、相机是否可用
console.log(getEnvInfo())
</script>
import 只写到插件根目录(@/uni_modules/bear-scan),MUST NOT 指到 utssdk/ 内部文件,否则插件升级就会断。
API
scan(options)
拉起当前端的原生扫码界面,识别到一个码值后关闭界面并回调。无返回值(不返回 Promise),结果只通过回调给出。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| viewType | number | 0 |
仅 Android:取景框样式,透传 ScanKit 的 setViewType;iOS / 鸿蒙使用系统界面,本字段忽略 |
| enableAlbum | boolean | true |
是否允许从相册选图识别。Android 据此决定是否申请媒体权限;HarmonyOS 透传系统界面的 enableAlbum;iOS 当前内置框架版本未开放该入口,无论传什么都只有实时扫码 |
| enableMultiMode | boolean | false |
一码多物(同屏多个码)识别,仅 HarmonyOS 生效;Android 走 ScanUtil.startScan 单码路径,本字段被忽略 |
| scanTypes | Array\<string> | null | null |
只识别指定码型,元素取自下方码型清单;不传或传空数组表示不限;全部非法时回 9050001 |
| success | (res : ScanResult) => void | — | 识别成功 |
| fail | (err : ScanFail) => void | — | 失败,errCode 为 9050xxx |
| complete | (res : any) => void | — | 成功回 ScanResult、失败回 ScanFail,两条路径都必定触发一次 |
成功回调的 ScanResult:
| 字段 | 类型 | 说明 |
|---|---|---|
| code | number | 固定 0,与 fail 分支的 9050xxx 成对,便于业务统一判 code |
| msg | string | 结果描述 |
| data | ScanData | null | 码值;success 分支必定非空 |
ScanData:
| 字段 | 类型 | 说明 |
|---|---|---|
| originalValue | string | 码值原文 |
| scanType | string | 三端归一化后的码型名(下表取值),识别不出时为 FORMAT_UNKNOWN |
| scanTypeCode | number | 统一口径的码型编号(取自鸿蒙 scanCore.ScanType,与 iOS 框架位序 +1 一致);识别不出码型时三端都回 -1,与华为 HmsScan 常量的数值无关 |
失败回调的 ScanFail 继承 UniError:errSubject 固定为 bear-scan,errCode 见「错误码」表,
errMsg = 基础文案 + 厂商原始码/文案(Android 的 ScanUtil 结果码与鸿蒙的 BusinessError.code 都不占
本插件段位,只拼在文案里;iOS 内置框架不回错误码)。
getEnvInfo()
同步查询运行环境与相机状态,开销极小,可在页面 onLoad 里直接调用。返回 ScanEnv:
| 字段 | 类型 | 说明 |
|---|---|---|
| platform | string | 分端文件里是常量 android / ios / harmony;Web 与小程序走兜底,回的是 uni.getSystemInfoSync().osName(如 ios / android / windows)而不是 web / mp,因此判「有没有原生扫码」请用 cameraAvailable(兜底端固定 false) |
| systemVersion | string | Android 为 API level,iOS 为系统版本,鸿蒙为 osFullName,兜底端为 osVersion |
| deviceBrand | string | 设备品牌:Android 取 Build.BRAND、鸿蒙取 deviceInfo.brand,取不到时为 '';iOS 走的是 UIDevice.current.model,回的是 iPhone / iPad 这类机型名而不是品牌 |
| cameraAvailable | boolean | 相机硬件是否可用(Android 查 FEATURE_CAMERA_ANY;iOS / 鸿蒙固定按有相机处理) |
| cameraAuthorization | string | granted / denied / restricted / notDetermined / unknown。只有 iOS 会真实查询;Android 由 scan 内部按需申请、鸿蒙由系统界面自理,两端固定回 unknown |
| albumSupported | boolean | 本端是否支持相册选图:Android 与相机可用性同值,iOS 因内置框架未开放入口如实回 false,鸿蒙固定 true |
码型清单
scanTypes 的入参取值与结果里的 scanType 使用同一套名字,三端一致:
FORMAT_UNKNOWN、AZTEC_CODE、CODABAR_CODE、CODE39_CODE、CODE93_CODE、CODE128_CODE、
DATAMATRIX_CODE、EAN8_CODE、EAN13_CODE、ITF14_CODE、PDF417_CODE、QR_CODE、
UPC_A_CODE、UPC_E_CODE、MULTIFUNCTIONAL_CODE、ONE_D_CODE、TWO_D_CODE
中间 13 个一维/二维码型(AZTEC_CODE … UPC_E_CODE)三端都能精确过滤;MULTIFUNCTIONAL_CODE 只有
Android 与 HarmonyOS 能过滤,ONE_D_CODE / TWO_D_CODE 只有 HarmonyOS 能,FORMAT_UNKNOWN 是结果侧
「码型未知」的占位名、不作为过滤条件。传了本端过滤不了的项时不会报 9050001(它仍是合法名字),
而是在换算各端掩码/枚举时被丢弃,全部丢弃后降级为「不限码型」;要按端精确过滤请只传单条码型名。
实现要点与注意事项
三端行为差异速查(细节见下面的编号条目):
| 行为 | Android | iOS | HarmonyOS |
|---|---|---|---|
| 用户取消 | 9050004(RESULT_CANCELED 或无结果数据) |
无任何回调,下一次 scan 才回 9050005 |
9050006(系统只给 BusinessError,不与失败区分) |
| 相册选图 | enableAlbum 同时控制入口与媒体权限申请 |
忽略,恒实时扫码 | 透传系统界面的 enableAlbum |
| 一码多物 | 忽略(单码路径) | 忽略 | enableMultiMode 生效 |
取景框样式 viewType |
透传 ScanKit setViewType |
忽略(框架界面) | 忽略(系统界面) |
| 相机权限 | scan 内部申请 |
scan 首次弹系统授权框 |
系统扫码界面自理 |
| 码型过滤入参 | 名字 → HmsScan 常量 |
名字 → 统一编号 → 位掩码 | 名字 → scanCore.ScanType 成员 |
- 三端只做「一个码值」。华为 ScanKit 支持连续扫码与多码结果,但三端的连续模式在界面能力、 生命周期与回调时序上差异很大(Android 是 Activity result、iOS 是代理回调、鸿蒙是系统页面), 强行对齐会让业务代码仍需判端。因此本插件把契约收敛成「拉起一次 → 回一个码值」, 连续扫码请由业务侧循环调用(每次都是一个完整的用户交互)。
- iOS 没有「取消」回调(本插件最容易踩的一条)。内置
ScanKitFrameWork的DefaultScanDelegate只有「识别到码」与「相册图片结果」两个方法,头文件里没有取消通道,用户按返回/侧滑关闭界面时 插件收不到任何信号,complete也不会触发。插件的应对是:把当前会话对象持在单例的一个槽位里, 下一次scan发现上一会话仍挂着时回9050005并在文案里提示重新发起——业务侧 MUST 把 「iOS 上用户可能取消且没有任何回调」当成正常情况,不要靠超时自己造取消。 - iOS 的对象持有走单例槽位而不是 Map。原实现用
Map<string, any>缓存扫码对象、结算后不清理, 每扫一次泄漏一个实例;现在结算路径(成功、初始化失败、下一次调用前的挂起检查)都会把槽位置空。 - iOS 的相机授权由插件在首次扫码时代为申请。
scan()先读授权状态:granted直接扫,notDetermined调AVCaptureDevice.requestAccess弹系统框(回调在系统子线程,混编层里已统一切回主线程), 被拒或denied/restricted才回9050003。授权 API 必须放在混编层HmsScanKit.swift: UTS 转译器会把AVCaptureDevice.authorizationStatus(for:)这类 Swift API 原样透传,写在index.uts里就是非法调用。 另外NSCameraUsageDescription缺失时系统不是报错而是直接杀进程,所以utssdk/app-ios/info.plist随插件提供,不可删; 文件名必须是小写info.plist(云端按字面名读取,Info.plist不会被合并进宿主工程)。 - Android 的结果解析留在 Kotlin。
data.getParcelableExtra(ScanUtil.RESULT)返回的是Parcelable, UTS 侧无法安全地转成HmsScan,因此解析放在scankit.kt,与 UTS 之间只走定长字符串数组: 第 2 位回的是归一化码型名(不是HmsScan的常量数值,理由见第 11 条), 码值不能带\0,且 UTS→Kotlin 的Number(str)会按「位累加」而不是十进制解析(编译器已知坑), 所以所有数值都在 Kotlin 侧用String.toInt()转好后以字符串传回。 - Activity result 监听按会话登记、结算即注销。原实现在
handleActivityResult内部无条件offAppActivityResult,会把别的插件正在等的 Activity result 一起摘掉;现在只有requestCode属于本插件时才注销,并且登记/注销都收敛在桥接层的一对私有函数里。 - 权限清单按「机型 API 与宿主 targetSdkVersion 的较低档」分档,且随
enableAlbum收缩。 Android 34+ 走选择性媒体访问(READ_MEDIA_IMAGES+READ_MEDIA_VIDEO+READ_MEDIA_VISUAL_USER_SELECTED三件套,只申请 IMAGES 时相册面板看不到可选内容),33 只要 IMAGES,≤32 用READ_EXTERNAL_STORAGE; 不使用相册时只申请相机权限。分档不能只看机型:系统判定某个媒体权限能不能申请看的是宿主targetSdkVersion,在targetSdk < 33的宿主上申请READ_MEDIA_IMAGES会抛IllegalStateException: Request android.permission.READ_MEDIA_IMAGES permission, The targetSdkVersion SDK must be 33 or more, 而这个异常由UTSAndroid.requestSystemPermission抛出后被 uni 框架转成 JS 异常——插件的fail一个都不回, 业务侧只看到控制台报targetMethod error,且单飞槽位会永久占住(之后每次都回9050005)。 现在取min(机型, targetSdk)选档,低 target 的宿主自动退回READ_EXTERNAL_STORAGE, 另外把申请调用包在try/catch里兜底复位。原实现漏掉了 34+ 的 VIDEO,并存在「权限被拒时既不 fail 也不 complete」 的分支,现已全部走统一收口。 - 厂商错误码一律归类,不占用段位。Android
ScanUtil回传的RESULT_CODE原值、鸿蒙BusinessError.code(100270xxxx一类)等只拼进errMsg,对外只暴露9050段位的 8 个码, 业务侧可以不分端地写switch(iOS 内置框架只有结果回调、不回错误码,因此本端不产生这类原始码)。 归类只承认官方 SDK 中确认存在的三个常量(SUCCESS/RESULT_CODE/ERROR_NO_READ_PERMISSION), 其余按语义标签走,避免猜常量名导致云端编译失败。 - 鸿蒙不区分「取消」与「识别失败」。系统
startScanForResult只回一个BusinessError, 厂商码里取消与失败混在一起,本端不猜常量名、不硬判取消,一律归9050006并把鸿蒙原始码留在errMsg。 业务侧若要区分「用户放弃」与「真的扫不出」,在 Android 判9050004,在鸿蒙只能按「没有结果」统一处理。 - 数字字面量联合类型只有 ArkTS 会硬判(
type ScanErrorCode = 9050001 | …)。厂商原始码与options里回填的数字一律先经core.uts的toScanErrorCode/ScanFailImpl收口(段内保留、段外归9050006并把原数留在文案里),三端才能同时编译通过。 - 跨端只对接码型名,编号是本插件自定义口径。
scanTypeCodeOf在core.uts只写一遍:编号取自鸿蒙scanCore.ScanType(API 10 起的命名:1–14 各码型、100 一维集合、101 二维集合),iOS 内置框架的HMSScanFormatTypeCode是位掩码、位序 +1 后与这套编号逐项一致。Android 的HmsScan.*_SCAN_TYPE属于另一套位掩码(QR=1、AZTEC=2、DATAMATRIX=4 … CODABAR=4096、ALL=8191),与上面两个编号体系都不能 按数值对接,否则 QR 会被读成 AZTEC;因此跨桥只传码型名,掩码换算与结果反查全部留在app-android/scankit.kt,入参用HmsScanAnalyzerOptions.Creator.setHmsScanTypes(int, int...)(ScanKit 无setScanType)。 鸿蒙的ScanOptions.scanTypes声明为Array<scanCore.ScanType>,枚举是名义类型、也不能按字符串动态取成员, 所以app-harmony/index.uts里额外写了「名字 ↔ 枚举成员」两张显式对照表,两端都不做枚举与 number 的隐式转换。 注意 API 9 的鸿蒙枚举是另一套命名(BARCODE_128、PDF417_2D…),本插件最低到 API 12,不兼容那套。scanTypeCode只作辅助,识别不出码型时三端一致回-1,业务判据请用scanType。 - 体积与来源:Android 依赖由云端从 Maven 拉取(
scanplus2.12.0.301,非华为设备可用的完整解码版本, 不含基础版的机型限制);iOS 的二进制随插件提供——Frameworks/ScanKitFrameWork.framework+Resources/ScanKitFrameWorkBundle.bundle(约 4.5 MB,来源为华为 ScanKit iOS 官方 SDK 发布包, LICENSE 随 framework 目录保留)。插件不采集任何数据、不含任何网络请求,也不会从远端拉取原生代码。
错误码
段位 9050,序号 009 固定表示「当前平台不支持」;与 utssdk/unierror.uts 逐项一致。
| errCode | 说明 |
|---|---|
| 9050001 | 扫码参数错误:scanTypes 全部不是本插件支持的码型名(三端都在申请权限、拉起界面之前先校验,不会为了报参数错而先弹授权框) |
| 9050002 | 扫码界面初始化失败:无相机、无可用 Activity/VC,或原生界面拉不起来 |
| 9050003 | 相机权限被拒绝:Android 申请被拒/永久拒绝,或权限清单与宿主 targetSdkVersion 不匹配导致申请失败;iOS 首次由插件弹框被拒,或此前已拒绝(系统不再弹框,需去设置里开启) |
| 9050004 | 用户取消扫码:仅 Android(返回键/侧滑关闭扫码界面);iOS 因框架无取消回调不会产生此码,HarmonyOS 的取消按 9050006 回 |
| 9050005 | 扫码被中断:上一次扫码尚未结束(iOS 含「上一会话仍挂着」) |
| 9050006 | 二维码识别失败:取到画面但解不出码,或厂商未归类错误(原始码拼在 errMsg 里);HarmonyOS 的用户取消也归这一码 |
| 9050007 | 相机或扫码界面被占用:预留语义,当前三端都不会主动回此码(Android ScanUtil.startScan 的非 0 返回值不猜厂商常量,统一按 9050002 回并把原值留在 errMsg) |
| 9050009 | 当前平台不支持:Web、小程序等没有原生实现的端 |
目录结构
bear-scan/ # 独立工程(HBuilderX 直接导入即可跑案例,不参与发布)
├── pages.json # 首屏即案例页 uni_modules/bear-scan/example/index
├── manifest.json # 案例工程配置:name 必须等于插件 id,工程侧只声明相机+震动(插件所需媒体权限在 app-android/AndroidManifest.xml)
├── main.js / App.vue / uni.scss # 标准 uni-app(vue3)工程骨架
└── uni_modules/bear-scan/ # ★ 插件本体:上传插件市场时只上传这一个目录
├── package.json # 元数据与平台矩阵(与 config.json 版本逐项一致)
├── readme.md # 本文件
├── changelog.md # 版本记录
├── license.txt # 授权条款(免费 + 广告解锁)
├── example/index.vue # 案例页:环境检测 + 按端能力显示的扫码按钮,码值进顶部「最近扫码内容」
└── utssdk/
├── interface.uts # 三端共享契约:ScanOptions / ScanResult / ScanErrorCode(9050xxx),只有声明
├── unierror.uts # 错误码表 + ScanFailImpl extends UniError,段内/段外收口
├── core.uts # 跨端纯逻辑:码型归一、统一码型编号、原生错误归类,无任何平台 API
├── index.uts # Web / 小程序兜底:getEnvInfo 降级返回、scan 回 9050009
├── app-android/
│ ├── index.uts # BearScanAndroid 单例 + 薄导出,权限申请与错误归类
│ ├── scankit.kt # 华为 ScanKit 桥接:startScan、Activity result 解析、权限分档、码型名 ↔ HmsScan 常量
│ ├── config.json # minSdkVersion 28 + scanplus 依赖 + agconnect Gradle 插件声明
│ └── AndroidManifest.xml # 相机 / 震动 / 媒体读取权限
├── app-ios/
│ ├── index.uts # BearScanIOS 单例:授权状态校验、位掩码换算、会话槽位
│ ├── HmsScanKit.swift # 框架桥接:present 扫码 VC、结果去重
│ ├── config.json # deploymentTarget 11
│ ├── info.plist # 相机 / 相册用途文案(文件名小写)
│ ├── Frameworks/ # ScanKitFrameWork.framework(华为官方二进制)
│ └── Resources/ # ScanKitFrameWorkBundle.bundle(模型资源与多语言文案)
└── app-harmony/
├── index.uts # BearScanHarmony 单例:startScanForResult 调用与错误归类
└── config.json # minSdkVersion 12(系统 ScanKit,无 har 依赖)
docs/rules/uts-plugin.md 是本仓库的 UTS 插件规范,改本插件前先看 §3(四层分工)与 §6(编码规范)。

收藏人数:
下载插件并导入HBuilder
赞赏(0)
下载 12
赞赏 0
下载 12696233
赞赏 1956
赞赏
京公网安备:11010802035340号