经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
记录vue用 html5+做移动APP 用barcode做扫一扫功能时安卓 的bug(黑屏、错位等等)和解决方法
来源:cnblogs  作者:h祝h  时间:2019/6/24 8:50:45  对本文有异议

最近做项目时,要用到扫一扫二维码的功能,在html5+里面有提供barcode功能,于是照过来用了,

写的代码如下 :

扫码页面:

  1. <style lang="less" scoped>
  2. #camera {
  3. height: 100%;
  4. width: 100%;
  5. .van-icon {
  6. top: -2px;
  7. font-size: 30px;
  8. color: #fff;
  9. &.back {
  10. left: 10px;
  11. }
  12. &.light {
  13. right: 10px;
  14. }
  15. }
  16. #scan {
  17. width: 100%;
  18. height: 100%;
  19. z-index: 2;
  20. position: fixed;
  21. left: 0;
  22. top: 0;
  23. background: rgba(0, 0, 0, 1);
  24. }
  25. .tips {
  26. text-align: center;
  27. position: absolute;
  28. width: 100%;
  29. top: 40%;
  30. color: #fff;
  31. z-index: 3;
  32. left: 0%;
  33. }
  34. .action {
  35. position: fixed;
  36. z-index: 777;
  37. width: 100%;
  38. left: 0;
  39. bottom: 0;
  40. .items {
  41. display: flex;
  42. justify-content: space-around;
  43. background: rgba(0, 0, 0, 0.35);
  44. width: 60%;
  45. padding: 4px;
  46. margin: 4px auto;
  47. .item {
  48. flex-basis: 50px;
  49. text-align: center;
  50. img {
  51. width: 27px;
  52. }
  53. }
  54. }
  55. }
  56. }
  57. </style>
  58. <template>
  59. <div id="camera">
  60. <div id="scan"></div>
  61. <div class="tips">"加载中...</div>
  62. <div class="action">
  63. <div class="items">
  64. <div
  65. class="item"
  66. @click="openLight"
  67. ><img src="../assets/img/png-60@3x.png"></div>
  68. <div
  69. class="item"
  70. @click="getPicture()"
  71. ><img src="../assets/img/png-59@3x.png"></div>
  72.  
  73. <div
  74. class="item"
  75. @click="cancelScan()"
  76. ><img src="../assets/img/png-61@3x.png"></div>
  77. </div>
  78. </div>
  79. </div>
  80. </template>
  81.  
  82. <script type='text/ecmascript-6'>
  83. let scan = null;
  84. export default {
  85. data() {
  86. return {
  87. codeUrl: "",
  88. isLight: false,
  89. showEnter: false,
  90. extra: null,
  91. type: ""
  92. };
  93. },
  94. mounted() {
  95. if (window.plus) {
  96. let s = plus.navigator.checkPermission("camera");
  97. if (s !== "notdeny") {
  98. plus.nativeUI.alert("相机权限未获取,请往设置应用程序里面开启权限!");
  99. }
  100. }
  101. this.startScan(); //`进入页面就调取扫一扫
  102. },
  103. beforeDestroy() {
  104. if (!window.plus) return;
  105. scan.cancel();
  106. scan.close();
  107. },
  108. methods: {
  109. // 打开闪光灯
  110. openLight() {
  111. this.isLight = !this.isLight;
  112. scan.setFlash(this.isLight);
  113. },
  114. //创建扫描控件
  115. startRecognize() {
  116. let that = this;
  117. if (!window.plus) return;
  118. scan = null;
  119. scan = new plus.barcode.Barcode(
  120. "scan",
  121. [plus.barcode.QR, plus.barcode.EAN8, plus.barcode.EAN13],
  122. {
  123. frameColor: "#1294cb",
  124. scanbarColor: "#1294cb",
  125. top: "100px",
  126. left: "0px",
  127. width: "100%",
  128. height: "500px",
  129. position: "fixed"
  130. }
  131. );
  132. scan.onmarked = onmarked;
  133. function onmarked(type, result, file) {
  134. result = result.replace(/\n/g, "");
  135. that.storage.save("cameraData", result);
  136. that.codeUrl = result; //扫描后返回值
  137. that.$router.go(-1);
  138. }
  139. },
  140. // //开始扫描
  141. startScan() {
  142. if (!window.plus) return;
  143. this.startRecognize(); //创建控件
  144. setTimeout(() => {
  145. scan.start();
  146. }, 200);
  147. },
  148. // 取消扫描
  149. cancelScan() {
  150. let l = plus.webview.all().length;
  151. this.$toast(l);
  152. if (l > 1) {
  153. let ws = plus.webview.currentWebview();
  154. plus.webview.close(ws);
  155. } else {
  156. this.$router.go(-1);
  157. }
  158. // this.$router.go(-1);
  159. if (!window.plus) return;
  160. plus.navigator.setStatusBarStyle("dark");
  161. if (scan) {
  162. scan.cancel(); //关闭扫描
  163. scan.close(); //关闭条码识别控件
  164. }
  165. },
  166. getPicture() {
  167. plus.gallery.pick(src => {
  168. plus.barcode.scan(
  169. src,
  170. (type, result) => {
  171. scan.cancel(); //关闭扫描
  172. scan.close();
  173. this.storage.save("cameraData", result);
  174. this.$router.go(-1);
  175. },
  176. error => {
  177. this.$toast({
  178. position: "bottom",
  179. message: error.message
  180. });
  181. }
  182. );
  183. });
  184. }
  185. }
  186. };
  187. </script>

 

去扫一扫前的页面:

  1. <template>
  2. <div id="workshop">
  3. <div id="scan">
  4. <div
  5. id="header"
  6. :style="{height:statubar}"
  7. >
  8. <div
  9. class="wrap"
  10. :style="{'padding-top':paddingTop}"
  11. >
  12. <div class="back">
  13. <van-icon
  14. name="arrow-left"
  15. @click="$router.go(-1)"
  16. />
  17. </div>
  18. <div class="title">扫一扫</div>
  19. <div class="history">
  20. <span>
  21. 历史记录
  22. </span>
  23. </div>
  24. </div>
  25. </div>
  26. <div class="searchBox">
  27. <van-row>
  28. <van-col span="3">
  29. <van-button
  30. size="large"
  31. :square="true"
  32. @click="goCamera"
  33. >
  34. <img
  35. class="right"
  36. src="../../assets/img/png-73@3x.png"
  37. />
  38. </van-button>
  39. </van-col>
  40. <van-col
  41. span="21"
  42. class="van-hairline--surround"
  43. >
  44. <van-search
  45. v-model="value"
  46. :placeholder="pla"
  47. @keydown.stop="search"
  48. shape="round"
  49. >
  50. <span slot="left-icon"></span>
  51. </van-search>
  52. </van-col>
  53. </van-row>
  54. </div>
  55. </div>
  56. </div>
  57. </template>
  58. <script>
  59. export default {
  60. name: "orderScan",
  61. data() {
  62. return {
  63. result: {},
  64. value: "",
  65. };
  66. },
  67. methods: {
  68. // 去扫码
  69. goCamera() {
  70. this.$router.go("/camera")
  71. },
  72. // 手动输入时搜索
  73. search(e) {
  74. if (e.keyCode == 13) {
  75. this.onSearch();
  76. }
  77. },
  78. // 搜索结果
  79. onSearch() {}
  80. },
  81. mounted() {
  82. let camera = sessionStorage.getItem("cameraData");
  83. if (camera && camera != "null") {
  84. this.value = sessionStorage.getItem("cameraData");
  85. sessionStorage.removeItem("cameraData");
  86. }
  87. }
  88. };
  89. </script>

两个页面运行的效果如下

 

当时以为很容易,结果做出后遇到各种BUG,有时黑屏,有时位置偏移,有时扫码框偏移等等

比如下图 这个扫码框已经偏移了

很奇怪,看官方提供的APP怎么扫都是没有问题。于是乎百度各种解决方法,看到 有的说是因为摄像头很耗资源,要用单独的webview来分配,用完即关,看看官方的案例,貌似确实也是新建一个webview来启动的。

心想应该就是这样吧,于是,把方法改了一下。去扫一扫前的页面的$router.go("/camera")时直接改成生成新一个webview,改后的JS代码如下;

  1. goCamera() {
  2. //新建一个webview来启动扫一扫,不再$router.push()的跳转
  3. let h = location.href;
  4. let n = h.indexOf("#");
  5. let r = h.substr(n);
  6. h = h.replace(r, "#/camera");
  7. let ws = plus.webview.create(h);
  8. ws.show();
  9. },

 

 在扫码页面,修改扫码成功后router.go(-1)改成关闭当前的webview,和设置一个定时器来加载摄像头的资源的JS更改如下

  1. let scan = null;
  2. export default {
  3. data() {
  4. return {
  5. codeUrl: "",
  6. isLight: false,
  7. showEnter: false,
  8. extra: null,
  9. scan: null,
  10. type: ""
  11. };
  12. },
  13. mounted() {
  14. setTimeout(() => {
  15. // 设置500毫秒等资源加载
  16. if (window.plus) {
  17. let s = plus.navigator.checkPermission("camera");
  18. if (s !== "notdeny") {
  19. plus.nativeUI.alert("相机权限未获取,请往设置应用程序里面开启权限!");
          return;
  20. }
  21. this.startScan(); //`进入页面就调取扫一扫
  22. }
  23. }, 500);
  24. },
  25. beforeDestroy() {
  26. if (!window.plus) return;
  27. scan.cancel();
  28. scan.close();
  29. // scan = null;
  30. },
  31. methods: {
  32. // 打开闪光灯
  33. openLight() {
  34. this.isLight = !this.isLight;
  35. scan.setFlash(this.isLight);
  36. },
  37. //创建扫描控件
  38. startRecognize() {
  39. let that = this;
  40. if (!window.plus) return;
  41. scan = null;
  42. scan = new plus.barcode.Barcode(
  43. "scan",
  44. [plus.barcode.QR, plus.barcode.EAN8, plus.barcode.EAN13],
  45. {
  46. frameColor: "#1294cb",
  47. scanbarColor: "#1294cb",
  48. top: "100px",
  49. left: "0px",
  50. width: "100%",
  51. height: "500px",
  52. position: "fixed"
  53. }
  54. );
  55. scan.onmarked = onmarked;
  56. function onmarked(type, result, file) {
  57. result = result.replace(/\n/g, "");
  58. that.storage.save("cameraData", result);
  59. if (plus.webview.all().length > 1) {
  60. // 扫码成功后关闭当前的webview
  61. let ws = plus.webview.currentWebview();
  62. plus.webview.close(ws);
  63. }
  64. }
  65. },
  66. // //开始扫描
  67. startScan() {
  68. if (!window.plus) return;
  69. this.startRecognize(); //创建控件
  70. setTimeout(() => {
  71. scan.start();
  72. }, 200);
  73. },
  74. // 取消扫描
  75. cancelScan() {
  76. let l = plus.webview.all().length;if (l > 1) {
  77. let ws = plus.webview.currentWebview();
  78. plus.webview.close(ws);
  79. } else {
  80. this.$router.go(-1);
  81. }
  82. // this.$router.go(-1);
  83. if (!window.plus) return;
  84. plus.navigator.setStatusBarStyle("dark");
  85. if (scan) {
  86. scan.cancel(); //关闭扫描
  87. scan.close(); //关闭条码识别控件
  88. }
  89. },
  90. // 从相册选择图片扫码
  91. getPicture() {
  92. plus.gallery.pick(src => {
  93. plus.barcode.scan(
  94. src,
  95. (type, result) => {
  96. scan.cancel();
  97. scan.close();
  98. this.storage.save("cameraData", result);
  99. if (plus.webview.all().length > 1) {
  100. // 扫码成功后关闭当前的webview
  101. let ws = plus.webview.currentWebview();
  102. plus.webview.close(ws);
  103. }
  104. },
  105. error => {
  106.      this.$toast({
  107. position: "bottom",
  108. message: error.message
  109. });
  110. }
  111. );
  112. });
  113. }
  114. }
  115. };

 至于扫码成功的数据切换,我是用localStorage来保存,跳转去扫码页面前设置一个定时器检测key值,改成这样新生成一个webview后,我自己测试了N遍,没遇到过那些问题了,我也用我同事的手机测试过,也没有问题。但愿是解决了吧

原文链接:http://www.cnblogs.com/huzhuhua/p/11064764.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号