I am working on a simple app that whole purpose is to create a notification on specific days. I am new to the Xamarin and Android stuff so it is possible that I completely messed something up but - the notifications doesn't arrive on scheduled time.
public class MainActivity : AppCompatActivity
{
private static readonly int NOTIFICATION_ID = 1000;
private static readonly string CHANNEL_ID = "location_notification";
private int _count = 0;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
DateTime curDate = DateTime.Now;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
CreateNotificationChannel();
ScheduleAlarm(9, 1, 18);
ScheduleAlarm(9, 1, 19);
ScheduleAlarm(9, 1, 20);
ScheduleAlarm(10, 1, 8);
ScheduleAlarm(10, 1, 9);
ScheduleAlarm(10, 1, 10);
var button = FindViewById<Button>(Resource.Id.button);
button.Click += Button_Click;
}
private void Button_Click(object sender, EventArgs e)
{ //test notification logic here}
private void ScheduleAlarm(int day, int month, int hour)
{
Intent alarmIntent = new Intent(this, typeof(AlarmReceiver));
alarmIntent.SetAction("com.team29.app.ALARM_ACTION");
PendingIntent pendingIntent;
if (Build.VERSION.SdkInt >= BuildVersionCodes.S)
{
pendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.Immutable);
}
else
{
pendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, 0);
}
AlarmManager alarmManager = (AlarmManager)GetSystemService(Context.AlarmService);
Calendar calendar = Calendar.Instance;
//calendar.Add(CalendarField.Minute, 3);
calendar.Set(CalendarField.DayOfMonth, day);
calendar.Set(CalendarField.Month, (month-1));
calendar.Set(CalendarField.HourOfDay, hour);
calendar.Set(CalendarField.Minute, 30);
calendar.Set(CalendarField.Second, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.SetContentTitle("Calendar check")
.SetContentText($"Day:{calendar.Get(CalendarField.DayOfMonth)}.{calendar.Get(CalendarField.Month)}. {calendar.Get(CalendarField.HourOfDay)}/{calendar.Get(CalendarField.Hour)}:{calendar.Get(CalendarField.Minute)}.")
.SetSmallIcon(Resource.Drawable.icon_transparent);
Notification notification = builder.Build();
NotificationManager notificationManager =
GetSystemService(Context.NotificationService) as NotificationManager;
const int notificationId = 11;
notificationManager.Notify(notificationId, notification);
alarmManager.SetRepeating(AlarmType.RtcWakeup, calendar.TimeInMillis, AlarmManager.IntervalDay, pendingIntent);
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
return;
}
var channelName = Resources.GetString(Resource.String.channel_name);
var channelDescription = GetString(Resource.String.channel_description);
var channel = new NotificationChannel(CHANNEL_ID, channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
and this is my .Resources.AlarmReceiver.cs:
[BroadcastReceiver(Enabled = true, Exported = false)]
[IntentFilter(new[] { "com.team29.app.ALARM_ACTION" })]
public class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Calendar notifCalendar = Calendar.Instance;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "location_notification")
.SetSmallIcon(Resource.Drawable.icon_transparent)
.SetContentTitle("Test notification")
.SetContentText($"Today is {notifCalendar.Get(CalendarField.DayOfMonth)}.{notifCalendar.Get(CalendarField.Month)}.")
.SetPriority(NotificationCompat.PriorityHigh);
Notification notification = builder.Build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.From(context);
const int notificationId = 118;
notificationManager.Notify(notificationId, notification);
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.team29.app" android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<application android:allowBackup="true" android:icon="@drawable/icon" android:label="AppName" android:supportsRtl="true" android:theme="@style/AppTheme">
<receiver android:name=".Resources.AlarmReceiver" android:exported="false">
<intent-filter>
<action android:name="com.team29.app.ALARM_ACTION" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>
As you can see, I added debug notification into the ScheduleAlarm
as well, just to check if there is some mismatch there. Also when I tried simply calendar.Add
and added the 3 minutes, it worked. It maybe took about a minute longer than 3, but the notification arrived. But when I switched from Add
to Set
, it won't. Now this was January 9th. On the second day, January 10th, a notification arrived at 10:33 and then another one at 12:35. I don't know if there was one in between at 11:30 because as they are set currently, they overwrite each other. I was working with emulator in the beginning, but then I switched to phone as I found that the scheduled notifications don't seem to work on the emulator. There is probably something I am missing or something I used wrongly. I tried browsing but found nothing that would help me yet. Can someone help me please? Thank you.