Android - Problemas com o serviço que envia várias notificações locais
Eu herdei uma base de código para um aplicativo Android e estou enfrentando um problema específico nas notificações locais.
A ideia é enviar uma notificação para cada evento programado no futuro, considerando também a preferência do lembrete em quantos minutos antes do evento o usuário deseja ser notificado.
Tudo funciona muito bem, exceto que após a notificação ser lançada pela primeira vez, se o usuário abrir o aplicativo antes do início do evento, a notificação será lançada outra vez. Isso acontece sempre que o aplicativo é aberto entre (data de início do evento - lembrete) e data de início do evento.
Eu já dei uma olhadaesta e tambémesta sem sorte. Eu li que o uso de um serviço pode causar exatamente esse problema e alguns sugerem removê-lo, mas acho que isso é necessário, pois a notificação deve ser lançada também quando o aplicativo é fechado.
Atualmente, a estrutura do código é a seguinte:
Editar - descrição atualizada do TabBarActivity
Dentro de TabBarActivity eu tenho o métodoscheduleTravelNotification que agenda o AlarmManager. Este método é executado sempre que houver um novo evento a ser adicionado ao banco de dados local ou se um evento existente tiver sido atualizado. O TabBarActivity executa esse método dentro dos métodos onCreate e onResume. TabBarActivity também é o destino do evento de notificação - ao clicar.
private static void scheduleTravelNotification(Context context, RouteItem routeItem) {
long currentTime = System.currentTimeMillis();
int alarmTimeBefore = routeItem.getAlarmTimeBefore();
long alarmTime = routeItem.getStartTime() - (alarmTimeBefore * 1000 * 60);
if(alarmTimeBefore < 0){
return;
}
if(alarmTime < currentTime){
return;
}
Intent actionOnClickIntent = new Intent(context, TravelNotificationReceiver.class);
PendingIntent travelServiceIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis(), actionOnClickIntent, PendingIntent.FLAG_ONE_SHOT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(alarmTime);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), travelServiceIntent);
Log.e("NEXT ALARM", "Time: " + String.valueOf(calendar.getTimeInMillis()));
}
Isto éTravelNotificationReceiver.java (devo usar LocalBroadcastReceiver em vez de BroadcastReceiver?)
public class TravelNotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("RECEIVER", "received TravelNotification request");
Intent notificationIntent = new Intent(context, TravelNotificationService.class);
context.startService(notificationIntent);
}
}
TravelNotificationService.java estendeNotificationService.java definindo como tipo = "Viagem", sinalizadores = 0, título = "alguma coisa" e texto = "outra coisa".
public abstract class NotificationService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
sendNotification();
return super.onStartCommand(intent, flags, startId);
}
public abstract String setNotificationType();
public abstract int setNotificationFlags();
public abstract String setNotificationTitle();
public abstract String setNotificationText();
/**
* Executes all the logic to init the service, prepare and send the notification
*/
private void sendNotification() {
int flags = setNotificationFlags();
String type = setNotificationType();
NotificationHelper.logger(type, "Received request");
// Setup notification manager, intent and pending intent
NotificationManager manager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intentAction = new Intent(this.getApplicationContext(), TabBarActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, intentAction, flags);
// Prepares notification
String title = setNotificationTitle();
String text = setNotificationText();
Notification notification = NotificationHelper.buildNotification(getApplicationContext(), title, text, pendingIntent);
// Effectively send the notification
manager.notify(101, notification);
NotificationHelper.logger(type, "Notified");
}
}
Editar - Aqui está o código para NotificationHelper.buildNotification
public static Notification buildNotification(Context context, String title, String text, PendingIntent pendingIntent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);
builder.setContentText(text);
builder.setContentTitle(title);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.mipmap.launcher);
builder.setCategory(Notification.CATEGORY_MESSAGE);
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
return builder.build();
}
Obrigado pelas respostas!
Editar eu também viesta mas não tem respostas aceitas, enquantoesta post sugerir algo que eu acho que já foi gerenciado com if (alarmTime <currentTime) {return; } no scheduleTravelNotification.