ionic 扫描二维码/条形码功能

廉展鹏
2023-12-01

一、安装插件@ionic-native/qr-scanne

二、page

scan.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams} from 'ionic-angular';
import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner';

/**
 * Generated class for the ScanPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */
@IonicPage()
@Component({
  selector: 'page-scan',
  templateUrl: 'scan.html',
})
export class ScanPage {
  light: boolean;//判断闪光灯
  frontCamera: boolean;//判断摄像头
  isShow: boolean = false;//控制显示背景,避免切换页面卡顿
  error = '';
  devicetype = '';
  

  constructor(
    private navCtrl: NavController,
    private qrScanner: QRScanner,
    public navParams: NavParams, 
  ) {
    //默认为false
    this.light = false;
    this.frontCamera = false;
  }

  ionViewDidLoad() {
    this.devicetype = this.navParams.get('devicetype') || '';
    this.qrScanner.prepare()
      .then((status: QRScannerStatus) => {
        if (status.authorized) {
          // camera permission was granted
          // start scanning
          let scanSub = this.qrScanner.scan().subscribe((text: string) => {
            // alert(text);
            this.qrScanner.hide(); // hide camera preview
            scanSub.unsubscribe(); // stop scanning
            if (this.devicetype == 'parent') {
              this.navCtrl.getPrevious().data.scantextParent = text;
            } else if (this.devicetype == 'sub') {
              this.navCtrl.getPrevious().data.scantextSub = text;
            } else {
              this.navCtrl.getPrevious().data.scantext = text;
            }

            this.navCtrl.pop();
          });

          // show camera preview
          this.qrScanner.show();

          // wait for user to scan something, then the observable callback will be called
        } else if (status.denied) {
          // camera permission was permanently denied
          this.error = '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.
          this.error = 'permission was denied, but not permanently. You can ask for permission again at a later time.';
        }
      })
      .catch((e: any) => {
        console.log('Error is', e);
        this.error = e;
      });
  }

  ionViewDidEnter() {
    //页面可见时才执行
    this.devicetype = this.navParams.get('devicetype') || '';
    this.showCamera();
    this.isShow = true;//显示背景
  }



  /**
   * 闪光灯控制,默认关闭
   */
  toggleLight() {
    if (this.light) {
      this.qrScanner.disableLight();
    } else {
      this.qrScanner.enableLight();
    }
    this.light = !this.light;
  }

  /**
   * 前后摄像头互换
   */
  toggleCamera() {
    if (this.frontCamera) {
      this.qrScanner.useBackCamera();
    } else {
      this.qrScanner.useFrontCamera();
    }
    this.frontCamera = !this.frontCamera;
  }

  showCamera() {
    (window.document.querySelector('ion-app') as HTMLElement).classList.add('cameraView');
  }
  hideCamera() {

    (window.document.querySelector('ion-app') as HTMLElement).classList.remove('cameraView');
    this.qrScanner.hide();//需要关闭扫描,否则相机一直开着
    this.qrScanner.destroy();//关闭
  }

  ionViewWillLeave() {
    this.hideCamera();
  }
}

scan.html

<!--
  Generated template for the ScanPage page.
  See http://ionicframework.com/docs/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>
  <ion-navbar>
    <ion-title>扫描中……{{error}}</ion-title>
  </ion-navbar>
</ion-header>
<ion-content no-scroll [ngClass]="{'qrscanner':isShow}">
  <div [ngClass]="{'qrscanner-area':isShow}">
  </div>
  <div [ngClass]="{'through-line':isShow}"></div>
  <div class="button-bottom">
    <button (click)="toggleLight()" ion-fab class="icon-camera" margin-right>
      <ion-icon name="flash"></ion-icon>
    </button>
    <button (click)="toggleCamera()" ion-fab class="icon-camera">
      <ion-icon name="reverse-camera"></ion-icon>
    </button>
  </div>
</ion-content>

scan.scss

page-scan {
.qrscanner {
    background: none !important;
    &-area {
      width: 100%;
      height: 86%;
      background: url(../assets/imgs/scanner.svg) no-repeat center center;
      background-size: contain;
    }
  }
  .through-line {
    left: 25%;
    width: 50%;
    height: 2px;
    background: red;
    position: absolute;
    animation: myfirst 2s linear infinite alternate;
  }
  @keyframes myfirst {
    0% {
      background: red;
      top: 30%;
    }
    25% {
      background: yellow;
      top: 35%;
    }
    50% {
      background: blue;
      top: 40%;
    }
    75% {
      background: green;
      top: 45%;
    }
    100% {
      background: red;
      top: 50%;
    }
  }
  .button-bottom {
    width: 128px;
    position: absolute;
    left: 50%;
    bottom: 80px;
    margin-left: -64px;
    .icon-camera {
      float: left;
    }
}
}

scan.module.ts

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ScanPage } from './scan';

@NgModule({
  declarations: [
    ScanPage,
  ],
  imports: [
    IonicPageModule.forChild(ScanPage),
  ],
})
export class ScanPageModule {}

三、使用

a.ts

  ionViewDidEnter() {
   this.scantext = this.navParams.get('scantext') || '';
  
  }

// 二维码
  qrScanners() {
    this.navCtrl.push('ScanPage');
  }

四、Ionic二维码扫码插件QR Scanner不能扫描一维码问题

解决:

在qr-scanner插件中的QRScanner.java的setupCamera中添加如下代码:

formatList.add(BarcodeFormat.UPC_A); // UPC标准码(通用商品)

formatList.add(BarcodeFormat.UPC_E); // UPC缩短码(商品短码)

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);

五、源码参考

 

https://github.com/xif3681/job2-8-smart-city-install-app/tree/master/src/pages/scan

 类似资料: