How to plan a task using something other than Alarms, and it should be easy to test, and also run even after the device is restarted?

I need to run a receiver that action USER_PRESENTonly receives for a specific duration on certain days of the week. Here, the duration and days of the week are selected by the user.

What I tried uses Preferencesc AlarmManagerto achieve this, and I would really like to use something else besides Alarmsc Preferencesto achieve this, since it is too difficult to test alarms with weekly alarms that start after a user-selected duration and for selected user days of the week.

Is there any other way to do this work than using Alarmsand Preferences. Sample code is very useful!



See my approach using Alarmswith Preferences:

Now, at first I calculate the starting time, allowing the user to select the hour and minutes by DialogFragmentwhich TimePickerDialogswells, so the user can select the start and I get hrsand minto call back onTimeSet(), and then I know the start time of reception of the receiver.

The code snippet looks something like this to calculate the start time in milliseconds from hrsand min:

    Calendar calSet = Calendar.getInstance();
    //setting alarm from current day so that it starts from today onwards
    int day = calSet.get(Calendar.DAY_OF_WEEK);
    calSet.set(Calendar.DAY_OF_WEEK, day);
    calSet.set(Calendar.HOUR_OF_DAY, hrs);
    calSet.set(Calendar.MINUTE, min);
    calSet.set(Calendar.SECOND, 0);
    calSet.set(Calendar.MILLISECOND, 0);
    Long milliseconds = calSet.getTimeInMillis();
    //check if the time is already passed
    Long daily = 24L * 60L * 60L * 1000L;
    if (milliseconds < System.currentTimeMillis()) {
        //if already passed then push it for next day by adding just 24 hrs
        milliseconds = milliseconds + daily;
    }

And then I save this calculated millisecond time in preference, say:SharedPreferences.Editor.putLong("PeriodicLockStartTimeInMillis", milliseconds);

Now I save the days that the user selected using checkBoxesand the settings Preferencesfor each day.

SharedPreferences.Editor.putBoolean("DAYNAME", true);

, , :

SharedPreferences.Editor.putLong("LockDurationInMillis", minutesinmillis);

AlarmManager , BroadcastReceiver, PeriodicLockService, PendingIntent, .

:

Intent reminderIntent = new Intent(getActivity(), PeriodicLockService.class);
reminderIntent.setAction("ACTION_REPEATING_ALARM_RECEIVER");
pendingIntent = PendingIntent.getBroadcast(getActivity(), PeriodicLockService.REPEATING_ALARM_UNIQUE_ID, reminderIntent, PendingIntent.FLAG_UPDATE_CURRENT);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      alarmManager.setExact(AlarmManager.RTC_WAKEUP, milliseconds, pendingIntent);
} else {
      alarmManager.set(AlarmManager.RTC_WAKEUP, milliseconds, pendingIntent);
}

PeriodicLockService, onReceive , , , , preference :

//Fetching today day from Calendar to compare if user has set lock for today
    Calendar calendar = Calendar.getInstance();
    int day = calendar.get(Calendar.DAY_OF_WEEK);

    switch (day) {
        case Calendar.SUNDAY:
            if (Preferences.getBooleanPreference(context, SUN_DAY)) {
                startLockNow(context);
            }
            break;
        case Calendar.MONDAY:
            if (Preferences.getBooleanPreference(context, MON_DAY)) {
                startLockNow(context);
            }
            break;
        case Calendar.TUESDAY:
            if (Preferences.getBooleanPreference(context, TUES_DAY)) {
                startLockNow(context);
            }
            break;
        case Calendar.WEDNESDAY:
            if (Preferences.getBooleanPreference(context, WED_DAY)) {
                startLockNow(context);
            }
            break;
        case Calendar.THURSDAY:
            if (Preferences.getBooleanPreference(context, THURS_DAY)) {
                startLockNow(context);
            }
            break;
        case Calendar.FRIDAY:
            if (Preferences.getBooleanPreference(context, FRI_DAY)) {
                startLockNow(context);
            }
            break;
        case Calendar.SATURDAY:
            if (Preferences.getBooleanPreference(context, SAT_DAY)) {
                startLockNow(context);
            }
            break;
    }

private void startLockNow(Context context) {
    Long lockStartTimeInMillis = Preferences.getLongPreference(context, "PeriodicLockStartTimeInMillis");

    //Update Unlock Time
    Long LockDurationInMillis = Preferences.getLongPreference(context, "LockDurationInMillis"); //End time to stop the Receiver for action USER_PRESENT
    Long newEndTime = lockStartTimeInMillis + LockDurationInMillis;

    //Set Unlocked notification broadcast which also disables the receiver for action `USER_PRESENT`
    Intent intent = new Intent(context, FinalUnlockedBroadcast.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, newEndTime + 1000, pendingIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, newEndTime + 1000, pendingIntent);
    }

    //update the time for next lock by adding a day
    milliseconds = Preferences.getLongPreference(context, "PeriodicLockStartTimeInMillis") + 24L * 60L * 60L * 1000L;
    Intent reminderIntent = new Intent(context, PeriodicLockService.class);
    reminderIntent.setAction("ACTION_REPEATING_ALARM_RECEIVER");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REPEATING_ALARM_UNIQUE_ID, reminderIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, milliseconds , pendingIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, milliseconds , pendingIntent);
    }
}

, , , .

, , Alarms Preferences

+4
3

Android-Job Android-Job repo

  • Android-Job , .
  • , API .
  • JobScheduler, GCMNetworkManager AlarmManager.
  • Android Nougat .
  • .

Android-Job .

API /.

  • : onRunJob. . , , .
  • JobRequest: , JobRequest, Job.
  • JobCreator: JobCreator factory . JobCreator JobCreator create.
  • JobManager: JobManager . singleton. JobManager . JobCreator JobManager.

plz, alook Android-Job

,

+1

Firebase. Android. API, JobScheduler, Android (API 9+), Google Play.

, , .

0

public class MyJobService extends JobService {

    @Override
    public boolean onStartJob(JobParameters params) {
        Toast.makeText(this, "testing", Toast.LENGTH_LONG).show();
        Log.i("sid", "Job scheduler called");
        jobFinished(params, true);
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }
}

private void constructJob(){
        JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(this, MyJobService.class));

        builder.setMinimumLatency(60000)
                .setBackoffCriteria(10000,JobInfo.BACKOFF_POLICY_LINEAR)
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
                .setPersisted(true);

        mJobScheduler.schedule(builder.build());
    }

, builder.setPersisted(true), . , Android N (API 24) API, API 21-23 builder.setPeriodic(60000) builder.setMinimumLatency(60000)

UPDATE API 15 , JobSchedulerCompat.

Add below dependencies to your gradle file -

compile 'me.tatarka.support:jobscheduler:0.1.1'
0
source

Source: https://habr.com/ru/post/1684218/


All Articles