Xamarin.Forms でバーコードスキャンライブラリ ZXing.Net.Mobile を使う


こんにちは。エクセルソフトの田淵です。

ZXing(Zebra Crossing の略みたいです)を使って簡単にバーコードスキャナが作れるよ!というエントリーを Xamarin エバンジェリストの James Montemagno さんがアップされていたので、試してみました。ネイティブでも有名なライブラリですよね。

GitHub サンプル

Windows Phone 8.1 に対応していない(Sliverlight のみ)ので、 Profile 7、49、78 のどれかを使用する必要があります(多分)。私は Profile 7 にして NuGet からインストールできました。各 Profile の対応プラットフォームは 私のブログエントリー を参照してください。

インストール

PCL の Profile が 7、49、78 以外の場合は Profile を変更します。Xamarin.Forms PCL プロジェクトで Profile を変更するには、一度 Xamarin.Forms ライブラリをアンインストールして、PCL プロジェクトのプロパティで Windows Phone 8.1 を外すなどして、保存し、再度 Xamarin.Forms ライブラリをインストールする必要があります。

NuGet から ZXing.Net.Mobile.Forms をインストールすると、一緒に ZXing.Net.Mobile もインストールされます。

インストール後の各プラットフォームの参照一覧は次のようになっていました。

PCL

Android

iOS

UWP

Windows Store

使い方

サンプルなので簡単に。
NavigationPage 経由でページを表示し、コードビハインドに次のイベントハンドラを記述します。

using ZXing.Net.Mobile.Forms;

async void ScanButtonClicked(object sender, EventArgs s)
{
    // スキャナページの設定
    var scanPage = new ZXingScannerPage()
    {
        DefaultOverlayTopText = "バーコードを読み取ります",
        DefaultOverlayBottomText = "",
    };
    // スキャナページを表示
    await Navigation.PushAsync(scanPage);

    // データが取れると発火
    scanPage.OnScanResult += (result) =>
    {
        // スキャン停止
        scanPage.IsScanning = false;

        // PopAsyncで元のページに戻り、結果をダイアログで表示
        Device.BeginInvokeOnMainThread(async () =>
        {
            await Navigation.PopAsync();
            await DisplayAlert("スキャン完了", result.Text, "OK");
        });
    };
}

XAML はボタンを追加しただけです。

では、各プロジェクトでビルドしてみます。

iOS

iOS は初回起動時の許可を求める必要がありますので、iOS プロジェクトの AppDelegate.csglobal::Xamarin.Forms.Forms.Init(); の後に ZXing の初期化コードが必要です。

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    global::Xamarin.Forms.Forms.Init();
    global::ZXing.Net.Mobile.Forms.iOS.Platform.Init(); // <- これ
    LoadApplication(new App());

    return base.FinishedLaunching(app, options);
}

また、ダイアログのメッセージを Info.plist に追加します。

<key>NSCameraUsageDescription</key>
<string>カメラを利用してスキャンします。</string>

初回起動時に確認ダイアログが表示されました

Android

ビルド前に色々設定を。

Manifest

GUI の設定から、または Manifest.xml を直接編集し、CAMERA と FLASHLIGHT の権限を取っておきます。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

Runtime Permission

Android 6.0 Marshmallow を対象にする場合は、ランタイムパーミッションの設定が必要なので 、Android プロジェクトの MainActivity.cs に以下を追加します。

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);           
}

ビルドすると

むむむ。。。ライブラリで参照しちゃってるんですね。仕方ないので values/Strings.xml のフォルダ、ファイルを作成し、

<?xml version="1.0" encoding="utf-8" ?>
<resources>
  <string name="Hello">Hello World, Click Me!</string>
  <string name="ApplicationName">アプリ名</string>
</resources>

を追加しておきます。

OK です。無事ビルドが通りました。ボタンをクリックしてカメラを初回起動した時の Marshmallow の Runtime Permission も動作しています。

UWP

UWP は一応 Package.appxmanifest の[機能]タブで[Webカメラ]にチェックを入れました。不要かも。

動作イメージ

笑えるくらい素早く認識してくれます。

iOS

Android

UWP

やっぱり QR コードしか対応していないようでした。

この後は

例えば ObservableCollection<string>scanPage.OnScanResultResult.Text をガンガン突っ込んでいけば連続でスキャンできますよね。ただ、画面を「スキャンしたよ」と一瞬ホワイトアウトさせるような処理を入れないとスキャンしたのかしてないのか分からないですよね。どうやるのか気になります。是非チャレンジしてみてください。

Xamarin 気になった方は

是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。
学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の情報が欲しい方は 田淵ブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

以上です。