Search code examples
androidnotificationsalarmmanagerdate

AlarmManager - How to set a Notification to appear annually


I want an notification to appear each year depending on the date entered (Birthday). I have everything else working bar how to set a notification annually. As you can see below I have changed the code to say "HERE" where the intervals go. There are intervals for days and I know I could multiply that by 365. But what happens if its a leap year..

int REQUEST_CODE = 7;
Intent intent = new Intent(Activity2.this, Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Activity2.this, REQUEST_CODE, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(am.RTC_WAKEUP, System.currentTimeMillis(), HERE, pendingIntent);

Solution

  • You could replace 'HERE' with a method that determines if the following February from today is in a leap year, and then returns the value 365 or 366 days (in the form of milliseconds mind you) based on those checks.

    private long millisUntilNextYear(){
    
        //Set days in a year for Leap and Regular
        final int daysInLeapYear = 366;
        final int daysInYear = 365;
    
        //Get calendar instance
        GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
    
        //Get this year and next year
        int thisYear = cal.get(GregorianCalendar.YEAR);
        int nextYear = thisYear + 1;
    
        //Get today's month
        int thisMonth = cal.get(GregorianCalendar.MONTH);
    
        //Get today's date
        int dayOfMonth = cal.get(GregorianCalendar.DAY_OF_MONTH);
    
        //Is today before February? If so then the following February is in THIS year
        if (thisMonth < GregorianCalendar.FEBRUARY){
    
            //Check if THIS year is leapYear, and return correct days (converted to millis)
            return cal.isLeapYear(thisYear) ? daysToMillis(daysInLeapYear) : daysToMillis(daysInYear);
        }
    
        //Is today after February? If so then the following February is NEXT year
        else if (thisMonth > GregorianCalendar.FEBRUARY) {
            //Check if NEXT year is leapYear, and return correct days (converted to millis)
            return cal.isLeapYear(nextYear) ? daysToMillis(daysInLeapYear) : daysToMillis(daysInYear);
        }
    
        //Then today must be February.
        else {
            //Special case: today is February 29
            if (dayOfMonth == 29){
                return daysToMillis(daysInYear);
            } else {
                //Check if THIS year is leapYear, and return correct days (converted to millis)
                return cal.isLeapYear(thisYear) ? daysToMillis(daysInLeapYear) : daysToMillis(daysInYear);
            }
        }
    }