MLKitCodeScanner 拓展
基于 Google ML Kit 捆绑(离线)模型的条码 / 二维码识别拓展。
两种用法:识别相册或素材里的图片,或者打开摄像头实时扫描。
为什么选它:
- 完全离线。识别模型随
.aix一起打包,设备不需要安装 Google Play 服务,断网也能用 —— 这对国内设备很关键。 - 不用先”初始化”。识别器按需创建,拖进来设好属性就能直接调方法。
- 认出内容类型。扫到网址、WiFi 配置、名片、短信等结构化二维码时,除通用事件外还会触发对应的专用事件,字段已经拆好,不用自己解析。
支持的条码格式:
| 类别 | 格式 |
|---|---|
| 二维码 | QR Code、Data Matrix、PDF417、Aztec |
| 一维条码 | EAN-13、EAN-8、UPC-A、UPC-E、Code-39、Code-93、Code-128、ITF、Codabar |
权限:摄像头(实时扫描用)、读取图片(识别图片文件用)。均在运行时自动申请。
打包架构:arm64-v8a + armeabi-v7a + x86 + x86_64(含模拟器)。
- .aix 拓展下载:
cn.fun123.MLKit.CodeScanner.aix
快速上手
一、扫图片里的二维码
设计器里放一个 MLKitCodeScanner、一个按钮、一个标签,再放一个「图像选择器」用来选图。
when 图像选择器1.AfterPicking() {
CodeScan1.RecognizeFromFile(图像选择器1.Selection)
}
when CodeScan1.GotBarcode(rawValue, format, valueType, displayValue, detailJson) {
标签1.Text = rawValue
}
when CodeScan1.NoBarcodeFound(operation) {
标签1.Text = "这张图里没有找到条码"
}
二、摄像头实时扫描
- 设计器里放一个垂直布局(或水平布局),把它的宽度设为「充满」、高度设为 300 像素 —— 这就是预览画面的位置。
- 选中
MLKitCodeScanner,把预览容器(PreviewContainer) 属性选成刚才那个布局。 - 代码块里直接调
开始扫描:
when 按钮_开始.Click() {
CodeScan1.StartScan()
}
when 按钮_停止.Click() {
CodeScan1.StopScan()
}
when CodeScan1.GotBarcode(rawValue, format, valueType, displayValue, detailJson) {
标签1.Text = rawValue
标签2.Text = join("格式:", format, " 类型:", valueType)
}
when CodeScan1.ScanFailed(operation, errorMessage) {
标签1.Text = join("出错(", operation, "):", errorMessage)
}
默认扫到第一个条码就自动关摄像头。想连续扫多个,把
连续识别(ContinuousScan)设为「真」—— 同一个条码在 1.5 秒内不会重复触发。
三、扫 WiFi 二维码并显示密码
扫到结构化二维码时,通用事件和专用事件都会触发,用哪个看需要。
when CodeScan1.GotWifi(ssid, password, encryption) {
标签_SSID.Text = join("网络名:", ssid)
标签_密码.Text = join("密码:", password)
标签_加密方式.Text = join("加密方式:", encryption)
CodeScan1.StopScan()
}
四、只扫二维码(提速)
条码格式认得越少,识别越快。只做二维码扫描时把 条码类型 属性设成 qr:
when Screen1.Initialize() {
CodeScan1.Formats = "qr"
CodeScan1.ContinuousScan = true
}
五、扫码开灯(暗环境)
when 按钮_闪光灯.Click() {
if CodeScan1.Torch {
CodeScan1.Torch = false
按钮_闪光灯.Text = "开灯"
} else {
CodeScan1.Torch = true
按钮_闪光灯.Text = "关灯"
}
}
属性
- Formats
- 要识别的条码类型,多个用英文逗号分隔,填
all表示全部(默认)。 可选值:qr、datamatrix、pdf417、aztec、ean13、ean8、upca、upce、code39、code93、code128、itf、codabar。 只勾选实际需要的类型可以显著提升识别速度,例如做付款码扫描只填qr。 - PreviewContainer
- 用来显示摄像头预览画面的可见组件,一般选一个水平布局或垂直布局。 该布局需要有明确的宽高(例如宽度「充满」、高度 300 像素),否则可能看不到画面。 只有实时扫描才需要设置;只识别图片时可以留空。
- ContinuousScan
- 实时扫描是否连续识别。 「假」(默认)= 扫到第一个条码就自动停止摄像头; 「真」= 持续扫描,适合连续扫多个条码,同一个条码在 1.5 秒内不会重复触发。
- Torch
- 闪光灯(手电筒)开关,仅在实时扫描进行中有效。暗环境扫码时打开。
- Scanning
- 只读。摄像头实时扫描是否正在进行。
- Busy
- 只读。是否正在识别图片。识别期间再次调用识别方法会触发
ScanFailed。
事件
- GotBarcode(rawValue,format,valueType,displayValue,detailJson)
- 扫到条码就会触发,任何类型都触发,是最常用的事件。
rawValue— 条码原始内容。format— 条码格式,如QR_CODE、EAN_13。valueType— 内容类型,如URL、WIFI、TEXT、PRODUCT、ISBN。displayValue— 适合直接显示给用户的文本(ML Kit 已做过整理)。detailJson— 结构化详情 JSON,含边界坐标bounds、四角坐标cornerPoints,以及该类型的全部字段。
- GotUrl(title,url)
- 扫到网址类二维码。
- GotWifi(ssid,password,encryption)
- 扫到 WiFi 配置二维码。
encryption为OPEN、WPA或WEP。 - GotContact(name,phone,email,organization,title,address,urls)
- 扫到名片(联系人)二维码。多个电话/邮箱只给第一个,完整列表见
detailJson;多个网址用英文逗号分隔。 - GotEmail(address,subject,body,type)
- 扫到电子邮件二维码。
type为WORK、HOME或UNKNOWN。 - GotPhone(number,type)
- 扫到电话号码二维码。
type为WORK、HOME、FAX、MOBILE或UNKNOWN。 - GotSms(phoneNumber,message)
- 扫到短信二维码。
- GotGeoPoint(latitude,longitude)
- 扫到地理位置二维码。
- GotCalendarEvent(summary,description,location,start,end)
- 扫到日历事件二维码。时间为
yyyy-MM-dd HH:mm:ss文本,缺省时为空。 - GotDriverLicense(firstName,lastName,licenseNumber,birthDate,expiryDate)
- 扫到驾照 / 身份证件条码(主要是北美 PDF417 规范,国内证件一般不适用)。
- NoBarcodeFound(operation)
- 图片里没有找到任何条码。
operation是发起识别的方法名。 只有图片识别会触发;实时扫描每帧扫不到是正常的,不会触发。 - ScanFailed(operation,errorMessage)
- 识别或扫描失败。
operation是出错的方法名,便于定位。
方法
- RecognizeFromFile(path)
- 识别图片文件中的条码。
path可以是素材文件名、设备绝对路径、file://或content://地址 (「图像选择器」的选中项可以直接传进来)。 识别到条码触发GotBarcode(一张图有多个条码会逐个触发),没找到触发NoBarcodeFound。 - RecognizeFromBase64(base64)
- 识别 Base64 图片中的条码。支持纯 Base64,也支持带
data:image/...;base64,前缀的写法。 - StartScan()
- 打开摄像头开始实时扫描,预览画面显示在
预览容器属性指定的组件里。 没设预览容器会触发ScanFailed并给出提示。 App 退到后台会自动释放摄像头,回到前台自动恢复扫描。 - StopScan()
- 停止实时扫描并移除预览画面。
运行环境:AI 伴侣联机需要 Android 11 及以上
本拓展的识别模型放在依赖库自带的 assets 里,AI 伴侣联机调试要把它挂进
AssetManager,用的是 Android 11(API 30)才有的 ResourcesLoader —— 这是系统提供的
唯一公开办法,更低版本没有等价 API。所以:
| 运行方式 | Android 6 ~ 10 | Android 11 及以上 |
|---|---|---|
| 打包 APK | ✅ 正常 | ✅ 正常 |
| AI 伴侣联机 | ❌ 模型加载不了 | ✅ 正常 |
打包 APK 之所以不受限制,是因为模型在编译时就被并进了 APK 的 assets,装到手机上 就是 App 自己的资源,与系统版本无关。伴侣的 APK 是提前编好装在手机上的,运行时没法 往自己已安装的包里加文件,只能靠系统的运行时挂载 API。
低版本设备上想验证功能,直接打包 APK 测即可;要用伴侣边改边调,请换 Android 11+ 的设备。
常见问题
扫描界面一片空白 / 看不到画面。
预览容器 那个布局没有实际尺寸。给它明确的宽高(宽度「充满」、高度 300 像素以上),别用「自动」。
一维条码扫不出来。
一维条码需要横向占满取景框、离得近一些、光线足够。另外确认 条码类型 属性没有限制成只认二维码。
识别很慢 / 手机发烫。
把 条码类型 限定成实际需要的几种(例如只填 qr)。全类型识别每帧都要跑十几种解码器。
.aix 为什么有 12MB?
离线识别模型(4 个 CPU 架构)都打包在里面了,这是”不依赖 Google Play 服务”的代价。
如果只发布给有 GMS 的设备,理论上可以换用体积小得多的联网变体,但国内设备普遍没有 GMS,所以本拓展固定用离线方案。
能生成二维码吗? 不能,本拓展只做识别。生成二维码请用 App Inventor 自带的相关拓展或在线接口。
扫码添加客服咨询