// LocalNotification { Title, Message }
// HourMinute { mHour, mMinute }
// dayOfWeek {1: Sunday, 2: Monday, 3: Tuesday, 4: Wednesday, 5: Thursday, 6: Friday, 7: Saturday}
// Example: Send notification at 9:00am every Wednesday: scheduleTime = { mHour: 9, mMinute: 0 }, dayOfWeek = 4
public void SetSchedule(LocalNotification notification, HourMinute scheduleTime, int dayOfWeek)
{
var appContext = Application.Context;
int id = 1234567890;
// Create a BroadcastReceiver intent
Intent intent = new Intent(appContext, typeof(AlarmBroadcastReceiver));
intent.PutExtra("title", notification.Title);
intent.PutExtra("message", notification.Message);
// Create a PendingIntent
PendingIntent pendingIntent = PendingIntent.GetBroadcast(appContext, id, intent, PendingIntentFlags.CancelCurrent);
// Set trigger time
var triggerTime = Calendar.Instance;
while (triggerTime.Get(CalendarField.DayOfWeek) != dayOfWeek)
{
// if today is not dayOfWeek, then find next day until find that day
// dayOfWeek = Calendar.Wednesday
triggerTime.Add(CalendarField.Date, 1);
}
triggerTime.Set(CalendarField.HourOfDay, scheduleTime.mHour);
triggerTime.Set(CalendarField.Minute, scheduleTime.mMinute);
triggerTime.Set(CalendarField.Second, 0);
Console.WriteLine("+++++++++++++" + triggerTime.Time);
// Setup an AlarmManager to trigger this pending intent
// Example: Send notification at 9:00am every Wednesday: scheduleTime = { mHour: 9, mMinute: 0 }, dayOfWeek = 4
AlarmManager alarmManager = appContext.GetSystemService(Context.AlarmService) as AlarmManager;
alarmManager.SetRepeating(AlarmType.RtcWakeup, triggerTime.TimeInMillis, AlarmManager.IntervalDay * 7, pendingIntent);
}
// LocalNotification { Title, Message }
// HourMinute { mHour, mMinute }
// dayOfWeek {1: Sunday, 2: Monday, 3: Tuesday, 4: Wednesday, 5: Thursday, 6: Friday, 7: Saturday}
// Example: Send notification at 9:00am every Wednesday: scheduleTime = { mHour: 9, mMinute: 0 }, dayOfWeek = 4
public void SetSchedule(LocalNotification notification, HourMinute scheduleTime, int dayOfWeek)
{
var appContext = Application.Context;
int id = 1234567890;
// Create a BroadcastReceiver intent
Intent intent = new Intent(appContext, typeof(AlarmBroadcastReceiver));
intent.PutExtra("title", notification.Title);
intent.PutExtra("message", notification.Message);
// Create a PendingIntent
PendingIntent pendingIntent = PendingIntent.GetBroadcast(appContext, id, intent, PendingIntentFlags.CancelCurrent);
// Set trigger time
var triggerTime = Calendar.Instance;
while (triggerTime.Get(CalendarField.DayOfWeek) != dayOfWeek)
{
// if today is not dayOfWeek, then find next day until find that day
// dayOfWeek = Calendar.Wednesday
triggerTime.Add(CalendarField.Date, 1);
}
triggerTime.Set(CalendarField.HourOfDay, scheduleTime.mHour);
triggerTime.Set(CalendarField.Minute, scheduleTime.mMinute);
triggerTime.Set(CalendarField.Second, 0);
Console.WriteLine("+++++++++++++" + triggerTime.Time);
// Setup an AlarmManager to trigger this pending intent
// Example: Send notification at 9:00am every Wednesday: scheduleTime = { mHour: 9, mMinute: 0 }, dayOfWeek = 4
AlarmManager alarmManager = appContext.GetSystemService(Context.AlarmService) as AlarmManager;
alarmManager.SetRepeating(AlarmType.RtcWakeup, triggerTime.TimeInMillis, AlarmManager.IntervalDay * 7, pendingIntent);
}
Set alarm from Monday to Friday
Set alarm repeating every day and in on Receive check current day. If its sat or sun ignore it
Create a background service using AlarmManager + BroadcastReceivers
(Deprecated) How to make notification work even when app is killed?
Call local notification (AlarmManager) in a foreground service
Create a service
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[Service]
publicclass AlarmService : Service
{
IBinder binder;
publicoverride IBinder OnBind(Intent intent)
{
binder = newAlarmServiceBinder(this);
return binder;
}
publicoverride StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// this method would hold the code to be run when the service is started.
// Call local notification here
Send(message, title);
return StartCommandResult.NotSticky;
}
}
publicclass AlarmServiceBinder : Binder
{
readonly AlarmService service;
publicAlarmServiceBinder(AlarmService service)
{
this.service = service;
}
public AlarmService GetAlarmService()
{
return service;
}
}
[Service]
public class AlarmService : Service
{
IBinder binder;
public override IBinder OnBind(Intent intent)
{
binder = new AlarmServiceBinder(this);
return binder;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// this method would hold the code to be run when the service is started.
// Call local notification here
Send(message, title);
return StartCommandResult.NotSticky;
}
}
public class AlarmServiceBinder : Binder
{
readonly AlarmService service;
public AlarmServiceBinder(AlarmService service)
{
this.service = service;
}
public AlarmService GetAlarmService()
{
return service;
}
}
[Service]
public class AlarmService : Service
{
IBinder binder;
public override IBinder OnBind(Intent intent)
{
binder = new AlarmServiceBinder(this);
return binder;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// this method would hold the code to be run when the service is started.
// Call local notification here
Send(message, title);
return StartCommandResult.NotSticky;
}
}
public class AlarmServiceBinder : Binder
{
readonly AlarmService service;
public AlarmServiceBinder(AlarmService service)
{
this.service = service;
}
public AlarmService GetAlarmService()
{
return service;
}
}
Run service in StartForegroundService
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
publicvoidRunForegroundService()
{
var intent = newIntent(MainActivity.AppInstance, typeof(AlarmService));
using System;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Support.V4.App;
using static Android.OS.PowerManager;
namespace localnotification.Droid.Notification
{
[Service(Enabled = true)]
public class MyRequestService : Service
{
private Handler handler;
private Action runnable;
private bool isStarted;
private WakeLock wakeLock;
private long DELAY_BETWEEN_LOG_MESSAGES = 15000;
private int NOTIFICATION_SERVICE_ID = 999999;
private int NOTIFICATION_SERVICE_ALARM_ID = 9999990;
private string NOTIFICATION_CHANNEL_ID = "888888";
private string NOTIFICATION_CHANNEL_NAME = "channel_name_123";
public override void OnCreate()
{
base.OnCreate();
handler = new Handler();
// Here is what you want to do always, i just want to push a notification every 15 seconds here
runnable = new Action(() =>
{
DispatchNotificationThatAlarmIsGenerated("I'm running");
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
});
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
if (isStarted)
{
// service is already started
}
else
{
// Popup start service notification
CreateNotificationChannel();
DispatchNotificationThatServiceIsRunning();
// Pop up notification every 15s
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
isStarted = true;
// Keep app work when device sleeps
PowerManager powerManager = (PowerManager)this.GetSystemService(Context.PowerService);
WakeLock wakeLock = powerManager.NewWakeLock(WakeLockFlags.Full, "Client Lock");
wakeLock.Acquire();
}
return StartCommandResult.Sticky;
}
public override void OnTaskRemoved(Intent rootIntent)
{
//base.OnTaskRemoved(rootIntent);
}
public override IBinder OnBind(Intent intent)
{
// Return null because this is a pure started service. A hybrid service would return a binder that would
// allow access to the GetFormattedStamp() method.
return null;
}
public override void OnDestroy()
{
// Stop the handler.
handler.RemoveCallbacks(runnable);
// Remove the notification from the status bar.
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Cancel(NOTIFICATION_SERVICE_ID);
isStarted = false;
wakeLock.Release();
base.OnDestroy();
}
private void CreateNotificationChannel()
{
//Notification Channel
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Max);
notificationChannel.EnableLights(true);
notificationChannel.LightColor = Color.Red;
notificationChannel.EnableVibration(true);
notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
notificationManager.CreateNotificationChannel(notificationChannel);
}
private void DispatchNotificationThatServiceIsRunning()
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetDefaults((int)NotificationDefaults.All)
.SetSmallIcon(Resource.Drawable.abc_btn_check_material)
.SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
.SetSound(null)
.SetChannelId(NOTIFICATION_CHANNEL_ID)
.SetPriority(NotificationCompat.PriorityDefault)
.SetAutoCancel(false)
.SetContentTitle("Mobile")
.SetContentText("My service started")
.SetOngoing(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
//notificationManager.Notify(NOTIFICATION_SERVICE_ID, builder.Build());
StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
}
private void DispatchNotificationThatAlarmIsGenerated(string message)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.abc_btn_check_material)
.SetContentTitle("Alarm")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(NOTIFICATION_SERVICE_ALARM_ID, notificationBuilder.Build());
}
}
}
using System;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Support.V4.App;
using static Android.OS.PowerManager;
namespace localnotification.Droid.Notification
{
[Service(Enabled = true)]
public class MyRequestService : Service
{
private Handler handler;
private Action runnable;
private bool isStarted;
private WakeLock wakeLock;
private long DELAY_BETWEEN_LOG_MESSAGES = 15000;
private int NOTIFICATION_SERVICE_ID = 999999;
private int NOTIFICATION_SERVICE_ALARM_ID = 9999990;
private string NOTIFICATION_CHANNEL_ID = "888888";
private string NOTIFICATION_CHANNEL_NAME = "channel_name_123";
public override void OnCreate()
{
base.OnCreate();
handler = new Handler();
// Here is what you want to do always, i just want to push a notification every 15 seconds here
runnable = new Action(() =>
{
DispatchNotificationThatAlarmIsGenerated("I'm running");
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
});
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
if (isStarted)
{
// service is already started
}
else
{
// Popup start service notification
CreateNotificationChannel();
DispatchNotificationThatServiceIsRunning();
// Pop up notification every 15s
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
isStarted = true;
// Keep app work when device sleeps
PowerManager powerManager = (PowerManager)this.GetSystemService(Context.PowerService);
WakeLock wakeLock = powerManager.NewWakeLock(WakeLockFlags.Full, "Client Lock");
wakeLock.Acquire();
}
return StartCommandResult.Sticky;
}
public override void OnTaskRemoved(Intent rootIntent)
{
//base.OnTaskRemoved(rootIntent);
}
public override IBinder OnBind(Intent intent)
{
// Return null because this is a pure started service. A hybrid service would return a binder that would
// allow access to the GetFormattedStamp() method.
return null;
}
public override void OnDestroy()
{
// Stop the handler.
handler.RemoveCallbacks(runnable);
// Remove the notification from the status bar.
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Cancel(NOTIFICATION_SERVICE_ID);
isStarted = false;
wakeLock.Release();
base.OnDestroy();
}
private void CreateNotificationChannel()
{
//Notification Channel
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Max);
notificationChannel.EnableLights(true);
notificationChannel.LightColor = Color.Red;
notificationChannel.EnableVibration(true);
notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
notificationManager.CreateNotificationChannel(notificationChannel);
}
private void DispatchNotificationThatServiceIsRunning()
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetDefaults((int)NotificationDefaults.All)
.SetSmallIcon(Resource.Drawable.abc_btn_check_material)
.SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
.SetSound(null)
.SetChannelId(NOTIFICATION_CHANNEL_ID)
.SetPriority(NotificationCompat.PriorityDefault)
.SetAutoCancel(false)
.SetContentTitle("Mobile")
.SetContentText("My service started")
.SetOngoing(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
//notificationManager.Notify(NOTIFICATION_SERVICE_ID, builder.Build());
StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
}
private void DispatchNotificationThatAlarmIsGenerated(string message)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.abc_btn_check_material)
.SetContentTitle("Alarm")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(NOTIFICATION_SERVICE_ALARM_ID, notificationBuilder.Build());
}
}
}
Call service in MainActivity.cs
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
publicvoidStartMyRequestService()
{
var serviceToStart = newIntent(this, typeof(MyRequestService));
StartService(serviceToStart);
}
publicvoidStopMyRequestService()
{
var serviceToStart = newIntent(this, typeof(MyRequestService));
WorkManager is a library that makes it easy to schedule deferrable, asynchronous tasks even if the app exits or the device restarts.
It was designed to be backwards compatible to API 14 and does so by wrapping JobScheduler, AlarmManager, and BroadcastReceivers all in one.
Using JobScheduler your app will be running on a device that is API 23+. Anything below, you’ll be using a combination of AlarmManager + BroadcastReceivers.
But the minimum interval for PeriodicWork is 15 minutes (same as JobScheduler Periodic Job). If you need it every 30 seconds — consider using OneTimeWork and schedule it again when the work is done. But Approximately your location query every 30 seconds will responsible for about 10% battery drain.
Leave a Reply