tonkunの備忘録

色々調べた事、試した事などを載せます

Xamarin.Android Google Play Services Visionを使ってみた

スキャナを作ってみようと色々調べていたらAndroid5.0以降はCameraクラスは非推奨との事で、 Camera2で試してみようかとも思ったんですが、Google Play Services Visionを使ってもできるようなので試しに使ってみました。

Google Play Services - Vision / Components / Xamarin

インストール

NugetからXamarin.GooglePlayServices.Visionをインストール。

f:id:tonkun_no:20160908020154p:plain

Manifest設定

プロジェクトのプロパティのから CAMERA をチェックオン

f:id:tonkun_no:20160908020618p:plain

実装

以下を参考に実装していきます。

com.google.android.gms.vision  |  Google APIs for Android  |  Google Developers

画面にはSurfaceViewを配置し、 MainActivityにはISurfaceHolderCallbackインターフェースも実装します。

MainActivity(抜粋)
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);
    this.surfaceView = (SurfaceView)this.FindViewById(Resource.Id.surfaceview);
    this.surfaceView.Holder.AddCallback(this);

    // バーコードの種類を指定する場合はSetBarcodeFormatsで指定
    //BarcodeDetector detector = new BarcodeDetector.Builder(this).SetBarcodeFormats(BarcodeFormat.QrCode).Build();
    BarcodeDetector detector = new BarcodeDetector.Builder(this).Build();
    detector.SetProcessor(
        new MultiProcessor.Builder(new MyTrackerFactory(this.HandleScanResult)).Build());
    this.cameraSource = new CameraSource.Builder(this, detector).SetFacing(CameraFacing.Back).SetAutoFocusEnabled(true).Build();
}

public void HandleScanResult(Barcode item)
{
    string msg = string.Empty;
    if (item != null && !string.IsNullOrEmpty(item.RawValue))
        msg = "Found Barcode: " + item.RawValue;
    else
        msg = "Scanning Canceled";
    this.RunOnUiThread(() => Toast.MakeText(this, msg, ToastLength.Long).Show());
}

public void SurfaceCreated(ISurfaceHolder holder)
{
    this.cameraSource.Start(this.surfaceView.Holder);
}
MyTrackerFactoryとBarcodeTracker
public class MyTrackerFactory
    : Java.Lang.Object, MultiProcessor.IFactory
{
    Action<Barcode> handleScanAction;
    public MyTrackerFactory(Action<Barcode> action)
    {
        this.handleScanAction = action;
    }
    public Tracker Create(Java.Lang.Object item)
    {
        return new BarcodeTracker(handleScanAction);
    }
}

public class BarcodeTracker
    : Tracker
{
    Action<Barcode> handleScanAction;
    public BarcodeTracker(Action<Barcode> action)
    {
        this.handleScanAction = action;
    }
    public override void OnNewItem(int id, Java.Lang.Object item)
    {
        handleScanAction((Barcode)item);
    }
}

バーコード読み込み時の処理をMainActivityで記述している為、
どうにかBarcodeTrackerに渡したくて無理やり渡しています。

今回はサンプルなので良いですが、実際にこれを使って実装する場合は 全体的にどう実装するんだろう?
個人的にはついついISurfaceHolderCallbackを実装したなんたらmanagerクラスを作って、やってしまいそうです( ゚Д゚)*1

ビルドして実行すると、無事バーコードの読み込みが出来ました。 f:id:tonkun_no:20160908215221p:plain

Visionは他の機能もあるので試してみようかと思います。

*1:そして役割が増えていく・・・