モバイルアプリの中で、QRコードやバーコードを読み込む機能はとても需要があります。これまでコミュニティ製のCordovaプラグインを使う方が多かったですが、今回Monaca公式プラグインとしてリリースしました。

バーコードスキャナー - Monaca Docs

公式プラグインなので、無料ユーザーでも利用可能です。今回、このバーコードスキャナーの使い方を解説します。

プロジェクトのソースコードは、GitHubに配置しています。
https://github.com/monaca-samples/Barcode-Scanner-App

今回利用する技術

今回は以下のプラグイン、ライブラリを利用しています。

  • Framework7
  • バーコードスキャナープラグイン

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

プラグインはMonaca IDEのCordovaプラグインの管理よりインストールしてください。

Barcode Scannerというプラグインになります。

設定の変更

バーコードスキャナーはカメラを使うため、カメラ利用に関する許諾が必要となります。

これは各プラットフォームによって設定の作業が異なりますの注意してください。

iOSの場合

config.xmlを開いて、iOSの設定を次のように追加します。

need camera access to scan barcode はカメラ利用に関するメッセージなので、必要なメッセージに書き換えてください。

<platform name="ios">
        <!-- 省略 -->
        <!-- 以下を追加 -->
        <edit-config target="NSCameraUsageDescription" file="*-Info.plist" mode="merge">
                <string>need camera access to scan barcode</string>
        </edit-config>
</platform>

Androidの場合

AndroidはMonaca クラウド IDE のAndroidアプリ設定で、ターゲットSDKバージョンを31以上に設定します。

デモアプリ

今回はスキャン画面と履歴画面を持ったアプリを作ります。

まず www/index.html でタブを表示します。

<div id="app">
    <!-- Views/Tabs container -->
    <div class="views tabs safe-areas">
        <!-- Tabbar for switching views-tabs -->
        <div class="toolbar toolbar-bottom tabbar-labels">
            <div class="toolbar-inner">
                <a href="#view-home" class="tab-link tab-link-active">
                    <i class="icon f7-icons">qrcode</i>
                    <span class="tabbar-label">スキャン</span>
                </a>
                <a href="#view-list" class="tab-link">
                    <i class="icon f7-icons">list_dash</i>
                    <span class="tabbar-label">履歴</span>
                </a>
            </div>
        </div>
            <!-- Your main view, should have "view-main" class -->
            <div id="view-home" class="view view-main view-init tab tab-active" data-url="/scan/">
            </div>
            <div id="view-list" class="view view-init tab" data-url="/list/">
            </div>
        </div>
    </div>
</div>

ルーティング

各画面へ遷移するためのパスは次の通りになります。

/scan/ でスキャン画面
/list/ で履歴画面

を表示するようにルーティングを設定します。

これは js/routes.js にて定義しています。

const routes = [
  {
    path: '/',
    url: './index.html',
  },
  // スキャン画面
  {
    path: '/scan/',
    componentUrl: './pages/scan.html',
  },
  // 履歴画面
  {
    path: '/list/',
    componentUrl: './pages/list.html',
  },
  // Default route (404 page). MUST BE THE LAST
  {
    path: '(.*)',
    url: './pages/404.html',
  },
];

スキャン画面

スキャン画面はスキャンを実行するボタンと、その結果を表示する画面になります。

また、スキャンしたデータはlocalStorageに保存して、履歴画面で表示します。

<div class="page">
    <div class="navbar">
        <div class="navbar-bg"></div>
        <div class="navbar-inner sliding">
            <div class="title">スキャン</div>
        </div>
    </div>
    <div class="page-content">
        <div class="block-title">スキャンしてください</div>
        <button class="button" @click=${doScan}>スキャンする</button>
        ${ scan.value.text ?
                $h`
                        <div class="block-title">スキャン結果</div>
                        <div class="block">
                                種別: ${scan.value.format} コード: ${scan.value.text}
                        </div>
                `
                :
                ''
        }
    </div>
</div>

履歴画面

履歴画面では、スキャンした履歴データを一覧表示します。

<div class="page">
    <div class="navbar">
        <div class="navbar-bg"></div>
        <div class="navbar-inner sliding">
            <div class="title">スキャン履歴</div>
        </div>
    </div>
    <div class="page-content">
        <div class="block-title">スキャンした履歴です</div>
        <div class="list media-list">
            <ul>
                ${history.value.map(h => $h`
                    <li>
                        <div class="item-inner">
                            <div class="item-title-row">
                                <div class="item-subtitle">${h.format}</div>
                                <div class="item-text">${h.text}</div>
                            </div>
                        </div>
                    </li>
                `)}
            </ul>
        </div>
    </div>
</div>

スキャンデータと履歴データ

スキャンデータと履歴データはFramework7のストアを使って保存、取得しています。

そうすることで、アプリ内での共通したデータとして扱えるようになります。

const createStore = Framework7.createStore;
// localStorageに履歴があれば復元
let history = localStorage.getItem('history');
if (history) {
    history = JSON.parse(history);
} else {
    history = [];
}
const store = createStore({
  state: {
        // スキャンデータが入る
    scan: {
    },
        // 履歴が入る
    history,
  },
  getters: {
        // スキャンデータ用
    scan({ state }) {
      return state.scan;
    },
        // 履歴用
    history({ state }) {
        return state.history;
    }
  },
  actions: {
        // 新しいスキャンデータを追加するアクション
    addScan({ state }, scan) {
            // スキャンデータの適用
            state.scan = scan;
            // 履歴データに追加
            state.history = [...state.history, scan];
            // 履歴データをlocalStorageに書き出し
            localStorage.setItem('history', JSON.stringify(state.history));
        },
    },
});

スキャン処理

スキャン画面ではストアから scan を取り出します。

これを使うことで、スキャン結果を適用すれば自動的に画面が更新されるようになります。

// ストアからデータを取得する
const { scan } = $store.getters;

スキャンする処理はスキャン画面でボタンを押したタイミングで実行される doScan 関数にて行います。

バーコードスキャナーは monaca.BarcodeScanner.scan で起動します。

実行すると res が呼ばれて、結果が返ってきます。

const doScan = async () => {
    try {
        // スキャン結果を受け取る
        const res = await execute();
        // スキャン結果を適用する
        $store.dispatch('addScan', res.data);
    } catch (e) {
        // キャンセルした場合
    }
};

// コールバック方式からPromiseに変換する関数
const execute = () => {
    return new Promise((res, rej) => {
        // バーコードスキャナー起動
        monaca.BarcodeScanner.scan(res, rej);
    });
}

スキャン オプションについて

スキャン処理には処理をカスタマイズするためのオプションを設定できます。

オプション設定により、バーコードやQRコードを読み込んだら、
すぐにアプリに戻り結果を表示する機能を実現することが可能です。

下のオプション記述のように、「oneShot」を「true」に設定すると
バーコードとQRコードを検知後、即処理が終了するようになります。

 const option = {
     "oneShot": true,
     "timeoutPrompt": {
     "show": true,
     "timeout": 5,
     "prompt": "Not detected"
     }
 }

monaca.BarcodeScanner.scan(res, rej, option);

デフォルトの 「oneShot」が「false」の場合は、
バーコード・QRコードの検知後、検知した内容が表示され
その内容をタップするまでスキャン処理は継続されます。

オプションの詳細については、こちらをご確認ください。

バーコード読込の結果

スキャン結果例です。こちらはバーコードを読み込んだ場合です。

{
    "data":{
        "text":"3068320128566",
        "format":"EAN_13"
    },
    "cancelled":false
}

QRコード読込の結果

こちらはQRコードです。

{
    "data":{
        "text":"https://ja.monaca.io/",
        "format":"QR_CODE"
    },
    "cancelled":false
}

キャンセルしてカメラを閉じると、cancelled = true になり、

失敗時のコールバックが呼ばれます。

{
    "data":{
        "text":"",
        "format":""
    },
    "cancelled":true
}

履歴の表示

履歴の表示処理は、コードはシンプルです。

ストアから history を取り出し、一覧表示するだけです。

export default (props, { $store }) => {
    // ストアから履歴データを取得
    const { history } = $store.getters;
    return $render;
}

これでスキャナーアプリの完成です。

まとめ

Monacaのバーコードスキャナーは簡単に実行できます。結果はクラウドのデータベースに保存したり、今回のようにlocalStorageに保存すれば繰り返し参照できます。

ぜひバーコードスキャナープラグインをお試しください。