Skip to content Skip to sidebar Skip to footer

Pushing Notifications When App Is Closed

I am looking to create a Text-Based Android game using C# in Xamarin Forms. In the story, I want to set the character tasks, which will take them some time e.g. 'I'll go dig this h

Solution 1:

I would start by creating 2 Interfaces in the PCL Project:

public interface IAlarm {
    void SetAlarm();
}

public interface INotification {
    void Notify(LocalNotification notification);
}

Then, in the Android Project, create the implementations:

Alarm Helper

[assembly: Dependency(typeof(AlarmHelper))]
namespace Test.Droid
{
    class AlarmHelper: IAlarm
    {
        public void SetAlarm(int minutes)
        {
            var alarmTime = Calendar.Instance;
            alarmTime.Add(CalendarField.Minute, minutes);

            var intent = new Intent(Android.App.Application.Context, typeof(ScheduledAlarmHandler));
            var pendingIntent = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, intent, PendingIntentFlags.CancelCurrent);
            var alarmManager = Android.App.Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;

            alarmManager.Set(AlarmType.RtcWakeup, alarmTime.TimeInMillis, pendingIntent); 
        }
    }
}

Notification Helper

[assembly: Dependency(typeof(NotificationHelper))]
namespace Test.Droid
{
    class NotificationHelper : INotification
    {
        public void Notify (string title, string text)
        {            
            NotificationManager notificationManager = (NotificationManager) Android.App.Application.Context.GetSystemService(Context.NotificationService);

            Intent intent = new Intent(Android.App.Application.Context, typeof(MainActivity));
            PendingIntent pIntent = PendingIntent.GetActivity(Android.App.Application.Context, 0, intent, PendingIntentFlags.OneShot);

            Notification nativeNotification = new Notification();

            var builder = new NotificationCompat.Builder(Android.App.Application.Context)
            .SetContentTitle(title)
            .SetContentText(text)
            .SetSmallIcon(Resource.Drawable.ic_notif) // 24x24 dp
            .SetLargeIcon(BitmapFactory.DecodeResource(Android.App.Application.Context.Resources, Android.App.Application.Context.ApplicationInfo.Icon))
            .SetPriority((int)NotificationPriority.Default)
            .SetAutoCancel(true)
            .SetContentIntent(pIntent);

            notificationManager.Notify(0, builder.Build()); // Id 0 can be random
        }
    }
}

When the waiting time is over, the BroadCastReceiver will be called:

[BroadcastReceiver]
class ScheduledAlarmHandler : WakefulBroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Implement quick checking logic here if notification is still required, plus its tittle and text
        // you have 10 seconds max in this method and cannot use 'await'

        var notificationHelper = new NotificationHelper();
        notificationHelper.Notify("Title","Text");
    }
}

In the PCL project game logic, you can set a new alarm as follows:

alarmHelper = DependencyService.Get<IAlarm>();
alarmSetter.SetAlarm(10); // 10 minutes from now

I have intentionally separated the Alarm & Notification logic, to enable you to check after 10 minutes if the notification should still be displayed and set its title and text. An alternative is to pass the title and text at time of setting the alarm using intent.putextra.


Solution 2:

  1. Add this line to your AndroidManifest.xml

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
  2. Implement BroadcastReceiver in your android project

    [BroadcastReceiver]
    public class NotificationBroadcastReceiver : BroadcastReceiver
    {
      private ApprovalDataStore _approvalDataStore => DependencyService.Get<ApprovalDataStore>();
    
      public override async void OnReceive(Context context, Intent intent)
      {
         var pm = PowerManager.FromContext(context);
         var wakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "GCM Broadcast Reciever Tag");
         wakeLock.Acquire();
    
         //Write your code here
    
         // When you are finished
         wakeLock.Release();
      }
    }
    

Post a Comment for "Pushing Notifications When App Is Closed"