Multiple repeated notifications with alarm manager [android]

1.2k Views Asked by At

i'm trying to do a pills reminder. When i create multiple reminders my app show all the notifications but only at the last time set. It also execute more times OnReceive() method and i don't understand why. I found many questions with the same argument and i changed my code with those answers but nothing resolved my problems. Thank you!

Device: Asus ZenPad S 8.0; Android: 6.0.1;

This is my code:

@Override
public void onClick(View view) {
    switch (view.getId()) {

        case R.id.button:
            mcurrentTime = Calendar.getInstance();
            int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
            int minute = mcurrentTime.get(Calendar.MINUTE);
            TimePickerDialog mTimePicker;
            mTimePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
                @Override
                public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                    mcurrentTime.set(Calendar.HOUR_OF_DAY, selectedHour);
                    mcurrentTime.set(Calendar.MINUTE, selectedMinute);
                    setAlarm();

                }
            }, hour, minute, true);//Yes 24 hour time
            mTimePicker.setTitle(R.string.orario);
            mTimePicker.show();
            notificationAlarm = new NotificationAlarm(editText.getText().toString());
            getApplicationContext().registerReceiver(notificationAlarm, intentFilter); 
            break;
}}


 private void setAlarm(){
    int id = (int) System.currentTimeMillis();
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this,id, intent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mcurrentTime.getTimeInMillis(),1000*60*5, pendingIntent);
    Log.d("Time", String.valueOf(mcurrentTime.getTimeInMillis()));

}



@Override
public void onResume(){
    super.onResume();
    final String SOME_ACTION = "com.example.mypackage.a2_pillsrem_WAKE";
    intent = new Intent(SOME_ACTION);
    intentFilter = new IntentFilter(SOME_ACTION);
}

And this is the BroadcastReceiver Class:

public class NotificationAlarm extends BroadcastReceiver {
String s;
int mNotificationId;
Random r = new Random();
ArrayList<Integer> notify = new ArrayList<>();
public NotificationAlarm(String s){
    this.s=s;
}

public void onReceive(Context context, Intent intent) {
    //RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification);

    Notification.Builder mBuilder =
            new Notification.Builder(context)
                    .setSmallIcon(R.drawable.pill)
                    .setContentTitle(context.getString(R.string.titolo_notifica))
                    .setContentText(context.getString(R.string.descr_notifica)+" "+s)
                   // .setContent(remoteViews)
                    .setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_SOUND)
                    .setVisibility(1);//1 è uguale a VISIBILITY_PUBLIC
                                        // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.html#VISIBILITY_PUBLIC

    //Random r = new Random();
    mNotificationId = r.nextInt(10000); //assegno un id casuale ad ogni notifica affinchè non siano sovrascritte
    Intent notificationIntent = new Intent(context,MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context,0,notificationIntent,0);
    mBuilder.setContentIntent(pendingIntent);
    Log.d("IDNOT",Integer.toString(mNotificationId));
    //Gets an instance of the NotificationManager service
    NotificationManager mNotifyMgr =
            (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
   // Builds the notification and issues it.
    mNotifyMgr.notify(mNotificationId, mBuilder.build());
}
}
2

There are 2 best solutions below

1
On

Have you tried setting up alarm with PendingIntent.FLAG_UPDATE_CURRENT like the below? try it out.

private void setAlarm () {
        int id = (int) System.currentTimeMillis();
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mcurrentTime.getTimeInMillis(), 1000 * 60 * 5, pendingIntent);
        Log.d("Time", String.valueOf(mcurrentTime.getTimeInMillis()));
    }

Hope this works for you!!

0
On

After many attempts i've decided to not use BroadcastReceiver but IntentServices. This is the right code and solution:

 @Override
public void onClick(View view) {
    switch (view.getId()) {

        case R.id.button:
            mcurrentTime = Calendar.getInstance();
            int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
            int minute = mcurrentTime.get(Calendar.MINUTE);
            TimePickerDialog mTimePicker;
            mTimePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
                @Override
                public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                    mcurrentTime.set(Calendar.HOUR_OF_DAY, selectedHour);
                    mcurrentTime.set(Calendar.MINUTE, selectedMinute);
                    setAlarm();

                }
            }, hour, minute, true);//Yes 24 hour time
            mTimePicker.setTitle(R.string.orario);
            mTimePicker.show();
            break;

private void setAlarm(){
    int id = (int) System.currentTimeMillis();
    Intent intent = new Intent(this, NotificationAlarm.class);
    intent.putExtra("Farmaco",editText.getText().toString());
    PendingIntent pendingIntent = PendingIntent.getService(this,id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mcurrentTime.getTimeInMillis(),5*60*1000, pendingIntent);
    }
    Log.d("Time", String.valueOf(mcurrentTime.getTimeInMillis()));
}

And this is the notification class:

public class NotificationAlarm extends IntentService {
String s;
int mNotificationId;
Random r = new Random();
public NotificationAlarm(){
    super("HelloNotificationService");

}

@Override
protected void onHandleIntent(Intent intent) {

    Notification.Builder mBuilder =
            new Notification.Builder(getApplicationContext())
                    .setSmallIcon(R.drawable.pill)
                    .setContentTitle(getApplicationContext().getString(R.string.titolo_notifica))
                    .setContentText(getApplicationContext().getString(R.string.descr_notifica)+" "+s)
                    // .setContent(remoteViews)
                    .setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_SOUND)
                    .setVisibility(1);//1 è uguale a VISIBILITY_PUBLIC
    // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.html#VISIBILITY_PUBLIC

    mNotificationId = r.nextInt(10000); //assegno un id casuale ad ogni notifica affinchè non siano sovrascritte
    Intent notificationIntent = new Intent(getApplicationContext(),MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),(int)System.currentTimeMillis(),notificationIntent,PendingIntent.FLAG_ONE_SHOT);
    mBuilder.setContentIntent(pendingIntent);
    Log.d("IDNOT",Integer.toString(mNotificationId));

// Gets an instance of the NotificationManager service
    NotificationManager mNotifyMgr =
            (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);

// Builds the notification and issues it.
    mNotifyMgr.notify(mNotificationId, mBuilder.build());
    stopSelf();
}

public int onStartCommand(Intent intent, int flags, int startId){
    super.onStartCommand(intent, flags, startId);
    s = intent.getStringExtra("Farmaco");
    return START_STICKY;
}
}