I'm trying to build an alarm clock, where the user can pick the time and the weekdays where the alarm has to fire. To do so, I used setAlarmClock()
, because the alarm has to fire even if the device goes into doze mode. The problem is, that setAlarmClock()
is only a one time alarm and can't be repeated on a weekly basis. The only solution I could think of is to make an setRepeatingAlarm()
, which schedules the setAlarmClock()
every day.
Please tell me if this is a smart work around or if there is a better way.
Also I'm not sure if I have to schedule the daily setAlarmClock()
from a broadcast receiver or from an additional service.
Please tell me if you need further information or pieces of the code.
After many late hours I found the official solution. You have to handle all the alarms after each reboot. I have done this the following way:
Get permission in manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Then create a receiver with the following Intent filter:
<receiver android:name=".FragmentAlarm.RestartAlarmsReceiver" android:enabled="true"
android:exported="false">
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<!--For HTC devices-->
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>`
Next you need to create this receiver. Mine looks like this:
public class RestartAlarmsReceiver extends BroadcastReceiver {
private String TAG = "halo";
@Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Log.e("starting", "starting JobScheduler");
schedule(context);
} else {
Log.e(TAG, "Received unexpected intent " + intent.toString());
}
}
private void schedule(Context context) {
// say when Job has to be executed
ComponentName componentName = new ComponentName(context, JobServiceC.class);
JobInfo info = new JobInfo.Builder(145, componentName)
.setOverrideDeadline(0)
.setPersisted(true) // keeps job alive after reboot -> need permission
.build();
JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
int resultCode = scheduler.schedule(info);
if (resultCode == JobScheduler.RESULT_SUCCESS) {
Log.e("TAG", "Job scheduled");
} else {
Log.e("TAG", "Job not scheduled");
}
}
private void cancel(Context context) {
JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.cancel(145);
Log.e("TAG", "JobCancelled");
}
Here you must adjust the "Component Name", where you have to start your Java-class, which sets all the alarms again for this day.