I'm struggling with complex local notifications on Android for a long time now.
I have a list of events. The user is able to choose when he/she would like to be notified:
He/she is also able to set the time when he/she wants to get notified. Every time is possible. He/she is also able to only get notified by different types of events.
What happens is, that it works fine with every device except the Samsung Galaxy Phones. Users told me that they are receiving a notification exactly one time (when they set them up) and then never again.
I tried almost everything, I'm running out of ideas. It looks like Samsung has some issues with notifications but it works for some other apps. So what's the difference between their code and mine.
Maybe someone else knows this issue and can help me out. This would be so amazing!
Here comes my code:
public int setEventNotifications(List<Event> chosenEvents) {
SharedPreferences settings = context.getSharedPreferences(Constants.PREFS_EVENT_SETTINGS, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
ArrayList<PendingIntent> intentArray = new ArrayList<>();
// To cancel an existing pending intent you need to recreate the exact same and cancel it -__-
// So pending intents need to be stored in the database
deleteOldGarbagePendingIntents();
// get notification settings from shared prefs
int hours = 0;
int minutes = 0;
String time = settings.getString(Constants.PREFS_EVENT_TIME, "00:00");
String parts[] = time.split(":");
try {
hours = Integer.parseInt(parts[0]);
minutes = Integer.parseInt(parts[1]);
} catch (Exception e) {
Log.e(TAG, "Invalid time. Cannot be parsed: " + time);
}
String interval = settings.getString(Constants.PREFS_EVENT_INTERVAL, "");
String communeId = settings.getString(Constants.PREFS_EVENT_COMMUNE_ID, "");
String regionId = settings.getString(Constants.PREFS_EVENT_REGION_ID, "");
for (Event event : chosenEvents) {
// check if date is in the future
Intent intent = new Intent(context, AlarmGarbageReceiver.class);
intent.putExtra("request_code", Integer.parseInt(event.getId()));
intent.putExtra("event_type", event.getGarbageType().getType());
intent.putExtra("event_date", event.getPickupDateAsDate().getTime());
// calculate trigger time
long triggerTime = calculateTriggerTime(event.getPickupDateAsDate(), hours, minutes, interval);
Calendar alarmCalendar = Calendar.getInstance();
alarmCalendar.setTimeInMillis(triggerTime);
try {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, Integer.parseInt(event.getId()), intent, FLAG_UPDATE_CURRENT);
if (alarmManager != null) {
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmCalendar.getTimeInMillis(), pendingIntent);
} else {
Log.e(TAG, "Alarmmanager is null");
}
intentArray.add(pendingIntent);
// save intents in database
dbHelper.insertEventData(event.getId(), event.getEventType().getType(), String.valueOf(event.getPickupDateAsDate().getTime()), event.getLocation(), event.getEventType().getColor(), communeId, regionId);
} catch (SecurityException securityException) {
Log.e(TAG, "Security Exception");
securityException.printStackTrace();
} catch (Exception exception) {
Log.e(TAG, "Exception");
exception.printStackTrace();
}
}
return intentArray.size();
}
AlarmEventReceiver class:
public class AlarmEventReceiver extends BroadcastReceiver {
private static final String NOTIFICATION_CHANNEL_NAME = "xxx_events";
private static final String NOTIFICATION_CHANNEL_ID = "xxx_events_1";
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getExtras() != null) {
Log.e(TAG, AlarmEventReceiver.class.getSimpleName() + " request code: " + intent.getExtras().getInt("request_code"));
}
int eventId = intent.getExtras().getInt("request_code");
String eventType = intent.getExtras().getString("event_type");
long pickupDate = intent.getExtras().getLong("event_date");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(pickupDate);
calendar.set(Calendar.HOUR, 6);
calendar.set(Calendar.MINUTE, 0);
long finalDate = calendar.getTimeInMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
Intent resultIntent = new Intent(context, EventCalendarActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(EventCalendarActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
if (notificationManager == null) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
if (notificationManager != null) {
notificationManager.createNotificationChannel(notificationChannel);
} else {
Log.e(TAG, "Notification Manager is NULL");
}
if (eventType != null) {
builder.setChannelId(NOTIFICATION_CHANNEL_ID)
.setDefaults(Notification.DEFAULT_ALL)
.setContentTitle("Erinnerung")
.setContentText(eventType)
.setWhen(finalDate)
.setContentIntent(resultPendingIntent)
.setAutoCancel(false)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
}
} else {
builder = new NotificationCompat.Builder(context);
builder.setContentTitle("Erinnerung")
.setDefaults(Notification.DEFAULT_ALL)
.setContentText(eventType)
.setWhen(finalDate)
.setContentIntent(resultPendingIntent)
.setAutoCancel(false)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
.setPriority(Notification.PRIORITY_DEFAULT);
}
Notification notification = builder.build();
if (notificationManager != null) {
notificationManager.notify(eventId, notification);
} else {
Log.e(TAG, "notificationManager is NULL");
}
}
}
I once had the chance to run it on a samsung phone and I think I remember there was some kind of SecurityException thrown because the phone was not able to update notifications. There was only a capacity of 500 notifications and if try to update them, old ones won't be deleted, but new ones created. You therefore reach 500 notifications quite fast and that's when the SecurityException is thrown. But I can't find the source for this anymore...
Check Notification Settings Step 1: Launch the Settings app and go to Notifications. Step 2: Tap on Included apps and ensure that switch next to All apps is enabled. Aside from the system settings, apps like Gmail and Instagram also allow you to set your notification preference within the app.
I browsed a related issue in the past, it happened on a Galaxy Note, although I'm not sure it will help.
mNotificationManager.cancel(notificationId);
mNotificationManager.notify(++notificationId, notification);
Each time a new notification has to be created, manually cancel the previous one and also update the notificationID each time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With