Search code examples
androidnotificationsbroadcastreceiveralarmmanagerandroid-pendingintent

I select random days for notification but notification is shown everyday


I am trying to set a notification using android studio in android level 26+ but if I select random days for notification but notification is shown everyday

How to set Calendar.DAYS_OF_WEEK .....like if today is Sunday and I am setting Calendar.DAYS_OF_WEEK,3(Tuesday) the alarm manager should the notification only on every Tuesday but it shows notification on Sunday also

 private void setNotification(AlarmList values) {
    Cursor data = mDatabaseHelper.getItemID(values.getMedicineName());
    int itemID = -1;
    while (data.moveToNext()) {
        itemID = data.getInt(0);
    }
    if (itemID > -1) {

        Intent intent = new Intent(getApplicationContext(), NotificationReceiver.class);
        intent.putExtra("name", values.getMedicineName());
        intent.putExtra("quantity", values.getQuantity());
        intent.putExtra("quality", values.getQuality());
        intent.putExtra("id", itemID);
        intent.putExtra("days", days);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), (itemID), intent, PendingIntent.FLAG_UPDATE_CURRENT);

        for (int i = 0; i < 7; i++) {
            if (days[i]) {
                Calendar calendar = Calendar.getInstance();

                calendar.set(Calendar.HOUR_OF_DAY, hour);
                calendar.set(Calendar.MINUTE, minute);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                calendar.set(Calendar.DAY_OF_WEEK, (i + 1));

                long alarm_time = calendar.getTimeInMillis();
                
                AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
                alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, alarm_time,
                        AlarmManager.INTERVAL_DAY*7, pendingIntent);
            }
        }
        finish();
        Intent activity = new Intent(AddMedicine.this, TabLayoutActivity.class);
        // i.putExtra("fragment id",1);
        startActivity(activity);
    }

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

public class NotificationReceiver extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {

       String name = intent.getStringExtra("name");
       String quantity = intent.getStringExtra("quantity");
       String quality = intent.getStringExtra("quality");
       int id = intent.getIntExtra("id", 0);
       boolean days[] = intent.getBooleanArrayExtra("days");

       String Heading = "Medicine Reminder";
       String text = "Reminder for " + name + " " + quantity + " " + quality;
     
               NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
               Intent repeatingIntent = new Intent(context, NotificationView.class);
               repeatingIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

               PendingIntent pendingIntent = PendingIntent.getActivity(context, id, repeatingIntent, PendingIntent.FLAG_UPDATE_CURRENT);

               NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "notify")
                       .setContentIntent(pendingIntent)
                       .setSmallIcon(R.drawable.clock)
                       .setContentTitle(Heading)
                       .setContentText(text)
                       .setAutoCancel(true)
                       .setPriority(NotificationCompat.PRIORITY_DEFAULT);
                       notificationManager.notify(id, builder.build());
                  }
               }

Solution

  • Setting the Calendar this way is unreliable. You should never call set() using DAY_OF_WEEK.

    If you want the alarm to trigger on the next Wednesday, you should figure out the date (month, day, year) of the next Wednesday and set that on the Calendar.

    See Setting DAY_OF_WEEK returns unexpected result

    See also https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4655637


    Example of how to create a Calendar instance for the current time for the following WEDNESDAY:

    Calendar calendar = Calendar.getInstance();
    int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
    // dayOfWeek is 1..7 (SUNDAY to SATURDAY)
    int daysToAdd = Calendar.WEDNESDAY - dayOfWeek;
    // Subtract current day of week from the day of week you want
    if (daysToAdd < 0) {
        // Current day of the week is after WEDNESDAY, so we go to next week
        daysToAdd += 7;
    }
    // If daysToAdd is zero, today is already WEDNESDAY!
    if (daysToAdd != 0) {
        calendar.add(Calendar.DATE, daysToAdd);
    }