Search code examples
c#androidxamarin.formsxamarin.android

Android 10 Xamarin.Forms MainActivity as FullScreen Intent for Alarm


I'm trying to patch an existing Xamarin.Android Forms based application to work with Android 10 devices.

We have one only one activity in the app, and we use the Forms Navigation system to push and pop alert pages.

We have a background service that may request the main activity to push a new page and interrupt the user on pre 10 devices.

Because we can no more interrupt the user running Android 10, we've decided to take the Google recommended route. I have found this previous answer for an implementation example.

Basically the pre Android 10 code is this:

    // post on ui thread
    Android.App.Application.SynchronizationContext.Post(
   _ =>
   {
       Intent intent = new Intent(this.applicationContext, typeof(MainActivity));
       // intent.AddFlags(ActivityFlags.NoHistory);
       intent.AddFlags(ActivityFlags.FromBackground);
       intent.AddFlags(ActivityFlags.NewTask);
       this.applicationContext.StartActivity(intent);
   },
   null);

The new code becomes:

var builder = new NotificationCompat.Builder(context: this.applicationContext, channelId: channelId);
builder.SetContentTitle(title: notification.Title);
builder.SetContentText(text: notification.Text);
builder.SetSmallIcon(icon: this.resourceManager.GetImage(resourceName: notification.Icon));
builder.SetPriority(pri: notification.Priority);
builder.SetAutoCancel(autoCancel: true);

Intent nextScreen = new Intent(this.applicationContext, typeof(MainActivity));

PendingIntent intent = PendingIntent.GetActivity(
context: this.applicationContext,
requestCode: 0,
intent: nextScreen,
flags: PendingIntentFlags.OneShot);

builder.SetFullScreenIntent(intent: intent, highPriority: true);
this.notificationManager.Notify(id: notification.Id, notification: builder.Build());

But the new code does not work.

What happens is that the notification is displayed in the notification Area and not full screen.

I'm under the impression that I need to use a new Activity.

Can't I use the app root activity?


Solution

  • Update 1 : this code works on pre android 10 device wether the device is locked or not, the app in the foreground or not.

    This works partially (not on the lock screen) with this new code:

    var manager = (Android.App.AlarmManager)this.applicationContext.GetSystemService(Context.AlarmService);
    using (var calendar = Calendar.Instance)
    {
        calendar.Add(CalendarField.Second, 1);
    
        Intent fullScreenIntent = new Intent(this.applicationContext, typeof(MainActivity));
        PendingIntent fullScreenPendingIntent = PendingIntent.GetActivity(
             this.applicationContext,
             0,
             fullScreenIntent,
             PendingIntentFlags.OneShot);
    
             manager.SetExact(AlarmType.RtcWakeup, calendar.TimeInMillis, fullScreenPendingIntent);
    }
    

    Update 2: A working solution was simply to request OverlayPermission for the application and stick with the old code (first block of the question).

    At startup we call the following new method:

    private async Task ManageOverlayPermissionAsync()
    {
        IPopupService popupService = Locator.GetSharedInstance<IPopupService>();
        if (BusinessHelper.AndroidMajorVersion >= 10 && !Android.Provider.Settings.CanDrawOverlays(Forms.Context))
        {
            if (await popupService.DisplayAlertAsync(
                    BusinessResources.GoToOverlayPermissionTitle,
                    BusinessResources.GoToOverlayPermissionMessage,
                    BusinessResources.Ok,
                    BusinessResources.Cancel))
            {
                var intent = new Intent(Android.Provider.Settings.ActionManageOverlayPermission,
                    Android.Net.Uri.Parse("package:" + Forms.Context.PackageName));
                Forms.Context.StartActivity(intent);
            }
        }
    }
    

    The user is then directed to the settings to enable the feature.