0

I am trying to create a notification to be triggered on a schedule. I want the notification to show once a day around a set time (doesn't have to be exact). So what I'm trying to do is create a PeriodicWorkRequest that runs every 24 hours, and delay the start of the work request to the time of day I want it to run. I can get it running on a schedule, but whenever I create it, it just runs right away. I found some questions saying you can use .setInitialDelay() on the builder, however this doesn't seem to be available in the Xamarin Work Manager API. I have also tried .SetPeriodStartTime() on the Builder class after finding the method in the builder class definition, but this doesn't seem to be affecting anything.

            MessagingCenter.Subscribe<StartNotificationRemindersMessage>(this, "StartNotificationRemindersMessage", message => {
                TimeSpan startDelay = DateTime.Now.AddMinutes(2) - DateTime.Now;

                PeriodicWorkRequest notificationsWorkRequest = PeriodicWorkRequest.Builder.From<NotificationsWorker>(1, TimeUnit.Days).SetPeriodStartTime(startDelay).Build();
                WorkManager.Instance.Enqueue(notificationsWorkRequest);
            });

Here I'm creating the periodic work request and trying to add a 2 minute delay to the start.

And here is the NotificationsWorker class.

    class NotificationsWorker : Worker
    {
        public NotificationsWorker(Context context, WorkerParameters workerParameters) : base(context, workerParameters)
        {

        }
        public override Result DoWork()
        {
            CrossLocalNotifications.Current.Show("GCS Reminder", "Testing reminder notifications");
            return Result.InvokeSuccess();
        }
    }

If someone can show me what I'm doing wrong, it would be much appreciated.

Thanks!

AdamMasters
  • 355
  • 3
  • 19
  • 1
    You can use `AlarmManager` and `Calendar ` to execute your task. `Calendar ` could shedule a time, `AlarmManager` could executed when arrival the time. You can see my this thread :https://stackoverflow.com/a/61356731/10627299 – Leon May 06 '20 at 14:26
  • @LeonLu-MSFT This works exactly as I need as long as the app is open. How can I get it to continue running after closing the app? – AdamMasters May 06 '20 at 16:39
  • If you closed your application, I cannot found a effective way to achieve it, But If application run in the background, you can use foreground service to keep the AlarmManager running continuously. – Leon May 07 '20 at 08:01

2 Answers2

0

There is an extension method named SetPeriodStartTime. It's extremely hard to find any documentation on it, but I've been experimenting with it and it appears to do the trick.

E.g.

   PeriodicWorkRequest workRequest = PeriodicWorkRequest.Builder
     .From<YourWorkerClass>(repeatInterval, flexInterval)
     .SetPeriodStartTime(TimeSpan.FromHours(1))
     .Build();
dsk
  • 101
  • 1
  • 1
  • 6
0

setInitialDelay() is now available on the builder in the Xamarin Work Manager API for Xamarin Android

I use setInitialDelay() to make sure PeriodicWorkRequest is delayed for a while you get a WorkRequest so Just cast it to a PeriodicWorkRequest

PeriodicWorkRequest notificationsWorkRequest = (PeriodicWorkRequest)PeriodicWorkRequest.Builder.From<YourWorkerClass>(repeatInterval,repeatIntervalTimeUnit).SetInitialDelay(repeatInterval,repeatIntervalTimeUnit).Build();

WorkManager.GetInstance(Android.App.Application.Context).Enqueue(notificationsWorkRequest );

Then to use it in Xamarin.Forms I use a dependency service, messaging center, or I just define it in the Android Main activity class depending on my reason for using work manager

example would be

PeriodicWorkRequest notificationsWorkRequest = (PeriodicWorkRequest) PeriodicWorkRequest.Builder.From<NotificationsWorker>(24, Java.Util.Concurrent.TimeUnit.Hours).SetInitialDelay(24, Java.Util.Concurrent.TimeUnit.Hours).Build();
Olayiwola Osho
  • 121
  • 2
  • 4