Skip to content

[Xamarin.GooglePlayServices.Code.Scanner] Using MlKit barcode scanner throws an exception #1063

Open
@IAlekhin

Description

@IAlekhin

Android framework version

net8.0-android, net9.0-android

Affected platform version

VS 2022 17.12.3 .NET 8.0; .NET 9.0

Description

I followed this tutorial in order to implement barcode scanner for my MAUI app, but after implementation I'm getting this error "Xamarin.Google.MLKit.Common.MlKitException: 'Waiting for the Barcode UI module to be downloaded.'"; In my app I used Xamarin.AndroidX.Collection.Ktx v1.2.0.10 and Xamarin.GooglePlayServices.Code.Scanner v116.1.0.1, then I decided to try it on some test app with the latest packages Xamarin.AndroidX.Collection.Ktx v1.4.5.1 and Xamarin.GooglePlayServices.Code.Scanner v116.1.0.9, the issue persists.
Is there an option to download the BarcodeUI before running code? Or maybe there is another way to implement it?

Steps to Reproduce

  1. Create new .NET 9 MAUI app
  2. Add following class to Platforms/Android
using Xamarin.Google.MLKit.Vision.Barcode.Common;
using Xamarin.Google.MLKit.Vision.CodeScanner;
using Gms = Android.Gms.Tasks;
using Android.Runtime;
using AndroidApp = Android.App.Application;
using Java.Lang;

namespace MauiApp1.Platforms.Android
{
    public class MlKitBarcodeScanner : IDisposable
    {
        private readonly IGmsBarcodeScanner barcodeScanner = GmsBarcodeScanning.GetClient(
            AndroidApp.Context,
            new GmsBarcodeScannerOptions.Builder()
                .AllowManualInput()
                .EnableAutoZoom()
                .SetBarcodeFormats(Barcode.FormatAllFormats)
                .Build());
        public async System.Threading.Tasks.Task<Barcode?> ScanAsync()
        {
            var taskCompletionSource = new System.Threading.Tasks.TaskCompletionSource<Barcode?>();
            var barcodeResultListener = new OnBarcodeResultListener(taskCompletionSource);
            using var task = barcodeScanner.StartScan()
                        .AddOnCompleteListener(barcodeResultListener);
            return await taskCompletionSource.Task;
        }
        public void Dispose()
        {
            barcodeScanner.Dispose();
        }
    }

    public class OnBarcodeResultListener(System.Threading.Tasks.TaskCompletionSource<Barcode?> taskCompletionSource) : Java.Lang.Object, Gms.IOnCompleteListener
    {
        public void OnComplete(Gms.Task task)
        {
            if (task.IsSuccessful)
            {
                taskCompletionSource.SetResult(task.Result.JavaCast<Barcode>());
            }
            else if (task.IsCanceled)
            {
                taskCompletionSource.SetResult(null);
            }
            else
            {
                taskCompletionSource.SetException(task.Exception);
            }
        }
    }
}
  1. Add this code to the MainPage.xaml.cs constructor: Loaded += MainPage_Loaded;
private async void MainPage_Loaded(object? sender, EventArgs e)
       {
#if ANDROID
           using var mlkit = new MauiApp1.Platforms.Android.MlKitBarcodeScanner();
           var barcode = await mlkit.ScanAsync();
           await Task.Delay(5000);
           await MainThread.InvokeOnMainThreadAsync(async () =>
           {
               //await Toast.Make(barcode is null ? "Error has occurred during barcode scanning" : barcode.RawValue, ToastDuration.Long).Show();
           });
#endif
       }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions