如何在 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 应用程序(预览版) )".
我有来自为 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 应用程序(预览版) )".