我正在将 Xamarin.Android 项目转换为 .NET MAUI。该项目是 WebView 的轻量级包装,UI 主要由用 HTML、JavaScript 和 CSS 编写的单独项目处理。该应用程序与本机 Android 功能(例如蓝牙、相机等)进行交互。项目中仅有的两个视图是
InitializationActivity
(用户输入网站的 URL)和 MainActivity
(在 WebView 中显示网站) .
将项目转换为目标 .net8.0-android 后,该应用程序运行良好,除了一项功能:二维码/条形码扫描。在 Xamarin.Android 项目中,我使用了
ZXing.Net.Mobile
库,其中有一个自定义布局,并在 .cs 文件中调用 MobileBarcodeScanner.Scan()
打开相机进行扫描。但是,ZXing.Net.Mobile
与.NET MAUI不兼容,所以我正在尝试升级到ZXing.Net.MAUI
。
在
ZXing.Net.MAUI
中,似乎我需要一个用于扫描的 MAUI 内容页面,并从我的 MainActivity
导航到该页面。我设法导航到扫描仪页面,但相机没有显示。我也不确定如何将扫描结果发送回我的 MainActivity
,然后发送到我的 WebView,因为这都是 JavaScript 调用。
相关代码如下:
[Activity(Label = "ZXingScanActivity")]
public class ZXingScanActivity : Activity
{
public static string m_Tag = "ZXingScanActivity";
public static readonly Lazy<MauiApp> MauiApp = new(() =>
{
var mauiApp = MauiProgram.CreateMauiApp(builder =>
{
builder
.UseMauiEmbedding()
.UseBarcodeReader();
});
return mauiApp;
});
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var mauiApp = MauiApp.Value;
var mauiContext = new MauiContext(mauiApp.Services, this);
var mauiView = new ZXingScannerPage();
var scannerView = mauiView.ToPlatformEmbedded(mauiContext);
SetContentView(scannerView);
}
}
public async Task<string> OpenZXingScanner()
{
RunOnUiThread(() =>
{
var intent = new Intent(this, typeof(ZXingScanActivity));
StartActivity(intent);
});
return string.Empty;
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls"
x:Class="TWP.Pages.ZXingScannerPage">
<zxing:CameraBarcodeReaderView x:Name="barcodeReader" BarcodesDetected="BarcodesDetected" />
</ContentPage>
namespace TWP.Pages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ZXingScannerPage : ContentPage
{
public ZXingScannerPage()
{
InitializeComponent();
barcodeReader.Options = new BarcodeReaderOptions
{
Formats = BarcodeFormats.All,
AutoRotate = true,
Multiple = false
};
barcodeReader.CameraLocation = CameraLocation.Front;
}
public void BarcodesDetected(object sender, BarcodeDetectionEventArgs e)
{
var first = e.Results?.FirstOrDefault();
if (first is null)
return;
Dispatcher.DispatchAsync(async () =>
{
await DisplayAlert("Barcode Detected", first.Value, "OK");
await Navigation.PopAsync();
});
}
}
}
<uses-permission android:name="android.permission.CAMERA" />
我有一个类似的任务,并遇到了类似的问题:我将一个 xamarin 应用程序移动到了 MAUI 应用程序,并且我在 Xamarin 应用程序上使用 ZXing 实现了 QR 阅读。
虽然这不能完全回答你的问题,但我可以告诉你我是如何解决这个问题的:使用另一个 NuGet 包,即 Camera.MAUI。我花了很多时间尝试使用 ZXing.Net.MAUI,最终放弃了。
MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.UseMauiCommunityToolkit()
.UseMauiCameraView();
return builder.Build();
}
QRScanPage.xaml
<ContentPage
xmlns:cv="clr-namespace:Camera.MAUI;assembly=Camera.MAUI"
xmlns:cvz="clr-namespace:Camera.MAUI.ZXingHelper;assembly=Camera.MAUI">
<cv:CameraView
x:Name="cameraView"
BackgroundColor="Transparent"
IsEnabled="{Binding IsCameraVisible}"
BarCodeDetectionEnabled="True"
BarcodeDetected="OnBarcodeDetected"
Loaded="OnCamerasLoaded">
</cv:CameraView>
</ContentPage>
QRScanPage.xaml.cs
private void OnCamerasLoaded(object sender, EventArgs e)
{
if (cameraView.NumCamerasDetected > 0)
{
cameraView.Camera = cameraView.Cameras.First();
cameraView.BarCodeOptions = new BarcodeDecodeOptions
{
AutoRotate = true,
PossibleFormats = { BarcodeFormat.QR_CODE },
ReadMultipleCodes = false,
TryHarder = true,
TryInverted = true
};
cameraView.BarCodeDetectionFrameRate = 10;
cameraView.BarCodeDetectionMaxThreads = 5;
cameraView.ControlBarcodeResultDuplicate = true;
MainThread.BeginInvokeOnMainThread(async () =>
{
await Task.Delay(100); // Workaround: fixes the initial blurry resolution of the first camera start.
await cameraView.StartCameraAsync();
});
}
}
private void OnBarcodeDetected(object sender, Camera.MAUI.ZXingHelper.BarcodeEventArgs e)
{
foreach (var result in e.Result)
{
if (result.BarcodeFormat == BarcodeFormat.QR_CODE)
{
// do stuff
}
}
}
您仍然需要相机许可。
希望这有帮助!
编辑:Camera.MAUI 存储库:https://github.com/hjam40/Camera.MAUI