Search code examples
androidalarmmanager

Unable to start Alarm Service on Android


I am trying to set a repeating alarm

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {

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

}

In my fragment, I am calling this

Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
    calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());

    /* Repeating on every 20 minutes interval */
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            1000 * 60 * 20, pendingIntent);

where pendingIntent is set as

alarmManager = (AlarmManager)(getActivity().getSystemService(Context.ALARM_SERVICE));
Intent intent = new Intent("FIRE_ALARM");
pendingIntent=PendingIntent.getBroadcast(getActivity(), MONDAY, intent, 0);

Toast appears when I click set alarm button only when current time is less than timePicker time.

AndroidManifest.xml

<receiver android:name="AlarmReceiver">
        <intent-filter>
            <action android:name="FIRE_ALARM"/>
        </intent-filter>
    </receiver>

Solution

  • As of API level 19 setRepeating() will no longer get triggered at exact times. You can do something like this instead:

    public class AlarmReceiver extends BroadcastReceiver {
    
        public static synchronized void startAlarm() {
    
            AlarmManager alarmManager =
                (AlarmManager) ApplicationContext.getContext().getSystemService(Context.ALARM_SERVICE);
    
            Intent intent = new Intent("FIRE_ALARM");
            PendingIntent pendingIntent =
                PendingIntent.getBroadcast(ApplicationContext.getContext(), 1, intent, 0);
    
            // ...
    
            if (Build.VERSION.SDK_INT >= 19)
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, interval, pendingIntent);
            else
                alarmManager.set(AlarmManager.RTC_WAKEUP, interval, pendingIntent);
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("FIRE_ALARM")) {
                // do stuff
                startAlarm();
            }
        }
    }
    

    and then call AlarmReceiver.startAlarm() from your main activity.