记录vue用 html5+做移动APP 用barcode做扫一扫功能时安卓 的bug(黑屏、错位等等)和解决方法
最近做项目时,要用到扫一扫二维码的功能,在html5+里面有提供barcode功能,于是照过来用了,
写的代码如下 :
扫码页面:
<style lang="less" scoped>
#camera {
height: %;
width: %;
.van-icon {
top: -2px;
font-size: 30px;
color: #fff;
&.back {
left: 10px;
}
&.light {
right: 10px;
}
}
#scan {
width: %;
height: %;
z-index: ;
position: fixed;
left: ;
top: ;
background: rgba(, , , );
}
.tips {
text-align: center;
position: absolute;
width: %;
top: %;
color: #fff;
z-index: ;
left: %;
}
.action {
position: fixed;
z-index: ;
width: %;
left: ;
bottom: ;
.items {
display: flex;
justify-content: space-around;
background: rgba(, , , 0.35);
width: %;
padding: 4px;
margin: 4px auto;
.item {
flex-basis: 50px;
text-align: center;
img {
width: 27px;
}
}
}
}
}
</style>
<template>
<div id="camera">
<div id="scan"></div>
<div class="tips">"加载中...</div>
<div class="action">
<div class="items">
<div
class="item"
@click="openLight"
><img src="../assets/img/png-60@3x.png"></div>
<div
class="item"
@click="getPicture()"
><img src="../assets/img/png-59@3x.png"></div> <div
class="item"
@click="cancelScan()"
><img src="../assets/img/png-61@3x.png"></div>
</div>
</div>
</div>
</template> <script type='text/ecmascript-6'>
let scan = null;
export default {
data() {
return {
codeUrl: "",
isLight: false,
showEnter: false,
extra: null,
type: ""
};
}, mounted() {
if (window.plus) {
let s = plus.navigator.checkPermission("camera");
if (s !== "notdeny") {
plus.nativeUI.alert("相机权限未获取,请往设置应用程序里面开启权限!");
}
}
this.startScan(); //`进入页面就调取扫一扫
},
beforeDestroy() {
if (!window.plus) return;
scan.cancel();
scan.close();
},
methods: {
// 打开闪光灯
openLight() {
this.isLight = !this.isLight;
scan.setFlash(this.isLight);
}, //创建扫描控件
startRecognize() {
let that = this;
if (!window.plus) return; scan = null;
scan = new plus.barcode.Barcode(
"scan",
[plus.barcode.QR, plus.barcode.EAN8, plus.barcode.EAN13],
{
frameColor: "#1294cb",
scanbarColor: "#1294cb",
top: "100px",
left: "0px",
width: "100%",
height: "500px",
position: "fixed"
}
); scan.onmarked = onmarked;
function onmarked(type, result, file) {
result = result.replace(/\n/g, "");
that.storage.save("cameraData", result);
that.codeUrl = result; //扫描后返回值
that.$router.go(-);
}
},
// //开始扫描
startScan() {
if (!window.plus) return;
this.startRecognize(); //创建控件
setTimeout(() => {
scan.start();
}, );
},
// 取消扫描
cancelScan() {
let l = plus.webview.all().length;
this.$toast(l);
if (l > ) {
let ws = plus.webview.currentWebview();
plus.webview.close(ws);
} else {
this.$router.go(-);
}
// this.$router.go(-1);
if (!window.plus) return;
plus.navigator.setStatusBarStyle("dark");
if (scan) {
scan.cancel(); //关闭扫描
scan.close(); //关闭条码识别控件
}
},
getPicture() {
plus.gallery.pick(src => {
plus.barcode.scan(
src,
(type, result) => {
scan.cancel(); //关闭扫描
scan.close();
this.storage.save("cameraData", result);
this.$router.go(-);
},
error => {
this.$toast({
position: "bottom",
message: error.message
}); }
);
});
}
}
};
</script>
去扫一扫前的页面:
<template>
<div id="workshop">
<div id="scan">
<div
id="header"
:style="{height:statubar}"
>
<div
class="wrap"
:style="{'padding-top':paddingTop}"
>
<div class="back">
<van-icon
name="arrow-left"
@click="$router.go(-1)"
/>
</div>
<div class="title">扫一扫</div>
<div class="history">
<span>
历史记录
</span>
</div>
</div>
</div>
<div class="searchBox">
<van-row>
<van-col span="">
<van-button
size="large"
:square="true"
@click="goCamera"
>
<img
class="right"
src="../../assets/img/png-73@3x.png"
/>
</van-button>
</van-col>
<van-col
span=""
class="van-hairline--surround"
>
<van-search
v-model="value"
:placeholder="pla"
@keydown.stop="search"
shape="round"
>
<span slot="left-icon"></span>
</van-search>
</van-col>
</van-row>
</div>
</div>
</div>
</template>
<script>
export default {
name: "orderScan",
data() {
return {
result: {},
value: "",
};
},
methods: {
// 去扫码
goCamera() {
this.$router.go("/camera")
},
// 手动输入时搜索
search(e) {
if (e.keyCode == ) {
this.onSearch();
}
},
// 搜索结果
onSearch() {}
},
mounted() {
let camera = sessionStorage.getItem("cameraData");
if (camera && camera != "null") {
this.value = sessionStorage.getItem("cameraData");
sessionStorage.removeItem("cameraData");
}
}
};
</script>
两个页面运行的效果如下
当时以为很容易,结果做出后遇到各种BUG,有时黑屏,有时位置偏移,有时扫码框偏移等等
比如下图 这个扫码框已经偏移了
很奇怪,看官方提供的APP怎么扫都是没有问题。于是乎百度各种解决方法,看到 有的说是因为摄像头很耗资源,要用单独的webview来分配,用完即关,看看官方的案例,貌似确实也是新建一个webview来启动的。
心想应该就是这样吧,于是,把方法改了一下。去扫一扫前的页面的$router.go("/camera")时直接改成生成新一个webview,改后的JS代码如下;
goCamera() {
//新建一个webview来启动扫一扫,不再$router.push()的跳转
let h = location.href;
let n = h.indexOf("#");
let r = h.substr(n);
h = h.replace(r, "#/camera");
let ws = plus.webview.create(h);
ws.show();
},
在扫码页面,修改扫码成功后router.go(-1)改成关闭当前的webview,进入页面时设置一个定时器来加载摄像头的资源的JS更改如下
let scan = null;
export default {
data() {
return {
codeUrl: "",
isLight: false,
showEnter: false,
extra: null,
scan: null,
type: ""
};
}, mounted() {
setTimeout(() => {
// 设置500毫秒等资源加载
if (window.plus) {
let s = plus.navigator.checkPermission("camera");
if (s !== "notdeny") {
plus.nativeUI.alert("相机权限未获取,请往设置应用程序里面开启权限!");
return;
}
this.startScan(); //`进入页面就调取扫一扫
}
}, );
},
beforeDestroy() {
if (!window.plus) return;
scan.cancel();
scan.close();
// scan = null;
},
methods: {
// 打开闪光灯
openLight() {
this.isLight = !this.isLight;
scan.setFlash(this.isLight);
},
//创建扫描控件
startRecognize() {
let that = this;
if (!window.plus) return; scan = null;
scan = new plus.barcode.Barcode(
"scan",
[plus.barcode.QR, plus.barcode.EAN8, plus.barcode.EAN13],
{
frameColor: "#1294cb",
scanbarColor: "#1294cb",
top: "100px",
left: "0px",
width: "100%",
height: "500px",
position: "fixed"
}
);
scan.onmarked = onmarked;
function onmarked(type, result, file) {
result = result.replace(/\n/g, "");
that.storage.save("cameraData", result);
if (plus.webview.all().length > ) {
// 扫码成功后关闭当前的webview
let ws = plus.webview.currentWebview();
plus.webview.close(ws);
}
}
},
// //开始扫描
startScan() {
if (!window.plus) return;
this.startRecognize(); //创建控件
setTimeout(() => {
scan.start();
}, );
},
// 取消扫描
cancelScan() {
let l = plus.webview.all().length;if (l > ) {
let ws = plus.webview.currentWebview();
plus.webview.close(ws);
} else {
this.$router.go(-);
}
// this.$router.go(-1);
if (!window.plus) return;
plus.navigator.setStatusBarStyle("dark");
if (scan) {
scan.cancel(); //关闭扫描
scan.close(); //关闭条码识别控件
}
},
// 从相册选择图片扫码
getPicture() {
plus.gallery.pick(src => {
plus.barcode.scan(
src,
(type, result) => {
scan.cancel();
scan.close();
this.storage.save("cameraData", result);
if (plus.webview.all().length > ) {
// 扫码成功后关闭当前的webview
let ws = plus.webview.currentWebview();
plus.webview.close(ws);
}
},
error => {
this.$toast({
position: "bottom",
message: error.message
});
}
);
});
}
}
};
至于扫码成功的数据切换,我是用localStorage来保存。
改成这样新生成一个webview方法后,我自己测试了N遍,没遇到过那些问题了,我也用我同事的手机测试过,也没有问题。但愿是解决了吧
记录vue用 html5+做移动APP 用barcode做扫一扫功能时安卓 的bug(黑屏、错位等等)和解决方法的更多相关文章
- vue项目使用前端框架开发,实现滑动效果,若不刷新页面则无法达到预期效果的问题及解决方法
滑动等效果的初始化时机很重要,在vue项目开发中,需到mounted()钩子函数 (当组件中的DOM结构被渲染好并放到页面中后,会执行这个钩子函数,此时即可初始化滑动效果的js代码). 若组件未挂载到 ...
- vue项目使用html5+ barcode扫码在苹果遇到的问题以及自己的解决方法
之前在记录扫码 在安卓时,会出现黑屏,错位,闪退等等问题.解决方法在另一篇文章里 https://www.cnblogs.com/huzhuhua/p/11064764.html . 当时以为 是 ...
- Android 编程下通过 Theme 和 Style 避免 APP 启动闪黑屏
之前在做 APP 的时候不太关注这个问题,因为自己在使用其他 APP 的时候也会在应用启动的初始有一个黑屏闪过后才会出现应用的欢迎页.直到最近开发过程中发现自己在欢迎页启动的线程由于请求和处理的数据量 ...
- Vue+DataTables warning:table id=xxxx -Cannot reinitialize DataTable.报错解决方法
问题描述: 使用DataTables来写列表,用vue来渲染数据,有搜索功能,每次点击搜索就会报错,如下图所示. 问题排查: 找了一系列原因,最后发现是我每次请求完数据之后都会添加分页功能,从而导致了 ...
- cordova+vue做的app解决引入cordova-plugin-splashscreen后启动先显示黑屏在显示启动页
先上项目目录结构cordova项目结构 android platform 结构 图中用红框框起来的为主要修改文件 这篇主要的讲cordova项目引用了cordova-plugin-splashscre ...
- html5文章 -- 使用 jQuery Mobile 与 HTML5 开发 Web App ——开发原则 | Kayo's Melody
最近专注研究 jQuery Mobile —— 一款很方便就可以把 Web App 包装成适合 Android 与 iPhone 等触屏移动设备的 Javascript 库,结合 jQuery Mob ...
- HTML5 Plus移动App(5+App)开发入门指南
HTML5 Plus移动App,简称5+App,是一种基于HTML.JS.CSS编写的运行于手机端的App,这种App可以通过扩展的JS API任意调用手机的原生能力,实现与原生App同样强大的功能和 ...
- atitit.html5 vs 原生 app的区别与选择
atitit.html5 vs 原生 app的区别与选择 1. html5的优点 1 1.1. 最大优势::在跨平台(ios苹果,android安卓等) 1 1.2. 开放性 1 1.3. 快速的更 ...
- h5做的app和原生app的区别
之所以说h5做的app和原生app的区别,是因为一位博友的问题: 随着 h5 的普及,是不是不再需要开发 app ? 我的回答是要分业务需求,分场合而定. 比如现在的微信小程序这么流行,甚至也取代了不 ...
随机推荐
- iOS10 新特性一
链接:http://www.jianshu.com/p/0cc7aad638d9 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是 ...
- [PHP] 深度解析Nginx下的PHP框架路由实现
所有的框架处理业务请求时,都会处理URL的路径部分,分配到指定的代码中去处理.实现这一功能的关键就是获取$_SERVER全局变量中对于URL部分的数据 当请求的路径为http://test.com/a ...
- Shell命令-网络操作之基础之ping、route
文件及内容处理 - ping.route 1. ping:测试主机之间网络的连通性 ping命令的功能说明 ping 命令用于检测主机.执行 ping 指令会使用 ICMP 传输协议,发出要求回应的信 ...
- Jinkins自动构建
Jinkins自动构建 1.项目添加 点击左侧操作栏“新建”,填写项目基础信息,如下图: 2. General配置 2.1 丢弃旧的构建 注:此处勾选丢弃旧的构建,默认天数为1,最大个数建议填写3-5 ...
- 花了快一天,才搞出来的一个client-go的demo
用来直接获取所有service的annotaion里有ambassador的东东. 或者,watch集群事件. package main import ( "fmt" " ...
- Ant风格路径表达式
ANT通配符有三种: ? 匹配任何单字符 * 匹配0或者任意数量的字符 ** 匹配0或者更多的目录 举例: /project/*.a 匹配项目根路径下所有在project路径下的.a文件 /proje ...
- 洛谷 P5596 【XR-4】题
洛谷 P5596 [XR-4]题 洛谷传送门 题目描述 小 X 遇到了一道题: 给定自然数 a,ba,b,求满足下列条件的自然数对 (x,y)(x,y) 的个数: y^2 - x^2 = ax + b ...
- C语言中关于输出n个数后就换行的问题。
例如:n=10 ........; n++; if(n%10==0&&n!=0) //因为当n=0时,n%10的值也是0,就也会转行,为了防止这种情况的发生,就用了&&a ...
- Hystrix 超时配置的N种玩法
前阵子在我的知识星球中,有位朋友对我提了个问题,问我如何让Hystrix支持对接口级别的超时配置,今天给大家写篇文章,普及下Hystrix配置超时的几种方式. 至于以后你是用阿里的Sentinel还是 ...
- ubuntu / zsh shell / oh-my-zsh / 常用插件
记录一下 zsh 的下载与配置,省得每次重装系统都要上网到处查. 安装 zsh shell sudo apt install zsh 切换 shell chsh -s /bin/zsh 安装 oh-m ...