0

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 hole, I'll give you a buzz when I'm done."

How do I set up notifications to appear after set times? For example the above statement may take 10 minutes, then the user receives a notification to continue the game?

I've only started C# a week ago, so I apologize if this is noobish, or already been asked. I have looked everywhere but there are several types of notification, and it seems like I'm reading french when I try to make sense of it.

Cœur
  • 37,241
  • 25
  • 195
  • 267
A.Bruce
  • 21
  • 1
  • 4

2 Answers2

0

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.

Koen
  • 96
  • 5
0
  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();
      }
    }
    
Amir Touitou
  • 3,141
  • 1
  • 35
  • 31