I am making a reminder app on Xamarin Android using c#. Currently when a notification is pushed out, I won't receive the notification if the app is swiped out.
I have seen loads of questions like this, but none of them have helped me.
Here is my BroadCastReceiver:
using Android.App;
using Android.Content;
using Newtonsoft.Json;
using ReminderApp.HelperRepository;
using System;
using ReminderApp.Models;
using Android.Graphics;
using Android.Support.V4.Content;
using Android.Media;
namespace ReminderApp.Notifications
{
[BroadcastReceiver(Enabled = true)]
public class ReminderNotifications : BroadcastReceiver
{
Reminder reminder;
public ReminderNotifications()
{
}
public override void OnReceive(Context context, Intent intent)
{
string CHANNEL_ID = "dan51";
var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Max)
{
Description = "Firebase Cloud Messages appear in this channel"
};
long[] urgentVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100 };
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();
Android.Net.Uri infoAlarmUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
channel.EnableLights(true);
channel.LightColor = Color.Red;
channel.SetSound(infoAlarmUri, alarmAttributes);
channel.EnableVibration(true);
channel.SetVibrationPattern(urgentVibrationPattern);
channel.SetBypassDnd(true);
channel.LockscreenVisibility = NotificationVisibility.Public;
string date = intent.GetStringExtra("date");
string time = intent.GetStringExtra("time");
reminder = ReminderHelper.SelectReminderByDateAndTime(context, date, time);
if (reminder != null)
{
int NOTIFY_ID = 0 + new Random().Next();
Intent newIntent = new Intent(context, typeof(ReminderContent));
newIntent.PutExtra("reminder", JsonConvert.SerializeObject(reminder));
Android.Support.V4.App.TaskStackBuilder stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(context);
stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(ReminderContent)));
stackBuilder.AddNextIntent(newIntent);
PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);
Bitmap icon = BitmapFactory.DecodeResource(context.Resources, Resource.Drawable.new_noti_celeb);
Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID)
.SetAutoCancel(true)
.SetContentIntent(resultPendingIntent)
.SetContentTitle("Reminder!!")
.SetSmallIcon(Resource.Drawable.new_noti_celeb)
.SetLargeIcon(icon)
.SetColor(ContextCompat.GetColor(context, Resource.Color.material_deep_teal_500))
.SetContentText("Click for details..")
.SetVisibility(NotificationVisibility.Public)
.SetDeleteIntent(resultPendingIntent);
NotificationManager notificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
notificationManager.Notify(NOTIFY_ID, builder.Build());
}
if (reminder != null)
{
MediaPlayer player = MediaPlayer.Create(context, Resource.Drawable.notification_sound);
player.Start();
}
}
}
}
Here is my code to start timer till notification when a reminder is added:
public void ScheduleReminder(Reminder reminder)
{
AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
Intent myIntent;
PendingIntent pendingIntent;
myIntent = new Intent(this, typeof(ReminderNotifications));
myIntent.PutExtra("date", reminder.Date);
myIntent.PutExtra("time", reminder.Time);
var t = reminder.Time.Split(':');
var ampm = t[1].Split(' ')[1];
var hrr = Convert.ToDouble(t[0]);
var min = Convert.ToDouble(t[1].Split(' ')[0]);
string dateString = Convert.ToString(reminder.Date + " " + hrr + ":" + min + ":00 " + ampm);
DateTimeOffset dateOffsetValue = DateTimeOffset.Parse(dateString);
var millisec = dateOffsetValue.ToUnixTimeMilliseconds();
pendingIntent = PendingIntent.GetBroadcast(this, new Random().Next(), myIntent, 0);
manager.Set(AlarmType.RtcWakeup, millisec, pendingIntent);
}
Any help Appreciated!
Well this worked for me:
using Android.App;
using Android.Content;
using Newtonsoft.Json;
using ReminderApp.HelperRepository;
using System;
using ReminderApp.Models;
using Android.Graphics;
using Android.Support.V4.Content;
using Android.Media;
using Android.OS;
namespace ReminderApp.Notifications
{
[Service]
public class ReminderNotifications : Service
{
Reminder reminder;
public ReminderNotifications()
{
}
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
string CHANNEL_ID = "dan51";
var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Max)
{
Description = "Firebase Cloud Messages appear in this channel"
};
long[] urgentVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100 };
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();
Android.Net.Uri infoAlarmUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
channel.EnableLights(true);
channel.LightColor = Color.Red;
channel.SetSound(infoAlarmUri, alarmAttributes);
channel.EnableVibration(true);
channel.SetVibrationPattern(urgentVibrationPattern);
channel.SetBypassDnd(true);
channel.LockscreenVisibility = NotificationVisibility.Public;
string date = intent.GetStringExtra("date");
string time = intent.GetStringExtra("time");
reminder = ReminderHelper.SelectReminderByDateAndTime(this, date, time);
if (reminder != null)
{
int NOTIFY_ID = 0 + new Random().Next();
Intent newIntent = new Intent(this, typeof(ReminderContent));
newIntent.PutExtra("reminder", JsonConvert.SerializeObject(reminder));
Android.Support.V4.App.TaskStackBuilder stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(this);
stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(ReminderContent)));
stackBuilder.AddNextIntent(newIntent);
PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);
Bitmap icon = BitmapFactory.DecodeResource(this.Resources, Resource.Drawable.new_noti_celeb);
Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID)
.SetAutoCancel(true)
.SetContentIntent(resultPendingIntent)
.SetContentTitle("Reminder!!")
.SetSmallIcon(Resource.Drawable.new_noti_celeb)
.SetLargeIcon(icon)
.SetColor(ContextCompat.GetColor(this, Resource.Color.material_deep_teal_500))
.SetContentText("Click for details..")
.SetVisibility(NotificationVisibility.Public)
.SetDeleteIntent(resultPendingIntent);
NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
notificationManager.Notify(NOTIFY_ID, builder.Build());
PowerManager pm = (PowerManager)this.GetSystemService(Context.PowerService);
bool isScreenOn = pm.IsInteractive;
if (!isScreenOn)
{
PowerManager.WakeLock wl = pm.NewWakeLock(WakeLockFlags.ScreenDim | WakeLockFlags.AcquireCausesWakeup, "myApp:notificationLock");
wl.Acquire(1);
}
MediaPlayer player = MediaPlayer.Create(this, Resource.Drawable.notification_sound);
player.Start();
}
return StartCommandResult.NotSticky;
}
}
}
and in my ScheduleReminder function, I changed GetBroadcast
to GetService
!
Only problem with this is that it gives like a 30 second delay before pushing the notification. If anybody has a better solution, please post it!