I'm the developer of Call Manager, and I'm trying to implement a notification reminder feature to my app. The idea is that the user can set themselves a reminder to call a specific person in the list. At first, when implementing this feature, the notification would show up immediately without being scheduled - this was due to an incorrect setting of values that resulted in negative milliseconds. However, now that I have corrected that, notifications do not get scheduled at all, even though I have the correct millisecond value to give the AlarmManager.
The method that schedules the notification is below:
public void scheduleReminder(Notification notification, String date, String time){
String[] dateArray = date.split("/");
String[] timeArray = time.split(":|\\s+");
Date currentDate = new Date();
int notHour;
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
if(timeArray[2].equals("PM")){
notHour = Integer.parseInt(timeArray[0]);
notHour = notHour + 12;
cal.set(Calendar.YEAR, Integer.parseInt(dateArray[2]));
cal.set(Calendar.MONTH, Integer.parseInt(dateArray[0]) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateArray[1]));
cal.set(Calendar.HOUR_OF_DAY, notHour);
cal.set(Calendar.MINUTE, Integer.parseInt(timeArray[1]));
}
else{
cal.set(Calendar.YEAR, Integer.parseInt(dateArray[2]));
cal.set(Calendar.MONTH, Integer.parseInt(dateArray[0]) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateArray[1]));
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArray[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(timeArray[1]));
}
Date reminderDate = cal.getTime();
long diffInMillis = reminderDate.getTime() - currentDate.getTime();
Intent notificationIntent = new Intent(this, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + diffInMillis, pendingIntent);
}
My Broadcast receiver class is as follows:
package groovinchip.com.callmanager;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
And the relevant Android Manifest declarations are as follows:
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name="groovinchip.com.callmanager.NotificationPublisher"
android:enabled="true">
</receiver>
I'm stumped as to why this isn't working - I've pored over my Google results trying to figure it out. I've switched between:
1) Setting AlarmManager
with System.ELAPSED_REALTIME_WAKEUP
2) Passing SystemClock.elapsedRealTime() + diffInMillies
3) Only passing diffInMillis
4) passing an Integer value representing only a few seconds instead of diffInMillis
to see if it would work at all
Anyone able to help with this? Thank you so much!
When you create your Notification are you setting a channel id? If you are testing on API 26 the alarm will not go off if there isn't one set, as well as a a channel in the broadcast receiver.
I have two methods that create and set the reminder from a timepicker and an alarm that the user chooses. Here is the source code for them
private void createReminder(Notification notification) {
Intent notificationIntent = new Intent(this, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
long delay = alarmCalendar.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
long futureInMillis = SystemClock.elapsedRealtime() + delay;
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}
private Notification getNotification() {
String channelId = "Reminders";
PendingIntent newEntryActivityPendingIntent = PendingIntent.getActivity(this, 1, new Intent(this, NewEntryActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.reminder_content))
.setTicker(getString(R.string.app_name))
.setSmallIcon(R.drawable.notebook_notification_white)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setContentIntent(newEntryActivityPendingIntent);
Log.i(TAG, "notification built");
return builder.build();
}
In my app I have a notification reminder and I have a seperate class for my broadcast reciever similar to you and this how mine looks
public class NotificationPublisher extends BroadcastReceiver {
private static final String TAG = "NotificationPublisher";
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel("Reminders", "Reminders", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
Log.i(TAG, "notification sent");
notificationManager.notify(id, notification);
}
}
Almost exactly like yours, from the looks of it.
And this works well for me. Let me know if I can help any other way.