studio notificationchannel notification notificaciones failed example create constantes android notifications alarmmanager

notificationchannel - Repetición de notificaciones en Android 4



notification channel android example (2)

Use AlarmManager.RTC_WAKEUP en lugar de AlarmManager.RTC

En AlarmManager.RTC

Hora de alarma en System.currentTimeMillis () (hora del reloj de pared en UTC). Esta alarma no activa el dispositivo; si se apaga mientras el dispositivo está dormido, no se enviará hasta la próxima vez que el dispositivo se despierte.

donde como en AlarmManager.RTC_WAKEUP

Hora de alarma en System.currentTimeMillis () (hora del reloj de pared en UTC), que activará el dispositivo cuando se apague.

Meta: la notificación aparece todos los días una vez, a las 2 p.m., si se cumple determinada condición.

Ejemplo: Para simplificar, consideremos que la condición, verificada con conexión a Internet, se cumple todos los días. Si hoy es después de las 2 p.m., comenzaremos las notificaciones a partir de mañana. Por ejemplo, el usuario inicia la aplicación a las 4 p.m. del lunes y recibe las notificaciones el martes a las 2 p.m., el miércoles a las 2 p.m., el jueves a las 2 p.m., etc.

Problema: a las 2 PM hay una primera notificación, pero luego recibo la misma notificación una y otra vez, en momentos aleatorios.

El problema parece ser solo en Android> = 4.0. Funciona bien en Androids anteriores.

Así es como envío la notificación:

public class NotifyService extends Service { static final int NOTIFICATION_ID = 1; // ... @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { try { Symbol biggest = getBiggestMover(); if (biggest != null) { String title = getString(R.string.app_name); String text = getNotificationText(biggest.symbol, biggest.change); sendNotification(title, text); } } catch (Exception e) { // If there is Internet problem we do nothing, don''t want to disturb the user. e.printStackTrace(); } return super.onStartCommand(intent, flags, startId); } /** @return Symbol which is the biggest mover today. If there is no big mover - null is returned. * @throws Exception If there is Internet problem. */ private Symbol getBiggestMover() throws Exception { Symbol biggest = null; Symbol[] equities = Network.getTraded(SymbolType.EQUITY); for (Symbol equity : equities) { if (Utilities.isToday(equity.lastTraded) && isBigMove(equity.change) && isBigger(equity, biggest)) { biggest = equity; } } return biggest; } private void sendNotification(String title, String text) { Notification notification = new Notification(R.drawable.ic_launcher, text, System.currentTimeMillis()); notification.flags = Notification.FLAG_AUTO_CANCEL; Intent clickIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, clickIntent, PendingIntent.FLAG_CANCEL_CURRENT); notification.setLatestEventInfo(this, title, text, pendingIntent); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(NOTIFICATION_ID, notification); } // ... }

sendNotification() se llama a las 2 p.m., debido al AlarmManager :

public class ServiceStarter extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { setNotificationAlarm(context); } /** Set repeating notifications every 24 hours. */ public static void setNotificationAlarm(Context context) { Intent intent = new Intent(context, NotifyService.class); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); final int oneDay = 24 * 60 * 60 * 1000; alarmManager.setRepeating(AlarmManager.RTC, getTriggerTime(), oneDay, pendingIntent); } private static long getTriggerTime() { GregorianCalendar calendar = new GregorianCalendar(); calendar.set(GregorianCalendar.HOUR_OF_DAY, 14); calendar.set(GregorianCalendar.MINUTE, 0); calendar.set(GregorianCalendar.SECOND, 0); calendar.set(GregorianCalendar.MILLISECOND, 0); if (calendar.before(new GregorianCalendar())) { calendar.add(GregorianCalendar.DAY_OF_MONTH, 1); } return calendar.getTimeInMillis(); } }

setNotificationAlarm() se llama desde 2 lugares. Primero, al inicio de la aplicación. Segundo, desde el código anterior, cuando el teléfono se reinicia ( onReceive() recibe BOOT_COMPLETED ). Lo hago porque cuando el usuario apaga el teléfono, AlarmManager borra sus alarmas.

Entonces, todo debería funcionar, porque alarmManager.setRepeating() anula la alarma anterior.

Descubrí que alguien tenía el mismo problema, pero tampoco respuesta:
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/t_tDU4PwR3g

También aquí encontré un problema similar: http://comments.gmane.org/gmane.comp.handhelds.android.devel/171471

Hace algún tiempo, pregunté cómo crear tales notificaciones, así que esto está relacionado:
Notificaciones diarias en un momento determinado


Tenía el mismo problema en el dispositivo ICS +. Mi solución fue muy simple-> Ponga la hora actual en las preferencias compartidas cuando se muestra la notificación. Antes de eso siempre verifica si realmente se pasa el intervalo, y si no solo aborta.

long lastnotification = sharedPrefs.getLong("lnnd", -1); Calendar now = Calendar.getInstance(); if (!namedayalarmEnabled) { return; } if (lastnotification > 1) { Calendar last = Calendar.getInstance(); last.setTimeInMillis(lastnotification); long distance = (now.getTimeInMillis() - last .getTimeInMillis()); if (distance < YOURINTERVAL) { return; } else { SharedPreferences.Editor editor = sharedPrefs.edit(); editor.putLong("lnnd", now.getTimeInMillis()); editor.commit(); } }