Ionic4 使用cordova-plugin-qrscanner扫描二维码、条形码

cordova-plugin-qrscanner可以高度定制扫码页面UI,相比于phonegap-plugin-barcodescanner来说,速度也快,
新建扫码页面qr-scanner:
html:

<ion-header>
  <ion-toolbar class="scanner">
    <ion-buttons slot="start">
      <ion-button (click)="closeModal()">
        <ion-icon slot="icon-only" name="close"></ion-icon>
      </ion-button>
    </ion-buttons>
    <ion-title>扫描中</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [class.scanner]="scannerClass">

  <div class="qr-scanner-area">
    <p class="lines"></p>
  </div>

  <ion-grid fixed class="scanner-button-bottom">
    <ion-row>
      <ion-col size="6" class="ion-flex ion-justify-content-center">
        <ion-button fill="clear" class="qr-scanner-button" (click)="toogleLight()">
          <ion-icon slot="icon-only" [name]="lightIcon"></ion-icon>
        </ion-button>
      </ion-col>
      <ion-col size="6" class="ion-flex ion-justify-content-center">
         <ion-button fill="clear" class="qr-scanner-button" (click)="toggleCamera()">
          <ion-icon name="reverse-camera" slot="icon-only"></ion-icon>
        </ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

css:

.scanner{  // 一定要将ion-content设置为背景透明,否则看不到摄像头画面
    --background: none transparent !important;
    background: none transparent !important;
    --color: white;
    ion-icon{ 
        color: white;
        font-size: 20px;
    }
}
.scanner-button-bottom{
    position: absolute;
    bottom: 45px;
    left: auto;
    right: auto;
    width: 100%;
    .qr-scanner-button{
        width: 75px;
        height: 75px;
        border-radius: 100%;
        background: rgba(0, 0, 0, 0.3);
    }
}
.qr-scanner-area{
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: calc(100% - 45px - 103px);
    background: url('./../../../assets/icon/qrscanner/scanner.svg') no-repeat center ;
    background-size: 100% 100%;
    .lines{
        width: 58%;
        height: 2px;
        background: var(--ion-color-primary);
        animation: lines 2s linear infinite alternate;
    }
}

TS:

import { NavController, Platform } from '@ionic/angular';
import { ModalsService } from './../../service/modals/modals.service';
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';
import { Component, OnDestroy, ElementRef } from '@angular/core';
import { ComponentsServiceService } from './../../service/componentsService/components-service.service';
@Component({
  selector: 'app-qr-scanner',
  templateUrl: './qr-scanner.page.html',
  styleUrls: ['./qr-scanner.page.scss'],
})
export class QrScannerPage implements OnDestroy {

  lightIcon: string;
  light: boolean;
  frontCamera: boolean;
  scannerClass: boolean;
  constructor(
    private platform: Platform,
    private scanner: QRScanner,
    private router: NavController,
    private modal: ModalsService,
    private element: ElementRef,
    private messageService: ComponentsServiceService,
  ) {
    this.lightIcon = 'flash-off';
    this.modal.showLoading();
  }
  ionViewDidEnter() {
    this.modal.hideLoading();
    this.scannerClass = true;
    this.startScanner();
    this.scanner.show();
  }

  ngOnDestroy() {
    this.scannerClass = false;
    this.destroyScanner();
  }

  closeModal() {
    this.router.back();
    this.destroyScanner();
  }

  toogleLight() {
    this.light = !this.light;

    if (this.light) {
      this.lightIcon = 'flash';
      this.scanner.enableLight();
    } else {
      this.lightIcon = 'flash-off';
      this.scanner.disableLight();
    }
  }

  toggleCamera() {
    this.frontCamera = !this.frontCamera;
    if (this.frontCamera) {
      this.scanner.useFrontCamera();
    } else {
      this.scanner.useBackCamera();
    }
  }

  startScanner() {
    this.platform.ready().then(() => {
      this.scanner.destroy();
      // Optionally request the permission early
      this.scanner.prepare().then((status: QRScannerStatus) => {
        if (status.authorized) {
          // camera permission was granted
          // start scanning
          let scanSub = this.scanner.scan().subscribe((text: string) => {
            console.log(text);

            this.messageService.sendEvents({ type: 'scanner', data: text });
            this.scanner.hide(); // hide camera preview
            scanSub.unsubscribe(); // stop scanning
            this.router.back();
          });

        } else if (status.denied) {
          this.scanner.openSettings();
          // camera permission was permanently denied
          // you must use QRScanner.openSettings() method to guide the user to the settings page
          // then they can grant the permission from there
        } else {
          // permission was denied, but not permanently. You can ask for permission again at a later time.
        }
      }).catch((e: any) => this.modal.toast(e));
    });
  }

  destroyScanner() {
    this.scanner.destroy();
    // 这里延迟一秒将html背景色重新设置为白色,否则会变透明,影响视觉效果
    setTimeout(() => {
      (window.document.querySelector('html') as HTMLElement).style.backgroundColor = '#fff';
    }, 1000);
  }
}

至此,便可以真机调试扫描二维码,此插件默认是只能扫描二维码的,也就是QR码,如果需要扫描条形码,也就是一维码,需要在源码里添加格式支持:
Android:plugins/cordova-plugin-qrscanner/src/android/QRScanner.java找到458行添加以下内容:

 formatList.add(BarcodeFormat.UPC_A);
 formatList.add(BarcodeFormat.UPC_E);
 formatList.add(BarcodeFormat.EAN_13);
 formatList.add(BarcodeFormat.EAN_8);
 formatList.add(BarcodeFormat.CODE_39);
 formatList.add(BarcodeFormat.CODE_93);
 formatList.add(BarcodeFormat.CODE_128);
 formatList.add(BarcodeFormat.ITF);
 formatList.add(BarcodeFormat.DATA_MATRIX);

IOS:plugins/cordova-plugin-qrscanner/src/ios/QRScanner.swift :

// 第156行修改为
metaOutput!.metadataObjectTypes = [AVMetadataObject.ObjectType.qr, AVMetadataObject.ObjectType.code39, AVMetadataObject.ObjectType.code93, AVMetadataObject.ObjectType.code128, AVMetadataObject.ObjectType.dataMatrix,
                AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13]
// 第243行修改为
if (found.type == AVMetadataObject.ObjectType.qr || found.type == AVMetadataObject.ObjectType.code39
                || found.type == AVMetadataObject.ObjectType.code93 || found.type == AVMetadataObject.ObjectType.code128
                || found.type == AVMetadataObject.ObjectType.dataMatrix || found.type == AVMetadataObject.ObjectType.ean8
                || found.type == AVMetadataObject.ObjectType.ean13) && found.stringValue != nil {
                ............
                }

修改完后,需要重新添加IOS、Android平台才可生效。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

废柴前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值