后续
后续就是下面两方法都无法解决http的问题,安卓开发说不是混合开发吗?你让我来调摄像头,有值传你不就行了。。。
具体方法:点扫码时调安卓函数,让安卓知道要扫码了,然后在main.js
绑定事件window.android.scanBarcode()
(备注:事件名字是安卓给的,相当于自己取的函数名称,后面这个一样,别被误导了),安卓扫码后触发一个window.handleScanResult
,这个事件传值回来,把window事件赋值给自己的this.什么的vue函数事件就行了,下面看看我的源代码
dome.vue
// 扫码
scanCode() {
this.$toast({
title: '测试-1.5s后进入扫码'
}, () => {
console.log('测试扫码');
// 核心是调安卓的函数
if (window.android) {
window.android.scanBarcode()
}
})
},
// 监听扫码结果,和下面的main.js相呼应
watch: {
'$store.state.scanCode'(newVal) {
if (newVal) {
this.form.CowID = newVal
this.$store.commit('setScanCode', '')
}
}
},
main.js
// 处理扫码
window.handleScanResult = (result) => {
//我这里是存vuex中,存本地或者其他方式也可以
store.commit('setScanCode', result)
}
上面是后续,下面是原文:
说明
只支持https域名
只支持https域名
只支持https域名因为uniapp自带的api不支持h5,而且非微信环境也无法使用公众号jsjdk的扫码,只能尝试其他方法
但是发现只能https域名才可以调用,其他所有人的都不许http域名。
开发调试记得去把这两个点起来,manifest.json => web配置 => 启动https协议 ,和 App模块配置 => 打包模块配置 => Barcode扫码(相当于你在源码视图加
“<uses-feature android:name=“android.hardware.camera”/>”,
“<uses-feature android:name=“android.hardware.camera.autofocus”/>”,)
效果图
html5-qrcode
下载插件
npm i html5-qrcode
组件代码:
<template>
<view class="dialog-mask" v-if="value">
<view class="dialog-box">
<view id="qr-reader"></view>
</view>
</view>
</template>
<script>
// html5-qrcode的扫码,只支持https,
// <scanCode v-model="showScan" @success="getScan" @err="err"></scanCode>
// showScan显示 @success成功回调 @err失败回调
import {
Html5Qrcode
} from "html5-qrcode";
export default {
name: 'Scan',
model: {
props: 'value',
event: 'close'
},
props: {
value: {
type: Boolean,
default: false
},
},
watch: {
value(val) {
if (val) {
this.$nextTick(() => {
this.getCameras()
})
}
},
},
data() {
return {
cameraId: '',
html5QrCode: '',
}
},
beforeDestroy() {
this.stop()
},
methods: {
getCameras() {
uni.showLoading({
title: '相机启动中...',
icon: 'none'
})
Html5Qrcode.getCameras()
.then((devices) => {
/**
* devices 是对象数组
* 例如:[ { id: "id", label: "label" }]
*/
if (devices && devices.length) {
if (devices.length > 1) {
this.cameraId = devices[1].id
} else {
this.cameraId = devices[0].id
}
console.log(this.cameraId, 'cameraId')
this.start()
}
})
.catch((err) => {
this.close()
console.log(err);
uni.showToast({
title: '启用相机失败' + err,
icon: 'none'
})
})
},
start() {
this.html5QrCode = new Html5Qrcode('qr-reader')
setTimeout(() => {
uni.hideLoading()
}, 1500)
this.html5QrCode
.start(
this.cameraId, // 传入cameraId参数,这个参数在之前的步骤中已经获取到.
{
fps: 10, // 设置摄像头的帧率为10帧每秒
qrbox: {
width: 300,
height: 300
}, // 设置需要扫描的QR码区域,这里设置的是300x300的区域
aspectRatio: 1.777778, // 设置扫描结果的宽高比为1.777778,即宽高比为根号2,即等腰梯形的宽高比
},
(qrCodeMessage) => {
// 当成功读取到QR码时,执行此回调函数
if (qrCodeMessage) {
this.qrCodeMessage = qrCodeMessage
this.$emit('success', qrCodeMessage)
this.close()
this.stop()
}
},
(errorMessage) => {},
)
.catch((err) => {
// 如果扫描启动失败,执行此catch块中的代码
uni.showToast({
title: `扫码失败:${err}`,
icon: 'none'
})
})
},
stop() {
this.html5QrCode &&
this.html5QrCode.stop().finally(() => {
this.html5QrCode.clear()
this.html5QrCode = null
})
},
close() {
this.$emit('close', false)
},
},
}
</script>
<style lang="scss" scoped>
.dialog-mask {
position: fixed;
top: 0;
left: 0;
z-index: 99;
height: 100vh;
width: 100vw;
background-color: rgba(0, 0, 0, 0.7);
.dialog-box {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
#qr-reader {
width: 750rpx;
}
}
}
</style>
使用
自己导入注册使用。或者uniapp项目直接放components文件夹,scanCode文件夹和scanCode.vue同名(俺就是用这种方法)。然后使用v-model的,showScan控制显示隐藏(底层v-if),自己手动控制相机开关,然后@success成功回调,@err失败回调
<scanCode v-model="showScan" @success="getScan" @err="err"></scanCode>
getScan(val) {
console.log('扫码成功', val);
alert(val)
},
err(err) {
console.log(err);
alert(err)
},
mumu-getQrcode(更强大)
插件市场地址:(H5调用摄像头识别二维码(原生H5调用,不需要任何sdk,本地扫描识别,不需要后端)): https://ext.dcloud.net.cn/plugin?id=7007#detail
HBX导入就行了,引入,注册,使用
// html,放在外层相当于弹出层一样
<view class="scanCode" v-if="showScan">
<mumu-get-qrcode @success='qrcodeSucess' @error="qrcodeError"></mumu-get-qrcode>
</view>
// js
import mumuGetQrcode from '@/uni_modules/mumu-getQrcode/components/mumu-getQrcode/mumu-getQrcode.vue'
components: {
mumuGetQrcode
},
qrcodeSucess(data) {
this.$toast({
title: data || '扫码成功'
})
this.showScan = false
},
qrcodeError(err) {
this.$toast({
title: err + '' || '扫码错误'
})
this.showScan = false
},
// css
.scanCode {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.7);
}