Alarm Clock: repeat setAlarmClock()

Felix Hegg :

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.

Felix Hegg :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=131547&siteId=1