0

Am trying to schedule a notification with a list of time suppose i want to schedule the following time:

1. 22:00
2. 10:00
3. 17:00

This is how i tackled it ,

a). first i stored the time in Sqlite,

b). then i used for each loop to make sure i insert the list of time in the scheduled manager, but the notification doesn't come.

Even when i tried to print in the console, it shows that the time is available, but am wondering why the notification not working.

My codes are below:

   public void MyLooper()
        {
            try
            {
                alarmService = new SetAlarmImplementation();
                MedicationDatabase c = new MedicationDatabase();
                //get schedulled time list
                var alarm = c.GetAlarmList();
                var username = c.GetUserName();
                var hour = 0;
                var minute = 0;

                foreach (var list in alarm)
                {
                    // This is the time i pick from the list
                    hour = Int32.Parse(list.Substring(0, 2));
                    minute = Int32.Parse(list.Substring(3, 2));

                    try
                    {
                        System.Diagnostics.Debug.WriteLine("Hour : " + hour + " Minutes : " + minute);

                        alarmService.SetAlarm(hour, minute, "Diabetics App", "Hello  " + username + " , I remind you to take your insulin at this stated time");
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine("Error  " + e);
                    }

                }
            }
            catch (Exception f)
            {

            }

        }

But surprisingly if i insert directly time in the code like this it works fine :

alarmService.SetAlarm(13, 14, "Diabetics App", "Hello  " + username + " , I remind you to take your insulin at this stated time");

How will i be able to register all the stored time in the alarm manager ?

EDIT

Alarm Implementation:

namespace Diabetes.Droid
{
    public class SetAlarmImplementation : ISetAlarm
    {

        public SetAlarmImplementation() { }


        public void SetAlarm(int hour, int minute, string title, string message)
        {


            Intent myintent = new Intent(Android.App.Application.Context, typeof(AlarmReceiver));
            myintent.PutExtra("message", message);
            myintent.PutExtra("title", title);
            int _id = DateTime.Now.Millisecond;


            TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
            long millis = (long)ts.TotalMilliseconds;
            int i = (int)millis;

            PendingIntent pendingintent = PendingIntent.GetBroadcast(Android.App.Application.Context, i, myintent, PendingIntentFlags.OneShot);

            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 = Android.App.Application.Context.GetSystemService(Android.Content.Context.AlarmService) as AlarmManager;
            alarmManager.Set(AlarmType.RtcWakeup, cal.TimeInMillis, pendingintent);
        }


    }
}

My Alarm Receiver ?

using System;
using Android.App;
using Android.Content;
using Android.Media;
using Android.Support.V4.App;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using Android.Widget;
using Diabetes.localDB;
using Xamarin.Forms;

namespace Diabetes.Droid
{
    [BroadcastReceiver]
    [IntentFilter(new string[] { "android.intent.action.BOOT_COMPLETED" }, Priority = (int)IntentFilterPriority.LowPriority)]
    public class AlarmReceiver : BroadcastReceiver
    {



        public override void OnReceive(Context context, Intent intent)
        {
            var message = intent.GetStringExtra("message");
            var title = intent.GetStringExtra("title");
            Intent i = new Intent(context, typeof(AppStickyService));
            i.PutExtra("message", message);
            i.PutExtra("title", title);
            context.StartService(i);

        }
    }

    [BroadcastReceiver]
    [IntentFilter(new string[] { "TAKE", "SKIP" })]
    public class CustomActionReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {

            switch (intent.Action)
            {
                case "TAKE":
                    try
                    {
                        MedicationDatabase db = new MedicationDatabase();
                        db.addtracktaken("true");
                        Toast.MakeText(context, "DOSAGE TAKEN", ToastLength.Short).Show();
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e.StackTrace);
                    }
                    break;
                case "SKIP":
                    try
                    {
                        Toast.MakeText(context, "DOSAGE SKIPPED", ToastLength.Short).Show();
                        MedicationDatabase db = new MedicationDatabase();
                        db.addtrackmissed("true");
                        Toast.MakeText(context, "DOSAGE MISSED", ToastLength.Short).Show();
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e.StackTrace);
                    }
                    break;
            }


        }
    }
}

Then the Service Class

using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using Java.Util;

namespace Diabetes.Droid
{

    [Service(Exported = true, Name = "com.diabetics.Diabetes.AppStickyService")]
    public class AppStickyService : IntentService
    {

        public override void OnCreate()
        {
            base.OnCreate();
            Toast.MakeText(this, "service started ", ToastLength.Long).Show();

            System.Diagnostics.Debug.WriteLine("Sticky Service - Created");
        }

        public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {

            WireAlarm(intent);

            return StartCommandResult.Sticky;
        }

        public override Android.OS.IBinder OnBind(Android.Content.Intent intent)
        {
            System.Diagnostics.Debug.WriteLine("Sticky Service - Binded");
            Toast.MakeText(this, "Service started", ToastLength.Long).Show();

            return null;
        }

        public override void OnDestroy()
        {
            try
            {
                base.OnDestroy();

            }
            catch (Java.Lang.IllegalStateException ex)
            {
                //Log.Debug("MainActivity.OnDestroy", ex, "The activity was destroyed twice");
                System.Diagnostics.Debug.WriteLine("Sticky Service error "+ ex);
            }



        }


        private void cancelnotification(int id)
        {
            NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
            notificationManager.Cancel(id);
        }

        public void SetAlarm(int hour, int minute, string title, string message)
        {

            //AppContext.StartService(new Intent(AppContext, typeof(AppStickyService)));
            Intent myintent = new Intent(Android.App.Application.Context, typeof(AppStickyService));
            myintent.PutExtra("message", message);
            myintent.PutExtra("title", title);
            //PendingIntent pendingintent = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, myintent, PendingIntentFlags.UpdateCurrent);
            PendingIntent pintent = PendingIntent.GetService(this, 0, new Intent(this, typeof(AppStickyService)), 0);

            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 = Android.App.Application.Context.GetSystemService(Android.Content.Context.AlarmService) as AlarmManager;
            alarmManager.Set(AlarmType.RtcWakeup, cal.TimeInMillis, pintent);
            Toast.MakeText(this, "Service started ", ToastLength.Long).Show();
        }


        public void WireAlarm(Intent intent)
        {
            //Show toast here
            //Toast.MakeText(context, "Hello it's me ", ToastLength.Short).Show();
            var message = intent.GetStringExtra("message");
            var title = intent.GetStringExtra("title");

            //Create intent for action 1 (TAKE)
            var actionIntent1 = new Intent();
            actionIntent1.SetAction("TAKE");
            var pIntent1 = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, actionIntent1, PendingIntentFlags.CancelCurrent);

            //Create intent for action 2 (REPLY)
            var actionIntent2 = new Intent();
            actionIntent2.SetAction("SKIP");
            var pIntent2 = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, actionIntent2, PendingIntentFlags.CancelCurrent);

            Intent resultIntent = Android.App.Application.Context.PackageManager.GetLaunchIntentForPackage(Android.App.Application.Context.PackageName);

            var contentIntent = PendingIntent.GetActivity(Android.App.Application.Context, 0, resultIntent, PendingIntentFlags.CancelCurrent);

            var pending = PendingIntent.GetActivity(Android.App.Application.Context, 0,
                resultIntent,
                PendingIntentFlags.CancelCurrent);

            //Debug.WriteLine(" Time -- : "+ m.ToString());


            // Instantiate the Big Text style:
            Notification.BigTextStyle textStyle = new Notification.BigTextStyle();


            var builder =
                new Notification.Builder(Android.App.Application.Context)
                                .AddAction(Resource.Drawable.tick_notify, "TAKE", pIntent1)
                                .AddAction(Resource.Drawable.cancel_notify, "SKIP", pIntent2)
                                .SetSmallIcon(Resource.Drawable.ic_launcher)
                                .SetContentTitle("Diabetics Reminder")
                                .SetDefaults(NotificationDefaults.Sound)
                                .SetStyle(new Notification
                                .BigTextStyle()
                                .SetSummaryText("")
                                .SetBigContentTitle(title)
                                .BigText(message)
             ).SetDefaults(NotificationDefaults.All);

            builder.SetContentIntent(pending);

            var notification = builder.Build();


            var manager = NotificationManager.FromContext(Android.App.Application.Context);
            manager.Notify(10010, notification);
        }

        protected override void OnHandleIntent(Intent intent)
        {
            throw new NotImplementedException();
        }
    }
}

1 Answers1

0

I can't see your implementation of the alarm service, but the problem could be that in order to have multiple alarms in Android, each one needs a unique identifier. So you may be overwriting the same alarm each iteration of the loop in your code. See this answer for more details.

David Conlisk
  • 3,387
  • 4
  • 33
  • 39
  • thanks for the response @David , would you mind to check on my post again i have updated it –  Nov 07 '17 at 21:13
  • This is what i used but still not working `int _id = DateTime.Now.Millisecond; PendingIntent pendingintent = PendingIntent.GetBroadcast(Android.App.Application.Context, _id, myintent, PendingIntentFlags.OneShot);` –  Nov 07 '17 at 21:26
  • @IdrisStack I still think you're probably overwriting in the loop (see Jakar's answer in the link I shared) - you could test this with 3 times close together and see if you get a notification at the 3rd time in the loop. In my own app scheduling I schedule one notification at a time, and after each notification fires, I then schedule the next one. The fact that your single call works tells me your code is probably fine apart from the loop. – David Conlisk Nov 08 '17 at 09:16