cordova でのスマホアプリ開発 ６

## バーコードリーダー

せっかくのスマホアプリなので、スマホならではの機能を

と、言うことで、バーコードリーダーを使ってみよう



カメラはネイティブの機能なので出来るのん？

と、疑問に思ったので、調べてみると cordova からプラグインが提供されている様子

https://ionicframework.com/docs/native/barcode-scanner
https://github.com/phonegap/phonegap-plugin-barcodescanner

サンプルコードでは、実際の挙動がわからないので、実装して動かしてみる

 

##### 実行環境

とりあえず、環境を確認（ionic のバージョンで全然書き方や実装方法が変わるので調査もタイヘン

```
C:\cordova_app>ionic info
[WARN] You are not in an Ionic project directory. Project context may be missing.

Ionic:

   Ionic CLI : 5.2.3

Utility:

   cordova-res : not installed
   native-run  : 0.2.7 (update available: 0.2.8)

System:

   NodeJS : v10.16.0
   npm    : 6.9.0
   OS     : Windows 10
```



##### 雛形になるアプリケーションを作成

新規に blank でアプリケーションを作成

```
C:\cordova_app>ionic start helloReader

Let's pick the perfect starter template!

Starter templates are ready-to-go Ionic apps that come packed with everything you need to build your app. To bypass this
prompt next time, supply template, the second argument to ionic start.

? Starter template: blank
√ Preparing directory .\helloReader - done!
√ Downloading and extracting blank starter - done!

Installing dependencies may take several minutes.

...
```

バーコードリーダーを実行するページも作成しておく

```
C:\cordova_app>cd helloReader

C:\cordova_app\helloReader>ionic g page reader
> ng.cmd generate page reader
CREATE src/app/reader/reader.module.ts (543 bytes)
CREATE src/app/reader/reader.page.html (125 bytes)
CREATE src/app/reader/reader.page.spec.ts (691 bytes)
CREATE src/app/reader/reader.page.ts (256 bytes)
CREATE src/app/reader/reader.page.scss (0 bytes)
UPDATE src/app/app-routing.module.ts (548 bytes)
[OK] Generated page!
```



##### 画面遷移したいよネ

前回 [cordova でのスマホアプリ開発 ５]() はリンクタグで無理やり遷移（しかも戻れない）してたので

ionic ぽい遷移を実装してみる



まずは、ルーティングの確認

```app-routing.module.ts
const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)},
  { path: 'reader', loadChildren: './reader/reader.module#ReaderPageModule' },
];
```

reader ページをコマンドから生成しているので、自動的にルート定義に追加されている

手動で作成した場合は、ここに追記が必要



初期ページにボタンを追加

```home.page.html
  <div class="ion-padding">
    <ion-button (click)="send('/reader')">Scanner</ion-button>
  </div>
```

追加したボタンの処理をスクリプトに記載

```home.page.ts
import { Component } from '@angular/core';
import { NavController } from '@ionic/angular';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  constructor(public navCtrl: NavController) {}

  send(page: string){
    this.navCtrl.navigateForward(page);
  }

}
```



遷移先ページに戻る遷移を追加

```reader.page.html
<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button>
    </ion-buttons>
    <ion-title>reader</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

</ion-content>
```

遷移できることを確認

![test_scanner12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/ad18a9e7-88c4-f988-2382-5ac66a8e7584.png)


##### バーコードリーダーの実装

cordova のプラグインをインストール

```
C:\cordova_app\helloReader>ionic cordova plugin add phonegap-plugin-barcodescanner
```

パッケージもインストール

```
C:\cordova_app\helloReader>npm install @ionic-native/barcode-scanner
```



reader ページに実行ボタンを配置

```reader.page.html
<ion-content>
  <ion-button (click)="scan()">すきゃん</ion-button>
</ion-content>
```

reader にバーコードリーダーのスクリプトを記載

```reader.page.ts
import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';

@Component({
  selector: 'app-reader',
  templateUrl: './reader.page.html',
  styleUrls: ['./reader.page.scss'],
  providers: [ BarcodeScanner ],
})
export class ReaderPage implements OnInit {

  constructor(private barcodeScanner: BarcodeScanner) { }

  ngOnInit() { }

  scan() {
    this.barcodeScanner
      .scan()
      .then(barcodeData => {
        alert("Barcode data " + JSON.stringify(barcodeData));
      })
      .catch(err => {
        console.log("Error", err);
      });
  }

}
```

実行してみる

![test_scanner3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/9e8552bf-3ed6-3efc-d142-0ed139f47d67.png)


ボタンが文字化け

そういえば、日本語を初めて使ったなぁと思いながら設定があるのか調べてみる



日本語化の設定が必要なわけではなく、html の文字コードの問題らしい

html ファイルの文字コードを UTF-8 で保存し再度確認すると、日本語が化けずに表示されているのを確認できた

![test_scanner4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/5db1b096-a395-7aa5-6f3c-bd3c12d9741f.png)


ボタンを押下してみると、デベロッパツールがエラーをはいてる

バーコードリーダーが cordova のプラグインだから ionic 単体では動作しないのかなー

![test_scanner5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/6ae26e2e-db1f-594e-ac01-85b5ddbb0b33.png)


##### エミュレータでの動作確認

それならば、とエミュレータで起動してみる

![test_scanner6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/1ea444ff-c562-66e9-ec14-ab4c77e7d2ec.png)


ボタン押下で、カメラ？が起動してる…ぽい？

なんか、バーチャルな世界をカメラで映している様子

※ALT + マウス移動で視点変更、ALT + WASDQE で移動できます

…ちゃうねん、それちゃうねん



調べてみると、Android Studio の AVD Manager からエミュレータのカメラ設定が可能らしい

AVD Manager から利用している端末の設定変更を選び、下部にある Show Advanced Settings を選択

![test_scanner7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/4eafea30-8413-c8ae-fbdd-96b7d3bc5426.png)


Camera の項目にある Back: を VirtualScene から Webcam0 に変更
※ノートPCのカメラを利用するため Webcam0 を設定してます

![test_scanner8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/585cf067-0162-763f-6a03-82e13ff41ed8.png)


Finish を押下で保存を忘れないように



再度エミュレータ実行してみる

![test_scanner9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/1fee917d-6ab6-17ff-c2be-f200a4327531.png)


おぉ～

なんか横向きになってたので、エミュレータを回転させて、バーコードを読み込ませてみる

左側：WikiPedia から QRコードのページにあったQRコードを読み込んでみた結果

右側：カメラ起動後、キャンセルした場合の結果

![test_scanner10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464760/512da8bc-25cf-b88c-03de-f837b5cc0acc.png)


JSON 形式で、text、format、cancelled が帰ってきてるのがわかる



ちなみに、実機にアプリインストールしてもちゃんと動作してました

開発環境にカメラがない場合は、実機からどうぞ