#はじめに
バーコードの読み取りをしたく、ZXing.Net.MobileをXamarin.Formsで使ってみました。PCLにそのままパッケージを追加することができないので、DependencyServiceを使って実装します。
#Xamarin.Forms
- 共有コードにインターフェースを作ります。スキャンだけするのでScanAsync()を書いておきます。
using System;
using System.Threading.Tasks;
namespace ZXingNetMobileSample
{
public interface IScanner
{
Task<string> ScanAsync();
}
}
Android
- パッケージにZXing.Net.Mobileを追加します。
- Required Permissionの中のCameraにチェックを入れます。
- IScannerインターフェースを継承したScanner_Androidクラスを実装します。
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クラスを実装します。
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()を呼ぶと、カメラ画面が表示され、スキャンすることができます。
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を読み取ろうとすると、下のバーコードを読み取ってしまうので何とかしたいところです。