如何在 Android 上使用来自 .NET MAUI 的 BroadcastReceiver?

How to use a BroadcastReceiver from .NET MAUI on Android?

我有来自为 Xamarin.Android(不是表单)编写的示例应用程序的现有代码。我需要在我为 .NET MAUI 编写的新应用程序中使用它,它是所有 Xamarin 的继任者。它使用 BroadcastReceiver 来了解 USB 设备何时与 phone 分离。但这在 MAUI 中不起作用。

这是旧代码:

public partial class MainPage : ContentPage
{
    private BroadcastReceiver detachedReceiver;

    public MainPage()
    {
        InitializeComponent();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();

        OnScanClicked(this, EventArgs.Empty);

        // TODO: Fix for MAUI
        //register the broadcast receivers
        detachedReceiver = new UsbDeviceDetachedReceiver(this);
        RegisterReceiver(detachedReceiver, new IntentFilter(UsbManager.ActionUsbDeviceDetached));
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();

        CloseDevice();

        // TODO: Fix for MAUI
        var temp = detachedReceiver; // copy reference for thread safety
        if (temp != null)
            UnregisterReceiver(temp);
    }

    private async void OnScanClicked(object sender, EventArgs args)
    {
        // Here's some code
    }

    class UsbDeviceDetachedReceiver : BroadcastReceiver
    {
        readonly MainPage mainPage;

        public UsbDeviceDetachedReceiver(MainPage mainPage)
        {
            this.mainPage = mainPage;
        }

        public override void OnReceive(Context context, Intent intent)
        {
            mainPage.OnScanClicked(null, null);
        }
    }
}

两个 TODO 注释下面的代码无法编译。我想不出应该如何为 MAUI 编写。有什么想法吗?

在 MAUI 中,您在 Xamarin.Android 中放入 Activity 生命周期事件的代码可以作为 App Builder 的一部分在 #if ANDROID 中完成。这记录在 Platform Lifecycle Events.

来自文档的示例:

using Microsoft.Maui.LifecycleEvents;

namespace PlatformLifecycleDemo
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureLifecycleEvents(events =>
                {
#if ANDROID
                    events.AddAndroid(android => android
                        .OnActivityResult((activity, requestCode, resultCode, data) => LogEvent("OnActivityResult", requestCode.ToString()))
                        .OnStart((activity) => LogEvent("OnStart"))
                        .OnCreate((activity, bundle) => LogEvent("OnCreate"))
                        .OnBackPressed((activity) => LogEvent("OnBackPressed"))
                        .OnStop((activity) => LogEvent("OnStop")));
#endif
                    static void LogEvent(string eventName, string type = null)
                    {
                        System.Diagnostics.Debug.WriteLine($"Lifecycle event: {eventName}{(type == null ? string.Empty : $" ({type})")}");
                    }
                });

            return builder.Build();
        }
    }
}

在 Xamarin.Android 文档中,我们找到 Broadcast Receivers in Xamarin.Android.

使用自定义广播接收器的示例:

// --- This is Xamarin.Android code, not MAUI code. ---
[Activity(Label = "MainActivity", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity: Activity
{
    MySampleBroadcastReceiver receiver;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        receiver = new MySampleBroadcastReceiver();

        // Code omitted for clarity
    }

    protected override void OnResume()
    {
        base.OnResume();
        RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));
        // Code omitted for clarity
    }

    protected override void OnPause()
    {
        UnregisterReceiver(receiver);
        // Code omitted for clarity
        base.OnPause();
    }
}

为了保持 MAUI's App Builder 代码简洁,我将定义从构建器代码调用的方法:

public static class MauiProgram
...
#if ANDROID
private static void MyOnCreate(Activity activity, Bundle bundle)
{
    receiver = new MySampleBroadcastReceiver();
}
private static void MyOnResume(Activity activity)
{
    activity.RegisterReceiver(receiver, new IntentFilter("com.xamarin.example.TEST"));
}
private static void MyOnPause(Activity activity)
{
    activity.UnregisterReceiver(receiver);
}
#endif

因此构建器代码始终为:

    ...
    builder
        .UseMauiApp<App>()
        .ConfigureLifecycleEvents(events =>
        {
#if ANDROID
            events.AddAndroid(android => android
                .OnCreate((activity, bundle) => MyOnCreate(activity, bundle))
                .OnResume((activity) => MyOnResume(activity))
                .OnPause((activity) => MyOnPause(activity)));
#endif
        });

在您的情况下,将您的旧 OnAppearing 代码放入 MyOnResume



注意:可以使用 .net 6 编写 Android 应用程序, 无需 任何提及 MAUI。这几乎与编写 Xamarin.Android 应用程序相同,除了命名空间更改。

要创建“.Net 6 Android”应用程序,在 VS 2022(预览版)中,“创建新项目”时,选择 “Android 应用程序(预览版) )".