LoginSignup
4

More than 5 years have passed since last update.

Xamarin.FormsでZXing.Net.Mobileを使ってみた

Posted at

はじめに

バーコードの読み取りをしたく、ZXing.Net.MobileをXamarin.Formsで使ってみました。PCLにそのままパッケージを追加することができないので、DependencyServiceを使って実装します。

Xamarin.Forms

  • 共有コードにインターフェースを作ります。スキャンだけするのでScanAsync()を書いておきます。
IScanner.cs
using System;
using System.Threading.Tasks;

namespace ZXingNetMobileSample
{
    public interface IScanner
    {
        Task<string> ScanAsync();
    }
}

Android

  • パッケージにZXing.Net.Mobileを追加します。
  • Required Permissionの中のCameraにチェックを入れます。
  • IScannerインターフェースを継承したScanner_Androidクラスを実装します。
Scanner_Android.cs
using System;
using System.Threading.Tasks;
using ZXing.Mobile;

[assembly: Xamarin.Forms.Dependency (typeof (ZXingNetMobileSample.Android.Scanner_Android))]

namespace ZXingNetMobileSample.Android
{
    public class Scanner_Android : IScanner
    {
        public async Task<string> ScanAsync()
        {
            var scanner = new MobileBarcodeScanner(Xamarin.Forms.Forms.Context);
            var result = await scanner.Scan();

            if (result != null)
            {
                return result.Text;
            }
            return string.Empty;
        }
    }
}

MobileBarcodeScannerに渡すContextはglobal::Android.App.Application.Contextではなく、Xamarin.Forms.Froms.Contextを使わないと、

[MonoDroid] android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

というエラーを出してしまいます。

iOS

iOSでもAndroidとほぼ同じく、
* パッケージにZXing.Net.Mobileを追加します。
* IScannerインターフェースを継承したScanner_Androidクラスを実装します。

Scanner_iOS.cs
using System;
using System.Threading.Tasks;
using ZXing.Mobile;

[assembly: Xamarin.Forms.Dependency (typeof (ZXingNetMobileSample.iOS.Scanner_iOS))]

namespace ZXingNetMobileSample.iOS
{
    public class Scanner_iOS : IScanner
    {
        public async Task<string> ScanAsync()
        {
            var scanner = new MobileBarcodeScanner();
            var result = await scanner.Scan();

            if (result != null)
            {
                return result.Text;
            }
            return string.Empty;
        }
    }
}

Context渡すとかしなくていいみたいですが、実機で動かす環境が無いため、実際にバーコードが読み取れるかはやっていません。

使い方

  • DependencyService.Get<IScanner>().ScanAsync()を呼ぶと、カメラ画面が表示され、スキャンすることができます。
App.cs
using System;
using Xamarin.Forms;

namespace ZXingNetMobileSample
{
    public class App
    {
        public static Page GetMainPage()
        {   
            var entry = new Entry();
            var button = new Button();
            button.Text = "Scan";
            button.Clicked += async (s, e) =>
            {
                entry.Text = await DependencyService.Get<IScanner>().ScanAsync();
            };

            return new ContentPage
            { 
                Content = new StackLayout
                {
                    Children =
                    {
                        entry,
                        button,
                    },
                    Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0),
                },
            };
        }
    }
}

おわりに

簡単にできてしまったので、DependencyServiceのサンプルとなってしまいました。これで書籍裏表紙のバーコードからISBNを読み取ろうとすると、下のバーコードを読み取ってしまうので何とかしたいところです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4