更新记录
1.0.0(2023-06-09)
新版首发
平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:5.0 - 12.0 | armeabi-v7a:支持,arm64-v8a:支持,x86:未测试 | 适用版本区间:11 - 15 |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
KJ-HmsScan
华为统一扫码最新完整版、支持前置摄像头、持续扫码、生成解析条形码二维码、图片多码识别、完全自定义扫码界面(双端)
优惠价的插件,不支持前置摄像头,可以看:https://ext.dcloud.net.cn/plugin?id=12693
注意事项
1. <KJ-HmsScanV2> 完全自定义扫码界面,才支持前置摄像头,前置摄像头扫码成功率会降低,因为大部分都没有聚焦功能
2. andorid 前置摄像头扫码,不支持打开闪光灯
使用
<template>
<view class="content">
<button type="primary" @click="start">开始扫码(自带UI)</button>
<view class="json">{{json}}</view>
<button type="primary" @click="start2">跳转完全自定义扫码界面</button>
<button type="primary" @click="decodeForImage">根据图片识别</button>
<view class="json">{{json2}}</view>
<button type="primary" @click="multiDecodeForImage">根据图片识别(多个码)</button>
<view class="json">{{json3}}</view>
<button type="primary" @click="generateCode">生成码图</button>
<image :src="qrFilePath"></image>
</view>
</template>
<script>
var KJHmsScan = uni.requireNativePlugin("KJ-HmsScanV2");
export default {
data() {
return {
json: null,
json2: null,
json3: null,
qrFilePath: null,
}
},
onLoad() {
if (plus.os.name == 'Android') {
plus.android.requestPermissions(
['android.permission.CAMERA',
"android.permission.READ_EXTERNAL_STORAGE"
],
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
}
);
}
},
methods: {
start() {
/**
* scanTypes - 扫码类型 不传或为null的话,支持所有
* AZTEC CODABAR CODE_39 CODE_93 CODE_128 DATA_MATRIX EAN_8 EAN_13 ITF PDF_417 QR_CODE UPC_A UPC_E
* */
var dic = {
//"scanTypes": ["CODE_128", "CODE_39"],
"viewType": 0 //0(设置扫码标题为“扫描二维码/条码”) 1(设置扫码标题为“扫描二维码”)
}
KJHmsScan.start(dic, (res) => {
console.log("start:" + JSON.stringify(res));
this.json = JSON.stringify(res)
/**
* 返回json字段说明:
* andorid:{"result":{"scanResult":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253","scanType":"QR_CODE",
* "other":{"showResult":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253","cornerPoints":[{"y":183,"x":17},{"y":16,"x":17},{"y":16,"x":183},{"y":182,"x":183}],
* "parserDic":{"theme":"","sceneType":"URL","linkValue":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253"},"scanTypeForm":1006}}}
*
* ios:{"result":{"scanResult":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253",
* "other":{"zoomValue":1,"formatValue":"QR_CODE","time":"4","sceneType":"WebSite",
* "ResultPoint":[{"posY":"845.546120","posX":"38.256096"},{"posY":"77.935369","posX":"38.222356"},{"posY":"77.850768","posX":"393.087168"},
* {"posY":"846.450417","posX":"392.724744"}],"rawBytes":["xxx"],"text":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253",
* "numBits":480,"parserDic":{"url":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253","sceneType":"WebSite"},
* "exposureAdjustmentValue":0},"scanType":"QR_CODE"}}
*
* ios和andorid共同字段:
* scanResult - 扫码结果
* scanType - 码类型
* other - 其它,sdk返回的其它信息
* */
})
},
start2() {
uni.navigateTo({
url: "scan"
})
},
decodeForImage() {
/**
* scanTypes - 扫码类型 不传或为null的话,支持所有
* AZTEC CODABAR CODE_39 CODE_93 CODE_128 DATA_MATRIX EAN_8 EAN_13 ITF PDF_417 QR_CODE UPC_A UPC_E
* */
var dic = {
"scanTypes": ["CODE_128", "CODE_39", "QR_CODE"],
"filePath": plus.io.convertLocalFileSystemURL("static/oneCode.png")
}
KJHmsScan.decodeForImage(dic, (res) => {
console.log("decodeForImage:" + JSON.stringify(res));
this.json2 = JSON.stringify(res)
})
},
multiDecodeForImage() {
/**
* scanTypes - 扫码类型 不传或为null的话,支持所有
* AZTEC CODABAR CODE_39 CODE_93 CODE_128 DATA_MATRIX EAN_8 EAN_13 ITF PDF_417 QR_CODE UPC_A UPC_E
* */
var dic = {
//"scanTypes": ["CODE_128", "CODE_39", "QR_CODE"],
"filePath": plus.io.convertLocalFileSystemURL("static/duoCode.png")
}
//注意事项: andorid版本识别多个码,不能全部识别出来,如果识别单个码,也识别不出来
KJHmsScan.multiDecodeForImage(dic, (res) => {
console.log("multiDecodeForImage:" + JSON.stringify(res));
this.json3 = JSON.stringify(res)
})
},
generateCode() {
var dic = {
"scanType": "CODE_128",
"content": "KJ-HmsScan", //内容
"width": 200,
"height": 200,
"savePath": plus.io.convertLocalFileSystemURL("_doc/KJ-HmsScan"), //保存码图的路径
"format": "png", //保存的图片格式 有效值:png、jpeg
"quality": 100, //保存的图片质量,取值1-100, ios png 无效
/**以下参数,andorid才有效**/
"color": "#ff0000",
"bgColor": "#00FF00",
"margin": 3, //边距
//"QRLogoFilePath": plus.io.convertLocalFileSystemURL("static/logo.png"),
"errorCorrectionLevel": "L" //容错能力,L(可纠正约7%错误) ,M(可纠正约15%错误),Q(可纠正约25%错误),H(可纠正约30%错误)
}
KJHmsScan.generateCode(dic, (res) => {
console.log("generateCode:" + JSON.stringify(res));
this.qrFilePath = res.filePath;
})
}
}
}
</script>
<style>
.json {
word-wrap: break-word;
}
</style>
完全自定义扫码界面nvue
<template>
<view class="content">
<KJ-HmsScanV2 class="hmsScan" ref="hmsScan" :style="{width:'100%',height:palyerHeight}">
</KJ-HmsScanV2>
<view class="head" :style="{top:headTo}">
<image class="back" src="../../static/back.png" @click="backClick"></image>
<text class="text">扫一扫</text>
<image class="album" src="../../static/scanAlbum.png" @click="albumClick"></image>
</view>
<view class="light" @click="lightClick">
<image class="light_image" :src="isLightOn?'../../static/lightOn.png':'../../static/lightOff.png'"></image>
<text class="text">{{isLightOn?'轻触关闭':'轻触照亮'}}</text>
</view>
<view class="btns">
<button class="btn" type="primary" @click="init2">初始化扫码线效果</button>
<button class="btn" type="primary" @click="init3">初始化扫码线效果2</button>
<button class="btn" type="primary" @click="openFrontCamera">打开前置摄像头</button>
<!-- <button class="btn" type="primary" @click="onScanForResult">监听扫码结果</button> -->
<button class="btn" type="primary" @click="pauseContinuouslyScan">暂停持续扫码</button>
<button class="btn" type="primary" @click="resumeContinuouslyScan">恢复持续扫码</button>
<!-- <button class="btn" type="primary" @click="getLightStatus">获取闪光灯状态</button>
<button class="btn" type="primary" @click="switchLight">切换闪光灯</button> -->
</view>
</view>
</template>
<script>
var KJHmsScan = uni.requireNativePlugin("KJ-HmsScanV2");
export default {
data() {
return {
palyerHeight: uni.getSystemInfoSync().screenHeight,
headTo: uni.getSystemInfoSync().statusBarHeight,
lightSrc: "../../static/ug_torch_off_img.png",
isLightOn: false,
json: null,
json2: null,
json3: null,
qrFilePath: null,
}
},
onLoad() {
var globalEvent = uni.requireNativePlugin('globalEvent');
globalEvent.addEventListener('customizedScanDelegateForResult', function(e) {
console.log('customizedScanDelegateForResult' + JSON.stringify(e));
});
if (plus.os.name == 'Android') {
plus.android.requestPermissions(
['android.permission.CAMERA',
"android.permission.READ_EXTERNAL_STORAGE"
],
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
}
);
}
},
onReady() {
setTimeout((res) => {
this.init2();
}, 500);
this.onScanForResult();
},
methods: {
init(scanLine) {
/**
* scanTypes - 扫码类型 不传或为null的话,支持所有
* AZTEC CODABAR CODE_39 CODE_93 CODE_128 DATA_MATRIX EAN_8 EAN_13 ITF PDF_417 QR_CODE UPC_A UPC_E
* */
var dic = {
//"scanTypes": ["CODE_128", "CODE_39", "QR_CODE"],
"isContinuouslyScan": true, //是否持续扫码
"scanLine": scanLine,
// "scanLine": { //扫码线,不配置,默认不显示
// "filePath": plus.io.convertLocalFileSystemURL("../../static/ug_animation_img.png"),
// "x": 0,
// "y": 0,
// "width": uni.getSystemInfoSync().screenWidth, //不配置,默认是组件的宽度
// "toY": this.palyerHeight, //动画到y的位置,不配置,默认是组件的高度
// "height": 30,
// "animateDuration": 2,
// "isAutoReverse": false, //true(上下来回移动) false(向下移动结束,从头开始)
// },
// "boundingBox": { //andorid识别区域
// "left": 0,
// "top": 0,
// "right": uni.getSystemInfoSync().screenWidth,
// "bottom": this.palyerHeight
// },
// "cutArea": { //ios识别区域
// "x": 0,
// "y": 0,
// "width": uni.getSystemInfoSync().screenWidth,
// "height": this.palyerHeight,
// }
}
console.log(JSON.stringify(dic))
this.$refs.hmsScan.init(dic, (res) => {
console.log("init:" + JSON.stringify(res));
})
},
init2() {
var scanLine = { //扫码线,不配置,默认不显示
"filePath": plus.io.convertLocalFileSystemURL("../../static/scanLine.png"),
"x": 0,
"y": 0,
"width": uni.getSystemInfoSync().screenWidth, //不配置,默认是组件的宽度
"toY": this.palyerHeight, //动画到y的位置,不配置,默认是组件的高度
"height": 30,
"animateDuration": 2,
"isAutoReverse": false, //true(上下来回移动) false(向下移动结束,从头开始)
}
this.init(scanLine);
},
init3() {
var scanLine = { //扫码线,不配置,默认不显示
"filePath": plus.io.convertLocalFileSystemURL("../../static/scanLine2.png"),
"x": 100,
"y": 300,
"width": uni.getSystemInfoSync().screenWidth - 200, //不配置,默认是组件的宽度
"height": 30,
"toY": this.palyerHeight - 300, //动画到y的位置,不配置,默认是组件的高度
"height": 30,
"animateDuration": 1,
"isAutoReverse": true, //true(上下来回移动) false(向下移动结束,从头开始)
}
this.init(scanLine);
},
onScanForResult() {
//监听扫码结果
this.$refs.hmsScan.onScanForResult((res) => {
console.log("onScanForResult:" + JSON.stringify(res));
uni.showModal({
title: '提示',
content: JSON.stringify(res),
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
/**
* 返回json字段说明:
* andorid:{"result":{"scanResult":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253","scanType":"QR_CODE",
* "other":{"showResult":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253","cornerPoints":[{"y":183,"x":17},{"y":16,"x":17},{"y":16,"x":183},{"y":182,"x":183}],
* "parserDic":{"theme":"","sceneType":"URL","linkValue":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253"},"scanTypeForm":1006}}}
*
* ios:{"result":{"scanResult":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253",
* "other":{"zoomValue":1,"formatValue":"QR_CODE","time":"4","sceneType":"WebSite",
* "ResultPoint":[{"posY":"845.546120","posX":"38.256096"},{"posY":"77.935369","posX":"38.222356"},{"posY":"77.850768","posX":"393.087168"},
* {"posY":"846.450417","posX":"392.724744"}],"rawBytes":["xxx"],"text":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253",
* "numBits":480,"parserDic":{"url":"https://itunes.apple.com/cn/app/hello-uni-app/id1417078253","sceneType":"WebSite"},
* "exposureAdjustmentValue":0},"scanType":"QR_CODE"}}
*
* ios和andorid共同字段:
* scanResult - 扫码结果
* scanType - 码类型
* other - 其它,sdk返回的其它信息
* */
})
},
openFrontCamera() {
//需要换为后置摄像头,执行init方法即可
this.$refs.hmsScan.openFrontCamera()
},
pauseContinuouslyScan() {
this.$refs.hmsScan.pauseContinuouslyScan()
},
resumeContinuouslyScan() {
this.$refs.hmsScan.resumeContinuouslyScan()
},
getLightStatus() {
this.$refs.hmsScan.getLightStatus((res) => {
console.log("getLightStatus:" + JSON.stringify(res));
})
},
switchLight() {
this.$refs.hmsScan.switchLight((res) => {
console.log("switchLight:" + JSON.stringify(res));
})
},
backClick() {
uni.navigateBack();
},
albumClick() {
uni.chooseImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function(res) {
console.log(JSON.stringify(res.tempFilePaths));
var filePath = res.tempFilePaths[0].replace('file://', '')
var dic = {
//"scanTypes": ["CODE_128", "CODE_39", "QR_CODE"],
"filePath": filePath
}
KJHmsScan.decodeForImage(dic, (res) => {
console.log("decodeForImage:" + JSON.stringify(res));
uni.showModal({
title: '提示',
content: JSON.stringify(res),
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
})
}
});
},
lightClick() {
this.isLightOn = !this.isLightOn;
this.switchLight();
}
}
}
</script>
<style>
.hmsScan {
justify-content: center;
align-items: center;
background-color: black;
}
.head {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 44px;
padding-left: 16px;
padding-right: 16px;
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.text {
color: white;
}
.back {
width: 50rpx;
height: 50rpx;
}
.album {
width: 60rpx;
height: 60rpx;
}
.light {
position: absolute;
top: 100px;
left: 0;
right: 0;
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-items: center;
justify-content: center;
}
.light_image {
width: 60rpx;
height: 120rpx;
}
.light>.text {
font-size: 14px;
margin-top: 8px;
}
.btns {
position: fixed;
bottom: 0;
left: 0;
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-items: flex-start;
justify-content: center;
}
.btn {
font-size: 10px !important;
}
</style>