user7615935
user7615935

Reputation:

Scheduling a local Notification with System Date and notifies without launching the App (Xamarin.Forms)

Am trying to schedule a local notification depending on the time set in SQLite , I am using a certain library in this link :

local Notification library

I have implemented it well, but am still facing the problems below:

a) The notification comes only when I launch the App.

b)All notification time notifies once which are stored locally in SQLite.

Now how can I make this Application to capture the system time (Phone time) and it notifies like an Alarm without even launching the Application

Am I supposed to use one of these methods:

i) OnSleep

ii)OnResume etc or...

So below is how I was placing my code in App.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using Diabetes.localDB;
using Diabetes.Main;
using Newtonsoft.Json;
using Plugin.Notifications;
using Xamarin.Forms;

namespace Diabetes
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            // Setting the Alarm time 
            MedicationDatabase db = new MedicationDatabase();
            //Getting  list of time set in SQlite.
            var alarm_list = db.GetAlarmList();

            // Looping each time to make an alarm
            foreach (var alarm in alarm_list)
            {
                try
                {

                    Debug.WriteLine("Date Time Format : " + alarm);

                //This is the library to set Notifications, Date is where the time is attached.
                    CrossNotifications.Current.Send(new Notification
                    {
                        Title = "Hola! ",
                        Message = "Hey  Eddy I remind you take insulin, this is the time you told me to remind you.",
                        Vibrate = true,
                        Sound = "pop",
                        Date = DateTime.Parse(alarm)

                    });
                }
                catch (FormatException v)
                {
                    Debug.WriteLine("Format Exception : " + v);
                }
                catch (OverflowException c)
                {
                    Debug.WriteLine("Overflow Exception : " + c);
                }


            }

            MainPage = new NavigationPage(new Login())

            {
                BarBackgroundColor = Color.FromHex("#66C8F3"),
                BarTextColor = Color.White,
                Title = "Diabetics App"


            };
        }

        protected override void OnStart()
        {


        }



        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }





    }
}

Upvotes: 1

Views: 917

Answers (1)

Grace Feng
Grace Feng

Reputation: 16652

Now how can I make this Application to capture the system time (Phone time) and it notifies like an Alarm without even launching the Application

You can use Android.App.AlarmManager, this class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.

Since you're using XF for development, then, firstly you should be able to create a receiver for broadcast in Android Client Project for example:

[BroadcastReceiver]
public class AlarmReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        var message = intent.GetStringExtra("message");
        var title = intent.GetStringExtra("title");

        var resultIntent = new Intent(context, typeof(MainActivity));
        resultIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

        var pending = PendingIntent.GetActivity(context, 0,
            resultIntent,
            PendingIntentFlags.CancelCurrent);

        var builder =
            new Notification.Builder(context)
                .SetContentTitle(title)
                .SetContentText(message)
                .SetSmallIcon(Resource.Drawable.Icon)
                .SetDefaults(NotificationDefaults.All);

        builder.SetContentIntent(pending);

        var notification = builder.Build();

        var manager = NotificationManager.FromContext(context);
        manager.Notify(10010, notification);
    }
}

Then in XF, when we need to use native method of each platform from PCL, we can use DependencyService to implement it.

In PCL, create an interface like this:

public interface ISetAlarm
{
    void SetAlarm(int hour, int minute);
}

Then, in Android client project, implement this interface for example like this:

[assembly: Xamarin.Forms.Dependency(typeof(SetAlarmImplementation))]
namespace YOURNAMESPACE.Droid
{
    public class SetAlarmImplementation : ISetAlarm
    {
        public void SetAlarm(int hour, int minute)
        {
            Intent myintent = new Intent(Xamarin.Forms.Forms.Context, typeof(AlarmReceiver));
            var pendingintent = PendingIntent.GetBroadcast(Xamarin.Forms.Forms.Context, 0, myintent, PendingIntentFlags.UpdateCurrent);

            Java.Util.Date date = new Java.Util.Date();
            Java.Util.Calendar cal = Java.Util.Calendar.Instance;
            cal.TimeInMillis = Java.Lang.JavaSystem.CurrentTimeMillis();
            cal.Set(Java.Util.CalendarField.HourOfDay, hour);
            cal.Set(Java.Util.CalendarField.Minute, minute);
            cal.Set(Java.Util.CalendarField.Second, 0);

            AlarmManager alarmManager = Xamarin.Forms.Forms.Context.GetSystemService(Android.Content.Context.AlarmService) as AlarmManager;
            alarmManager.Set(AlarmType.RtcWakeup, cal.TimeInMillis, pendingintent);
        }
    }
}

Then finally when you want to call this from PCL, you can call it like this:

DependencyService.Get<ISetAlarm>().SetAlarm(13, 30);  

Upvotes: 1

Related Questions