I have existing code from a sample app written for Xamarin.Android (not Forms). I need to use this in my new app written for .NET MAUI, the successor of all Xamarin. It uses a BroadcastReceiver to know when a USB device was detached from the phone. But this doesn't work in MAUI.
Here's the old code:
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);
}
}
}
The code below the two TODO comments doesn't compile. I cannot figure out how this should be written for MAUI. Any ideas?
CodePudding user response:
In MAUI, code that in Xamarin.Android
you would have put in Activity
lifecycle events, can be done inside #if ANDROID
, as part of the App Builder. This is documented in Platform Lifecycle Events.
Example from doc:
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();
}
}
}
In Xamarin.Android docs, we find Broadcast Receivers in Xamarin.Android.
Its example of using a custom Broadcast Receiver:
// --- 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();
}
}
To keep MAUI's App Builder
code concise, I would define methods that are called from the builder code:
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
So that the builder code is always:
...
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
});
In your case, place your old OnAppearing
code into MyOnResume
.
NOTE: It is possible to use .net 6
to write an Android
app, without any mention of MAUI
. That would be almost identical to writing a Xamarin.Android
app, except for namespace changes.
To create a ".Net 6 Android" app, in VS 2022 (Preview), when "Create a new project", choose "Android Application (Preview)".