5

I have an Alarm which sends a notification at a specific time (if in that day there is a contact's birthday).

What I need is that when I set the alarm, it should repeat every year in the same day and at the same time. How could I do that?

Intent myIntent = new Intent(Main.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Main.this, 0, myIntent, 0);

AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
cal.set(2012,5,20,18,40);

alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*60*24*365*1000, pendingIntent);

and this is the AlarmService:

public class MyAlarmService extends Service {
  static final int uniqueID = 1394885;
  private PendingIntent pendingIntent;

  @Override
  public void onCreate() {
    // TODO Auto-generated method stub
    Toast.makeText(this, "MyAlarmService.onCreate()", Toast.LENGTH_LONG).show();

  }

  @Override
  public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "MyAlarmService.onBind()", Toast.LENGTH_LONG).show();
    return null;
  }

  @Override
  public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
  }

  @Override
  public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub

  }

  @Override
  public boolean onUnbind(Intent intent) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "MyAlarmService.onUnbind()", Toast.LENGTH_LONG).show();
    return super.onUnbind(intent);
  }
}

Could you help me, please?

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
stanga bogdan
  • 724
  • 2
  • 8
  • 26

2 Answers2

9
Intent intent = new Intent(this, MyReceiver.class);
intent.putExtra("key", "Alert");
pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);

alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar=Calendar.getInstance();

// Calendar.set(int year, int month, int day, int hourOfDay, int minute, int second)
calendar.set(2013, Calendar.OCTOBER, 13, 18, 55, 40);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5*1000, pendingIntent);

This param is interval in milliseconds between subsequent repeats of the alarm:

5*1000 = 5 second

Sample:

1year = 365(day)* 24(hour)* 60(min)* 60(second)* 1000(sec -> milisecond);
// leap year 366day

The month value is 0-based, so it may be clearer to use a constant like Calendar.OCTOBER

MyReceiver.java

public class MyReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
       Toast.makeText(context,intent.getStringExtra("key"),Toast.LENGTH_SHORT).show();
  }

}

update: Note: Beginning with API 19 (Build.VERSION_CODES.KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested. reference

i recommend use JobScheduler for android 21 or Firebase JobDispatcher for older devices instead of Alarm Manager

update: Google has released WorkManager as part of JetPack Schedule tasks with WorkManager

vuhung3990
  • 6,353
  • 1
  • 45
  • 44
  • what if we want it to repeat it every year and so at the same date andtime, what should we use in the interval field where 5*1000 is written? alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5*1000, pendingIntent); – mushahid Oct 23 '14 at 05:22
  • 1
    1year = 365(day)* 24(hour)* 60(min)* 60(second)* 1000(sec -> milisecond); // leap year 366day – vuhung3990 Oct 23 '14 at 05:37
  • Headsup: Value (5*1000 in this example) will be forced up to 60*1000 as per android 5.1 – Muhammad Riyaz Jul 10 '17 at 08:56
4

set alarm using alarmManager.set()

Intent myIntent = new Intent(Main.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Main.this, 0, myIntent, 0);

AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
cal.set(2012,5,20,18,40);

alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);  

and, when the alarm goes off, set the alarm for the next year from the MyAlarmService.

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
Eight
  • 4,194
  • 5
  • 30
  • 51
  • I tried that but i receive notification without stopping.I had to turn of my phone to stop them. Where should I add it , in the Start method ? – stanga bogdan Jun 20 '12 at 16:12
  • @stangabogdan which one you are using alarmManager.set or alarmManager.setRepeating? – Eight Jun 20 '12 at 16:14