下面列出了怎么用android.app.job.JobInfo的API类实例代码及写法,或者点击链接到github查看源代码。
public static void scheduleAddWatchNextRequest(Context context, ClipData clipData) {
JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
PersistableBundle bundle = new PersistableBundle();
bundle.putString(ID_KEY, clipData.getClipId());
bundle.putString(CONTENT_ID_KEY, clipData.getContentId());
bundle.putLong(DURATION_KEY, clipData.getDuration());
bundle.putLong(PROGRESS_KEY, clipData.getProgress());
bundle.putString(TITLE_KEY, clipData.getTitle());
bundle.putString(DESCRIPTION_KEY, clipData.getDescription());
bundle.putString(CARD_IMAGE_URL_KEY, clipData.getCardImageUrl());
scheduler.schedule(new JobInfo.Builder(1,
new ComponentName(context, AddWatchNextService.class))
.setExtras(bundle)
.build());
}
private static void scheduleJob(Context context) {
JobScheduler scheduler =
(JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
JobInfo info = getJobInfo(
preferences.getBoolean("backgroundDownloadRequireUnmetered", true),
preferences.getBoolean("backgroundDownloadAllowRoaming", false),
preferences.getBoolean("backgroundDownloadRequireCharging", false));
LOGGER.info("Scheduling background download job: " + info);
int result = scheduler.schedule(info);
if (result == JobScheduler.RESULT_SUCCESS) {
LOGGER.info("Successfully scheduled background downloads");
} else {
LOGGER.log(Level.WARNING, "Unable to schedule background downloads");
}
}
private static JobInfo getJobInfo(boolean requireUnmetered, boolean allowRoaming,
boolean requireCharging) {
JobInfo.Builder builder = new JobInfo.Builder(
JobSchedulerId.BACKGROUND_DOWNLOAD.id(),
new ComponentName("com.totsp.crossword.shortyz",
BackgroundDownloadService.class.getName()));
builder.setPeriodic(TimeUnit.HOURS.toMillis(1))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresCharging(requireCharging)
.setPersisted(true);
if (!requireUnmetered) {
if (allowRoaming) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
} else {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING);
}
}
return builder.build();
}
public static void scheduleJob(Context context) {
JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
JobInfo pending = jobScheduler.getPendingJob(JOB_ID);
JobInfo jobInfo =
new JobInfo.Builder(JOB_ID, new ComponentName(context, BrightnessIdleJob.class))
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.setPeriodic(TimeUnit.HOURS.toMillis(24)).build();
if (pending != null && !pending.equals(jobInfo)) {
jobScheduler.cancel(JOB_ID);
pending = null;
}
if (pending == null) {
jobScheduler.schedule(jobInfo);
}
}
@Test
public void schedule_whenExtrasEvailable_transmitsExtras() {
String extras = "e1";
TransportContext transportContext =
TransportContext.builder()
.setBackendName("backend1")
.setExtras(extras.getBytes(Charset.defaultCharset()))
.build();
store.recordNextCallTime(transportContext, 1000000);
scheduler.schedule(transportContext, 1);
JobInfo jobInfo = jobScheduler.getAllPendingJobs().get(0);
PersistableBundle bundle = jobInfo.getExtras();
assertThat(bundle.get(JobInfoScheduler.EXTRAS))
.isEqualTo(
Base64.encodeToString(extras.getBytes(Charset.defaultCharset()), Base64.DEFAULT));
}
/**
* UI onclick listener to schedule a new job.
*/
public void scheduleJob(View v) {
JobInfo.Builder builder = new JobInfo.Builder(kJobId++,mServiceComponent);
String delay = mDelayEditText.getText().toString();
if (delay != null && !TextUtils.isEmpty(delay)) {
builder.setMinimumLatency(Long.valueOf(delay) * 1000);
}
String deadline = mDeadlineEditText.getText().toString();
if (deadline != null && !TextUtils.isEmpty(deadline)) {
builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
}
boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
boolean requiresAnyConnectivity = mAnyConnectivityRadioButton
.isChecked();
if (requiresUnmetered) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
} else if (requiresAnyConnectivity) {
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
JobScheduler jobScheduler =
(JobScheduler) getApplication().getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
}
public static void scheduleJob(Context context) {
QiscusLogger.print(TAG, "scheduleJob: ");
ComponentName componentName = new ComponentName(context, QiscusNetworkCheckerJobService.class);
JobInfo jobInfo = new JobInfo.Builder(STATIC_JOB_ID, componentName)
.setMinimumLatency(TimeUnit.SECONDS.toMillis(5))
.setOverrideDeadline(TimeUnit.SECONDS.toMillis(10))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.build();
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
if (jobScheduler != null) {
jobScheduler.schedule(jobInfo);
}
}
@Override
public int enqueue(JobInfo job, JobWorkItem work) throws RemoteException {
if (DEBUG) {
Slog.d(TAG, "Enqueueing job: " + job.toString() + " work: " + work);
}
final int uid = Binder.getCallingUid();
final int userId = UserHandle.getUserId(uid);
enforceValidJobRequest(uid, job);
if (job.isPersisted()) {
throw new IllegalArgumentException("Can't enqueue work for persisted jobs");
}
if (work == null) {
throw new NullPointerException("work is null");
}
validateJobFlags(job, uid);
long ident = Binder.clearCallingIdentity();
try {
return JobSchedulerService.this.scheduleAsPackage(job, work, uid, null, userId,
null);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Test
public void testScheduleWithDurationExtra() {
final Intent intent = new Intent(context, EventIntentService.class);
when(pendingIntentFactory.hasPendingIntent(intent)).thenReturn(false);
PendingIntent pendingIntent = getPendingIntent();
when(pendingIntentFactory.getPendingIntent(intent)).thenReturn(pendingIntent);
when(optlyStorage.getLong(EventIntentService.EXTRA_INTERVAL, AlarmManager.INTERVAL_HOUR)).thenReturn(AlarmManager.INTERVAL_HOUR);
long duration = AlarmManager.INTERVAL_DAY;
intent.putExtra(EventIntentService.EXTRA_INTERVAL, duration);
serviceScheduler.schedule(intent, duration);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ArgumentCaptor<JobInfo> jobInfoArgumentCaptor = ArgumentCaptor.forClass(JobInfo.class);
verify(jobScheduler).schedule(jobInfoArgumentCaptor.capture());
assertEquals(jobInfoArgumentCaptor.getValue().getIntervalMillis(), duration );
}
else {
verify(alarmManager).setInexactRepeating(AlarmManager.ELAPSED_REALTIME, duration, duration, pendingIntent);
}
verify(logger).info("Scheduled {}", intent.getComponent().toShortString());
pendingIntent.cancel();
}
/**
* Create a new JobStatus that was loaded from disk. We ignore the provided
* {@link android.app.job.JobInfo} time criteria because we can load a persisted periodic job
* from the {@link com.android.server.job.JobStore} and still want to respect its
* wallclock runtime rather than resetting it on every boot.
* We consider a freshly loaded job to no longer be in back-off, and the associated
* standby bucket is whatever the OS thinks it should be at this moment.
*/
public JobStatus(JobInfo job, int callingUid, String sourcePkgName, int sourceUserId,
int standbyBucket, long baseHeartbeat, String sourceTag,
long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
long lastSuccessfulRunTime, long lastFailedRunTime,
Pair<Long, Long> persistedExecutionTimesUTC,
int innerFlags) {
this(job, callingUid, resolveTargetSdkVersion(job), sourcePkgName, sourceUserId,
standbyBucket, baseHeartbeat,
sourceTag, 0,
earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
lastSuccessfulRunTime, lastFailedRunTime, innerFlags);
// Only during initial inflation do we record the UTC-timebase execution bounds
// read from the persistent store. If we ever have to recreate the JobStatus on
// the fly, it means we're rescheduling the job; and this means that the calculated
// elapsed timebase bounds intrinsically become correct.
this.mPersistedUtcTimes = persistedExecutionTimesUTC;
if (persistedExecutionTimesUTC != null) {
if (DEBUG) {
Slog.i(TAG, "+ restored job with RTC times because of bad boot clock");
}
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
static void scheduleJob(Context context, Bundle extras) {
ComponentName jobComponentName = new ComponentName(context.getPackageName(), GcmJobService.class.getName());
JobScheduler mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo existingInfo = mJobScheduler.getPendingJob(JOB_ID);
if (existingInfo != null) {
mJobScheduler.cancel(JOB_ID);
}
JobInfo.Builder jobBuilder = new JobInfo.Builder(JOB_ID, jobComponentName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).setTransientExtras(extras);
int result = mJobScheduler.schedule(jobBuilder.build());
if (result != JobScheduler.RESULT_SUCCESS) {
Log.e(LCAT, "Could not start job, error code: " + result);
}
}
/**
* @return Whether or not this job is ready to run, based on its requirements. This is true if
* the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
* TODO: This function is called a *lot*. We should probably just have it check an
* already-computed boolean, which we updated whenever we see one of the states it depends
* on here change.
*/
public boolean isReady() {
// Deadline constraint trumps other constraints (except for periodic jobs where deadline
// is an implementation detail. A periodic job should only run if its constraints are
// satisfied).
// AppNotIdle implicit constraint must be satisfied
// DeviceNotDozing implicit constraint must be satisfied
// NotRestrictedInBackground implicit constraint must be satisfied
final boolean deadlineSatisfied = (!job.isPeriodic() && hasDeadlineConstraint()
&& (satisfiedConstraints & CONSTRAINT_DEADLINE) != 0);
final boolean notDozing = (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0
|| (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
final boolean notRestrictedInBg =
(satisfiedConstraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0;
return (isConstraintsSatisfied() || deadlineSatisfied) && notDozing && notRestrictedInBg;
}
void detachLocked() {
final int N = mMyObservers.size();
for (int i=0; i<N; i++) {
final ObserverInstance obs = mMyObservers.get(i);
obs.mJobs.remove(this);
if (obs.mJobs.size() == 0) {
if (DEBUG) {
Slog.i(TAG, "Unregistering observer " + obs + " for " + obs.mUri.getUri());
}
mContext.getContentResolver().unregisterContentObserver(obs);
ArrayMap<JobInfo.TriggerContentUri, ObserverInstance> observerOfUser =
mObservers.get(obs.mUserId);
if (observerOfUser != null) {
observerOfUser.remove(obs.mUri);
}
}
}
}
/**
* Manually requests a job to run now.
*
* <p>To check the current status of the sync, register a {@link
* android.content.BroadcastReceiver} with an {@link android.content.IntentFilter} which checks
* for the action {@link #ACTION_SYNC_STATUS_CHANGED}.
*
* <p>The sync status is an extra parameter in the {@link Intent} with key {@link #SYNC_STATUS}.
* The sync status is either {@link #SYNC_STARTED} or {@link #SYNC_FINISHED}.
*
* <p>Check that the value of {@link #BUNDLE_KEY_INPUT_ID} matches your {@link
* android.media.tv.TvInputService}. If you're calling this from your setup activity, you can
* get the extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
*
* <p>
*
* @param context Application's context.
* @param inputId Component name for the app's TvInputService. This can be received through an
* Intent extra parameter {@link TvInputInfo#EXTRA_INPUT_ID}.
* @param syncDuration The duration of EPG content to fetch in milliseconds. For a manual sync,
* this should be relatively short. For a background sync this should be long.
* @param jobServiceComponent The {@link EpgSyncJobService} class that will run.
*/
public static void requestImmediateSync(
Context context, String inputId, long syncDuration, ComponentName jobServiceComponent) {
if (jobServiceComponent.getClass().isAssignableFrom(EpgSyncJobService.class)) {
throw new IllegalArgumentException("This class does not extend EpgSyncJobService");
}
PersistableBundle persistableBundle = new PersistableBundle();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
}
persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId);
persistableBundle.putLong(EpgSyncJobService.BUNDLE_KEY_SYNC_PERIOD, syncDuration);
JobInfo.Builder builder = new JobInfo.Builder(REQUEST_SYNC_JOB_ID, jobServiceComponent);
JobInfo jobInfo =
builder.setExtras(persistableBundle)
.setOverrideDeadline(EpgSyncJobService.OVERRIDE_DEADLINE_MILLIS)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
scheduleJob(context, jobInfo);
if (DEBUG) {
Log.d(TAG, "Single job scheduled");
}
}
@Override
public void plantOneOff(JobRequest request) {
long startMs = Common.getStartMs(request);
long endMs = Common.getEndMs(request, true);
JobInfo jobInfo = createBuilderOneOff(createBaseBuilder(request, true), startMs, endMs).build();
int scheduleResult = schedule(jobInfo);
if (scheduleResult == ERROR_BOOT_PERMISSION) {
jobInfo = createBuilderOneOff(createBaseBuilder(request, false), startMs, endMs).build();
scheduleResult = schedule(jobInfo);
}
mCat.d("Schedule one-off jobInfo %s, %s, start %s, end %s (from now), reschedule count %d", scheduleResultToString(scheduleResult),
request, JobUtil.timeToString(startMs), JobUtil.timeToString(Common.getEndMs(request, false)), Common.getRescheduleCount(request));
}
protected int convertNetworkType(@NonNull JobRequest.NetworkType networkType) {
switch (networkType) {
case ANY:
return JobInfo.NETWORK_TYPE_NONE;
case CONNECTED:
return JobInfo.NETWORK_TYPE_ANY;
case UNMETERED:
return JobInfo.NETWORK_TYPE_UNMETERED;
case NOT_ROAMING:
return JobInfo.NETWORK_TYPE_UNMETERED; // use unmetered here, is overwritten in v24
case METERED:
return JobInfo.NETWORK_TYPE_ANY; // use any here as fallback
default:
throw new IllegalStateException("not implemented");
}
}
@Test
public void testScheduleWithNoDurationExtra() {
final Intent intent = new Intent(context, EventIntentService.class);
when(pendingIntentFactory.hasPendingIntent(intent)).thenReturn(false);
PendingIntent pendingIntent = getPendingIntent();
when(pendingIntentFactory.getPendingIntent(intent)).thenReturn(pendingIntent);
when(optlyStorage.getLong(EventIntentService.EXTRA_INTERVAL, AlarmManager.INTERVAL_HOUR)).thenReturn(AlarmManager.INTERVAL_HOUR);
serviceScheduler.schedule(intent, AlarmManager.INTERVAL_HOUR);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ArgumentCaptor<JobInfo> jobInfoArgumentCaptor = ArgumentCaptor.forClass(JobInfo.class);
verify(jobScheduler).schedule(jobInfoArgumentCaptor.capture());
assertEquals(jobInfoArgumentCaptor.getValue().getIntervalMillis(), AlarmManager.INTERVAL_HOUR );
}
else {
verify(alarmManager).setInexactRepeating(AlarmManager.ELAPSED_REALTIME, AlarmManager.INTERVAL_HOUR, AlarmManager.INTERVAL_HOUR, pendingIntent);
}
verify(logger).info("Scheduled {}", intent.getComponent().toShortString());
pendingIntent.cancel();
}
private void resendTheIntentInSeveralSeconds(int seconds) {
appendLog(getBaseContext(), TAG, "resendTheIntentInSeveralSeconds:SDK:", Build.VERSION.SDK_INT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ComponentName serviceComponent = new ComponentName(this, UpdateWeatherResendJob.class);
JobInfo.Builder builder = new JobInfo.Builder(UpdateWeatherResendJob.JOB_ID, serviceComponent);
builder.setMinimumLatency(seconds * 1000); // wait at least
builder.setOverrideDeadline((3 + seconds) * 1000); // maximum delay
JobScheduler jobScheduler = getSystemService(JobScheduler.class);
jobScheduler.schedule(builder.build());
appendLog(getBaseContext(), TAG, "resendTheIntentInSeveralSeconds: sent");
} else {
AlarmManager alarmManager = (AlarmManager) getBaseContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(),
0,
new Intent(getBaseContext(), UpdateWeatherService.class),
PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + (1000 * seconds), pendingIntent);
}
}
/**
* Schedules the TimeZoneUpdateIdler job service to run once.
*
* @param context Context to use to get a job scheduler.
*/
public static void schedule(Context context, long minimumDelayMillis) {
// Request that the JobScheduler tell us when the device falls idle.
JobScheduler jobScheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
// The TimeZoneUpdateIdler will send an intent that will trigger the Receiver.
ComponentName idlerJobServiceName =
new ComponentName(context, TimeZoneUpdateIdler.class);
// We require the device is idle, but also that it is charging to be as non-invasive as
// we can.
JobInfo.Builder jobInfoBuilder =
new JobInfo.Builder(TIME_ZONE_UPDATE_IDLE_JOB_ID, idlerJobServiceName)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.setMinimumLatency(minimumDelayMillis);
Slog.d(TAG, "schedule() called: minimumDelayMillis=" + minimumDelayMillis);
jobScheduler.schedule(jobInfoBuilder.build());
}
public static JobInfo persistableBundleToJobInfo(PersistableBundle bundle) {
JobInfo.Builder builder = new JobInfo.Builder(bundle.getInt(B_KEY_ID),
new ComponentName(bundle.getString(B_KEY_COMPONENT_PKG), bundle.getString(B_KEY_COMPONENT_NAME)))
.setMinimumLatency(bundle.getInt(B_KEY_INTERVAL))
.setExtras(bundle);
if (bundle.containsKey(B_KEY_PERSISTENT_ACROSS_REBOOTS)) {
builder.setPersisted(true);
}
if (bundle.containsKey(B_KEY_REQUIRES_CHARGING)) {
builder.setRequiresCharging(true);
}
if (bundle.containsKey(B_KEY_BACKOFF_CRITERIA)) {
builder.setBackoffCriteria(
bundle.getPersistableBundle(B_KEY_BACKOFF_CRITERIA).getInt(B_INNER_BACKOFF_MILLIS),
bundle.getPersistableBundle(B_KEY_BACKOFF_CRITERIA).getInt(B_INNER_BACKOFF_POLICY)
);
}
if (bundle.containsKey(B_KEY_NETWORK_TYPE)) {
builder.setRequiredNetworkType(
bundle.getPersistableBundle(B_KEY_NETWORK_TYPE).getInt(B_INNER_REQUIRED_NETWORK)
);
}
return builder.build();
}
public static void schedule(Context context) {
if (isBackgroundDexoptDisabled()) {
return;
}
JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
// Schedule a one-off job which scans installed packages and updates
// out-of-date oat files.
js.schedule(new JobInfo.Builder(JOB_POST_BOOT_UPDATE, sDexoptServiceName)
.setMinimumLatency(TimeUnit.MINUTES.toMillis(1))
.setOverrideDeadline(TimeUnit.MINUTES.toMillis(1))
.build());
// Schedule a daily job which scans installed packages and compiles
// those with fresh profiling data.
js.schedule(new JobInfo.Builder(JOB_IDLE_OPTIMIZE, sDexoptServiceName)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.setPeriodic(IDLE_OPTIMIZATION_PERIOD)
.build());
if (DEBUG_DEXOPT) {
Log.i(TAG, "Jobs scheduled");
}
}
private void scheduleUpdate(int appWidgetId) {
String frequency = getConfig(appWidgetId, R.string.pref_widget_frequency);
long frequencyHourMillis = DateUtils.HOUR_IN_MILLIS * (TextUtils.isEmpty(frequency) ?
DEFAULT_FREQUENCY_HOUR : Integer.valueOf(frequency));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getJobScheduler().schedule(new JobInfo.Builder(appWidgetId,
new ComponentName(mContext.getPackageName(), WidgetRefreshJobService.class.getName()))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPeriodic(frequencyHourMillis)
.build());
} else {
mAlarmManager.setInexactRepeating(AlarmManager.RTC,
System.currentTimeMillis() + frequencyHourMillis,
frequencyHourMillis,
createRefreshPendingIntent(appWidgetId));
}
}
private void startLookingForMedia() {
new Thread(() -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP /* TODO && (has included folders) */) {
JobInfo job = new JobInfo.Builder(0, new ComponentName(getApplicationContext(), LookForMediaJob.class))
.setPeriodic(1000)
.setRequiresDeviceIdle(true)
.build();
JobScheduler scheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
if (scheduler.getAllPendingJobs().size() == 0)
Log.wtf(TAG, scheduler.schedule(job) == JobScheduler.RESULT_SUCCESS
? "LookForMediaJob scheduled successfully!" : "LookForMediaJob scheduled failed!");
}
}).start();
}
JobWorkEnqueuer(Context context, ComponentName cn, int jobId) {
super(context, cn);
ensureJobId(jobId);
JobInfo.Builder b = new JobInfo.Builder(jobId, mComponentName);
mJobInfo = b.setOverrideDeadline(0).build();
mJobScheduler = (JobScheduler) context.getApplicationContext().getSystemService(
Context.JOB_SCHEDULER_SERVICE);
}
@RequiresApi(26)
@Override
public void schedule(long delay, @NonNull List<Constraint> constraints) {
JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(getNextId(), new ComponentName(application, SystemService.class))
.setMinimumLatency(delay)
.setPersisted(true);
for (Constraint constraint : constraints) {
constraint.applyToJobInfo(jobInfoBuilder);
}
Log.i(TAG, "Scheduling a run in " + delay + " ms.");
JobScheduler jobScheduler = application.getSystemService(JobScheduler.class);
jobScheduler.schedule(jobInfoBuilder.build());
}
public static void scheduleJob(Context context) {
JobScheduler js =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(
VIDEO_JOB_ID,
new ComponentName(context, VideosContentJob.class));
builder.addTriggerContentUri(
new JobInfo.TriggerContentUri(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
js.schedule(builder.build());
}
public static void scheduleService(Context context) {
JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(context.getPackageName(), FloatJobService.class.getName()));
builder.setPersisted(true);
builder.setPeriodic(3 * 1000);
js.cancel(JOB_ID);
js.schedule(builder.build());
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void bindJobService() {
if (!preference.getBoolean(PREF_AUTO_CLEAN, false)) {
jobScheduler.cancel(0);
}
JobInfo job = new JobInfo.Builder(0, new ComponentName(context, AutoCleanService.class))
.setRequiresCharging(true)
.setRequiresDeviceIdle(true)
.setPeriodic(24 * 60 * 60 * 1000)
.setPersisted(true)
.build();
jobScheduler.cancel(0);
jobScheduler.schedule(job);
}
/**
* 演示JobScheduler的使用
*/
private void startJobScheduler() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
builder.setRequiresCharging(true)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
jobScheduler.schedule(builder.build());
}
}
@Override
public boolean schedule(Requirements requirements, String servicePackage, String serviceAction) {
JobInfo jobInfo =
buildJobInfo(jobId, jobServiceComponentName, requirements, serviceAction, servicePackage);
int result = jobScheduler.schedule(jobInfo);
logd("Scheduling job: " + jobId + " result: " + result);
return result == JobScheduler.RESULT_SUCCESS;
}