Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 27806|回复: 0

记录vue用 html5+做移动APP 用barcode做扫一扫功能时安卓 的bug(黑屏、错位等等)和解决方法

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-5 17:49:01 | 显示全部楼层 |阅读模式

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

    写的代码如下 :

    扫码页面:

    <style lang="less" scoped>
    #camera {
      height: 100%;
      width: 100%;
      .van-icon {
        top: -2px;
        font-size: 30px;
        color: #fff;
        &.back {
          left: 10px;
        }
        &.light {
          right: 10px;
        }
      }
      #scan {
        width: 100%;
        height: 100%;
        z-index: 2;
        position: fixed;
        left: 0;
        top: 0;
        background: rgba(0, 0, 0, 1);
      }
      .tips {
        text-align: center;
        position: absolute;
        width: 100%;
        top: 40%;
        color: #fff;
        z-index: 3;
        left: 0%;
      }
      .action {
        position: fixed;
        z-index: 777;
        width: 100%;
        left: 0;
        bottom: 0;
        .items {
          display: flex;
          justify-content: space-around;
          background: rgba(0, 0, 0, 0.35);
          width: 60%;
          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(-1);
          }
        },
        // //开始扫描
        startScan() {
          if (!window.plus) return;
          this.startRecognize(); //创建控件
          setTimeout(() => {
            scan.start();
          }, 200);
        },
        // 取消扫描
        cancelScan() {
          let l = plus.webview.all().length;
          this.$toast(l);
          if (l > 1) {
            let ws = plus.webview.currentWebview();
            plus.webview.close(ws);
          } else {
            this.$router.go(-1);
          }
          // 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(-1);
              },
              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="3">
                <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="21"
                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 == 13) {
            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(); //`进入页面就调取扫一扫 } }, 500); }, 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 > 1) { // 扫码成功后关闭当前的webview let ws = plus.webview.currentWebview(); plus.webview.close(ws); } } }, // //开始扫描 startScan() { if (!window.plus) return; this.startRecognize(); //创建控件 setTimeout(() => { scan.start(); }, 200); }, // 取消扫描 cancelScan() { let l = plus.webview.all().length;if (l > 1) { let ws = plus.webview.currentWebview(); plus.webview.close(ws); } else { this.$router.go(-1); } // 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 > 1) { // 扫码成功后关闭当前的webview let ws = plus.webview.currentWebview(); plus.webview.close(ws); } }, error => {      this.$toast({ position: "bottom", message: error.message }); } ); }); } } };

     至于扫码成功的数据切换,我是用localStorage来保存。

    改成这样新生成一个webview方法后,我自己测试了N遍,没遇到过那些问题了,我也用我同事的手机测试过,也没有问题。但愿是解决了吧

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-26 19:22 , Processed in 0.077040 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表