【uniapp安卓原生语言插件】之华为统一扫码插件【保姆级】开发教程。
事先提醒:本文技术栈 安卓原生部分:java + uni部分:vue2
Android Studio版本:Android Studio Narwhal 3 Feature Drop | 2025.1.3
HbuildX版本:4.76
APP离线SDK版本:Android-SDK@4.76.82455_20250822
第一步 下载
先看官网教程开发者须知 | uni安卓原生语言插件开发教程
根据官网链接,下载需要软件和代码即可(需要Android Studio、HbuildX、APP离线SDK以及其中包含的原生demo项目),后续我来教你。
第二步 构建
首先我们看向下载好的App离线SDK,将其解压,因为这里面有原生插件的demo项目,UniPlugin-Hello-AS,我们使用Android Studio(后续简称AS)中打开。

进入到以下界面

然后大家会发现,下载奇慢无比,如果是有经验的程序员可能已经准备打开魔法了。不过总会有一些人没有魔法,或者无法使用魔法,所以现在我来教大家不使用魔法跑起原生项目的方法。
首先,我们先点击右下角的x停止龟速下载。然后开始修改项目配置。
一、项目级别gradle文件夹下的gradle-wrapper.properies
将中间部分替换成腾讯云仓库mirrors.cloud.tencent.com/gradle

二、项目级别的build.gradle
改为
增加了
rust
maven {url 'https://maven.aliyun.com/repository/google'}
maven {url 'https://maven.aliyun.com/repository/gradle-plugin'}
视情况可以加上
rust
maven {url 'https://maven.aliyun.com/repository/jcenter'}
然后我们就可以点击右上角二点try again。如果你stop失败,也可以关闭项目重新打开就会自动重新下载。(PS:可以简单解释下,jcenter已经跑路了,所以注释或替换,google仓库阿里的不全会有的找不到所以原来的要保留,至于gradle-plugin是因为替换完后依旧有库找不到,库的名字包含gradle-plugin遂加上。) 如果个别仓库找不到,你可以试着加上或删除一些仓库重新同步。
然后就构建成功了

第三步 创建
我们保持已有module的命名来加一个uniplugin_hmsscan(在左侧顶层文件夹右键创建Module) 一定一定要注意左侧选Library (PS:我就是一开始选错了,导致有些截图的左侧列表不太一样)
顺带一提,这两没用可以删
第四步 接入华为统一扫描SDK
一、整理依赖
根据最开始的DCLOUD官网教程,我们新建的module是不能直接用的,需要调整依赖。
官网的例子有多余的库,实际上浏览demo中其他几个库能发现,将上述图片用以下依赖替换即可
php
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar'])
compileOnly 'androidx.recyclerview:recyclerview:1.0.0'
compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
compileOnly 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.alibaba:fastjson:1.2.83'
implementation 'com.facebook.fresco:fresco:1.13.0'
}
二、接入华为统一扫描
首先我们需要学习华为统一扫描的教程集成HMS Core SDK-开发准备-Android-统一扫码服务 - 华为HarmonyOS开发者,建议从链接处开始阅读即可,且agc部分并不是必须的,关于agc部分的都可以跳过。网上也有很多集成攻略,就不详细讲解了。
由于后续我们插件要打包aar所以只能使用联网下载依赖,不能使用libs方案(已踩坑),
1、依赖联网下载
照着往项目里加
然后点右上角Sync Now
三、编写主要代码
右键新建名为HmsScanModule 的java文件 写入以下代码
java
package com.example.uniplugin_hmsscan;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.huawei.hms.hmsscankit.ScanUtil;
import com.huawei.hms.ml.scan.HmsScan;
import com.huawei.hms.ml.scan.HmsScanAnalyzerOptions;
import io.dcloud.feature.uniapp.common.UniModule;
import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
/**
* date: 2025/9/25
* author: 落叶霞枫
* remake:
**/
public class HmsScanModule extends UniModule {
private static final int REQUEST_CODE_SCAN = 0X01;
private UniJSCallback successCallback;
private UniJSCallback errorCallback;
@UniJSMethod(uiThread = true)
public void startScan(UniJSCallback successCallback, UniJSCallback errorCallback) {
this.successCallback = successCallback;
this.errorCallback = errorCallback;
Context context = mUniSDKInstance.getContext();
if (!(context instanceof Activity)) {
if (errorCallback != null) {
errorCallback.invoke("当前上下文无效");
}
return;
}
Activity activity = (Activity) context;
//启动扫描Acticity
try {
ScanUtil.startScan(activity, REQUEST_CODE_SCAN, new HmsScanAnalyzerOptions.Creator().create());
} catch (Exception e) {
Log.e("HMSScan", "启动扫描失败", e);
if (errorCallback != null) {
errorCallback.invoke("启动扫描失败: " + e.getMessage());
}
}
}
// 接收扫码结果
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SCAN) {
if (data != null && successCallback != null) {
HmsScan obj = data.getParcelableExtra(ScanUtil.RESULT);
if (obj != null) {
Log.d("HMSScan", "扫码结果: " + obj.originalValue);
// 返回给JS
successCallback.invoke(obj.originalValue);
} else {
errorCallback.invoke("未识别到内容");
}
} else if (errorCallback != null) {
errorCallback.invoke("扫描取消或无返回数据");
}
}
}
}
四、调整module清单,并声明activity
这是新建之后的清单 改为以下内容(由于我们要跳转打开华为扫码界面,所以我们需要声明华为扫码界面,类似uniapp的pages声明)
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.uniplugin_hmsscan">
<application>
<activity android:name="com.huawei.hms.hmsscankit.ScanKitActivity"/>
</application>
</manifest>
第五步 离线测试
众所周知,uniapp主要是在线打包,哪怕自定义基座都是有隐藏次数限制的,且需要排队,所以测试我们代码是否能正常运行,我们可以先考虑离线测试。参考文档uni-app原生插件集成指南 | uni小程序SDK。
我们先来把AS里的东西搞好
一、干掉没用的模块
记得Sync Data
二、修改dcloud_uniplugins.json

接下来让我们去到HbuildX
三、创建一个新的test-hms-scan项目
注意我选的vue2 这是自动生成的代码
我们简单加个按钮调用我们写的原生插件代码
一定一定要记得保存代码(ctrl+s)
js
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<button @click="scan">扫码</button>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
this.HmsScan = uni.requireNativePlugin('HmsScan');
},
methods: {
scan() {
this.HmsScan.startScan(
res => {
uni.showToast({
title: res,
icon:'none'
})
},
err => {
uni.showToast({
title: err,
icon:'none'
})
}
);
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
四、制作离线包
如果是第一次,那肯定会有一些提示,跟着提示登陆,获取appid等就行。
五、离线资源替换到AS项目
我们带着打包好的离线资源回到AS项目里
1.替换资源
关闭文件夹路径合并,或者在系统文件管理里操作 直接删掉原来的__UNI__E
替换成我们刚刚打包的
2.修改配置
找到app下assets里的data里的dcloud_control.xml 改为
xml
<hbuilder>
<apps debug="true" syncDebug="true">
<app appid="__UNI__909A1B1" appver=""/>
</apps>
</hbuilder>
appid取刚刚离线打包出来的文件夹名,增加debug="true" syncDebug="true"
3.修改清单文件
打开app的清单,滑到最下面 根据提示,我们打开DCLOUD开发者中心登录 。可以看到我们刚刚创建的test-hms-scan 项目。
点击应用名称蓝色超链接跳转。
新增APP离线id
三个必填,包名、SHA1、SHA256
由于我们用的demo,所以包名就是app级build.gradle里的applicationId com.android.UniPlugin 怎么获取SHA1和SHA256呢?需要使用java环境里的keytool 工具(PS:demo的密钥库密码是123456 在demo里有写)
如果你电脑的java环境是java8,那么出来的结果可能只有SHA1,因为java8及以下版本不支持SHA256。你需要自己下一个大于java8的版本。或者百度、ai其他方法。
4.提交后生成离线key

5.回到AS项目app级清单文件里填写appkey

6.编译获取apk安装包
在AS右侧点开Gradle工具栏,找到app级的task工具,双击assemble 等待编译。(PS:理论上直接run也可以,但是可能依赖相关需要调整,插曲有点多。) 成功后可以在此路径下找到apk,然后就可以找个安卓设备安装了
编译小插曲1 按提示将uniplugin_hmsscan模块的build.gradle的minSdk降级为21(因为主app的minsdk是21)
编译小插曲2
按提示将app的build.gradle的target升级到33
7.测试
注意,华为统一扫码是需要拍照和媒体动态申请权限 的,为了方便,我没写,在设置里手动赋予应用的(可以在原生写,也可以在uni调用插件前写)。
第六步,做成插件包
还是AS右侧Gradle工具,这次我们选择我们的插件模块,双击assemble 我们就得到了插件aar包
第七步,回到uniapp使用插件包
首先我们按这个格式创建nativeplugins文件夹,用来存放插件 其中package.json是与android文件夹同层级的,内容为
json
{
"name": "uniplugin_hmsscan",
"id": "uniplugin_hmsscan",
"version": "1.0.0",
"description": "Android华为统一扫码插件",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"android": {
"plugins": [{
"type": "module",
"name": "HmsScan",
"class": "com.example.uniplugin_hmsscan.HmsScanModule"
}],
"integrateType": "aar",
"minSdkVersion": "21",
"dependencies": [
"com.huawei.hms:scanplus:2.12.0.301"
]
}
}
}
然后我们需要在清单中勾选我们的本地插件 然后就可以打自定义基座或者正式包 了!!! 结果如下
最后的最后,如果你发现dependencies配置无法生效,安装包中始终缺少依赖。可以尝试手动加libs