@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Create JobScheduler JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); //Create a component passing the JobService that we want to use ComponentName jobService = new ComponentName(getPackageName(), MyJobService.class.getName()); //Create a JobInfo passing a unique JOB_ID and the jobService //also set the periodic time to repeat this job JobInfo jobInfo = new JobInfo.Builder(JOB_ID, jobService) .setPeriodic(REFRESH_INTERVAL) .build(); jobScheduler.schedule(jobInfo); }
@Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { final String remindersKey = getString(R.string.pref_key_reminders); if (key.equals(remindersKey)) { boolean enabled = sharedPreferences.getBoolean(remindersKey, false); JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); if (!enabled) { jobScheduler.cancel(JOB_ID); Log.d(TAG, "cancelling scheduled job"); } else { long interval = AlarmManager.INTERVAL_HOUR; JobInfo job = new JobInfo.Builder(JOB_ID, new ComponentName(getPackageName(), ScheduledJobService.class.getName())) .setPersisted(true) .setPeriodic(interval) .build(); jobScheduler.schedule(job); Log.d(TAG, "setting scheduled job for: " + interval); } } }
@Test(timeout = 5000) public void testProcessOnePacket() throws Exception { DataPacket dataPacket = new ByteArrayDataPacket(Collections.singletonMap("id", "testId"), "testPayload".getBytes(Charsets.UTF_8)); queuedSiteToSiteClientConfig.createQueuedClient(context).enqueue(dataPacket); mockNiFiS2SServer.enqueueSiteToSitePeers(Collections.singletonList(peer)); String transactionPath = mockNiFiS2SServer.enqueuCreateTransaction(portIdentifier, transactionIdentifier, 30); mockNiFiS2SServer.enqueuDataPackets(transactionPath, Collections.singletonList(dataPacket), queuedSiteToSiteClientConfig); mockNiFiS2SServer.enqueueTransactionComplete(transactionPath, 2, ResponseCode.CONFIRM_TRANSACTION, ResponseCode.CONFIRM_TRANSACTION); JobInfo.Builder processJobInfoBuilder = SiteToSiteJobService.createProcessJobInfoBuilder(context, 1, queuedSiteToSiteClientConfig, parcelableQueuedOperationResultCallback); processJobInfoBuilder.setOverrideDeadline(0); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); assertEquals(JobScheduler.RESULT_SUCCESS, jobScheduler.schedule(processJobInfoBuilder.build())); assertEquals(1, parcelableQueuedOperationResultCallback.getInvocations().size()); SiteToSiteDBTestUtil.assertNoQueuedPackets(siteToSiteDB); mockNiFiS2SServer.verifyAssertions(); }
public static void requestSync(Context context, String inputId, boolean currentProgramOnly) { PersistableBundle pBundle = new PersistableBundle(); pBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); pBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); pBundle.putString(SyncJobService.BUNDLE_KEY_INPUT_ID, inputId); pBundle.putBoolean(SyncJobService.BUNDLE_KEY_CURRENT_PROGRAM_ONLY, currentProgramOnly); JobInfo.Builder builder = new JobInfo.Builder(REQUEST_SYNC_JOB_ID, new ComponentName(context, SyncJobService.class)); JobInfo jobInfo = builder .setExtras(pBundle) .setOverrideDeadline(SyncJobService.OVERRIDE_DEADLINE_MILLIS) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); scheduleJob(context, jobInfo); Intent intent = new Intent(SyncJobService.ACTION_SYNC_STATUS_CHANGED); intent.putExtra(SyncJobService.BUNDLE_KEY_INPUT_ID, inputId); intent.putExtra(SyncJobService.SYNC_STATUS, SyncJobService.SYNC_STARTED); LocalBroadcastManager.getInstance(context).sendBroadcast(intent); }
@Override public void onReceive(Context context, Intent intent) { JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); // If there are not pending jobs. Create a sync job and schedule it. List<JobInfo> pendingJobs = jobScheduler.getAllPendingJobs(); if (pendingJobs.isEmpty()) { String inputId = context.getSharedPreferences(SyncJobService.PREFERENCE_EPG_SYNC, Context.MODE_PRIVATE).getString(SyncJobService.BUNDLE_KEY_INPUT_ID, null); if (inputId != null) { // Set up periodic sync only when input has set up. SyncUtils.setUpPeriodicSync(context, inputId); } return; } // On L/L-MR1, reschedule the pending jobs. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { for (JobInfo job : pendingJobs) { if (job.isPersisted()) { jobScheduler.schedule(job); } } } }
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)) .setMinimumLatency(0) .setExtras(bundle) .build()); }
@Override public int schedule(JobInfo job) throws RemoteException { int vuid = VBinder.getCallingUid(); int id = job.getId(); ComponentName service = job.getService(); JobId jobId = new JobId(vuid, service.getPackageName(), id); JobConfig config = mJobStore.get(jobId); if (config == null) { config = new JobConfig(mGlobalJobId++, service.getClassName(), job.getExtras()); mJobStore.put(jobId, config); } else { config.serviceName = service.getClassName(); config.extras = job.getExtras(); } saveJobs(); mirror.android.app.job.JobInfo.jobId.set(job, config.virtualJobId); mirror.android.app.job.JobInfo.service.set(job, mJobProxyComponent); return mScheduler.schedule(job); }
@Test public void testStart() { Context context = InstrumentationRegistry.getTargetContext(); QuickPeriodicJobScheduler qpjs = new QuickPeriodicJobScheduler(context); qpjs.start(2, 30000l); SystemClock.sleep(1000); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); List<JobInfo> jobInfoList = jobScheduler.getAllPendingJobs(); JobInfo jobInfo = null; for(JobInfo job : jobInfoList) { if(job.getId() == 2) { jobInfo = job; } } Assert.assertEquals(jobInfo.getMaxExecutionDelayMillis(), 30000l); Assert.assertEquals(jobInfo.getMinLatencyMillis(), 30000l); Assert.assertEquals(jobInfo.getId(), 2); Assert.assertEquals(jobInfo.getExtras().getLong("interval"), 30000l); Assert.assertNotNull(jobInfo); }
@SuppressWarnings("ConstantConditions") public static void schedule(final Context context) { final JobScheduler scheduler = context.getSystemService(JobScheduler.class); for (final JobInfo job : scheduler.getAllPendingJobs()) { if (job.getId() == JOB_ID_PERIODIC) { return; } } final long interval = MINUTE * Integer.valueOf(DefaultSharedPrefUtils.getBackgroundServiceInterval(context)); final ComponentName name = new ComponentName(context, PeriodicJob.class); final int result = scheduler.schedule(new JobInfo.Builder(JOB_ID_PERIODIC, name) .setPeriodic(interval) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build()); if (result != JobScheduler.RESULT_SUCCESS) { Log.e(TAG, "Failed to schedule periodic job"); } }
public void schedule(int time, boolean startOnBoot) { if (mAlarm == null) { JobInfo.Builder job = new JobInfo.Builder(1, new ComponentName(mContext, NotificationsJS.class)); PersistableBundle pb = new PersistableBundle(); pb.putInt("JobSyncTime", time); job.setPersisted(startOnBoot) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setMinimumLatency(time) .setExtras(pb); if (connected()) if (syncExact == 1) job.setOverrideDeadline(time); else job.setOverrideDeadline(time * 2); mJobScheduler.schedule(job.build()); Log.i("MFB_Scheduler", "JobScheduler started"); } else { syncTime = time; receiver = new Receiver(); IntentFilter filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); mContext.getPackageManager().setComponentEnabledSetting(new ComponentName(mContext, Receiver.class), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); mContext.registerReceiver(receiver, filter); Log.i("MFB_Scheduler", "AlarmManager started"); } }
public static void schedule(Context context) { SharedPreferences settings = AppSettings.getSharedPreferences(context); int notificationsFrequency = AppSettings.Notifications.getNotificationsFrequency(settings); ComponentName component = new ComponentName(context, NotificationsJobService.class); JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, component) .setPeriodic(60000 * notificationsFrequency); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NOT_ROAMING); else builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(builder.build()); }
@TargetApi(21) public static void startPolling(Context context) { JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); final int JOB_ID = 1; if (isBeenScheduled(JOB_ID, context)){ Log.i(TAG, "scheduler.cancel(JOB_ID)"); scheduler.cancel(JOB_ID); } else{ Log.i(TAG, "scheduler.schedule(jobInfo)"); int pollInterval = QueryPreferences.getPollInterval(context); Log.i(TAG, "the poll interval is: " + pollInterval + " ms"); JobInfo jobInfo = new JobInfo.Builder( JOB_ID, new ComponentName(context, PollJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setPeriodic(pollInterval) .setPersisted(true) .build(); scheduler.schedule(jobInfo); } }
@Override public void onBindViewHolder(JobListRecyclerAdapter.JobViewHolder holder, int position) { final JobInfo ji= mJobList.get(position); holder.jobId.setText(Integer.toString(ji.getId())); holder.serviceName.setText(ji.getService().getClassName()); holder.stopBut.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { JobScheduler jobScheduler = (JobScheduler)mContext.getSystemService(mContext.JOB_SCHEDULER_SERVICE); jobScheduler.cancel(ji.getId()); Log.i("JobList", "Stopping the job "+ji.getId()); Toast.makeText(mContext, "Canceling the job "+ji.getId(), Toast.LENGTH_LONG).show(); mContext.initList(); } }); }
private static void schedulePeriodic(Context context) { Timber.d("Scheduling a periodic task"); JobInfo.Builder builder = new JobInfo.Builder( PERIODIC_ID, new ComponentName(context, QuoteJobService.class)); builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setPeriodic(PERIOD) .setBackoffCriteria(INITIAL_BACKOFF, JobInfo.BACKOFF_POLICY_EXPONENTIAL); JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE); int result = scheduler.schedule(builder.build()); if (result == JobScheduler.RESULT_SUCCESS) { Timber.i("Job scheduled successfully!"); } else { Timber.e("Job did not scheduled!"); } }
private void syncJob() { QiscusAccount qiscusAccount = Qiscus.getQiscusAccount(); Random rand = new Random(); int randomValue = rand.nextInt(50); JobInfo jobInfo = new JobInfo.Builder(qiscusAccount.getId() + randomValue, componentName) .setPeriodic(TimeUnit.MINUTES.toMillis(15)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); if (jobScheduler != null) { jobScheduler.schedule(jobInfo); } }
private static void registerForNetworkAvailability(Context context) { JobScheduler jobScheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE); if (jobScheduler == null) { return; } int scheduleId = getScheduleId(context, ON_NETWORK_AVAILABLE_JOB_ID); jobScheduler.cancel(scheduleId); int r = jobScheduler.schedule(new JobInfo.Builder(scheduleId, new ComponentName(context, MobileMessagingJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build()); if (r == JobScheduler.RESULT_SUCCESS) { MobileMessagingLogger.d(TAG, "Registered job for connectivity updates"); } else { MobileMessagingLogger.e(TAG, "Failed to register job for connectivity updates"); } }
@Override public void onReceive(Context context, Intent intent) { Log.d(getClass().getName(), "onReceive"); // // Automatically open application // Intent bootIntent = new Intent(context, MainActivity.class); // bootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // context.startActivity(bootIntent); // Initiate background job for synchronizing with server content ComponentName componentName = new ComponentName(context, ContentSynchronizationJobService.class); JobInfo.Builder builder = new JobInfo.Builder(LiteracyApplication.CONTENT_SYNCRHONIZATION_JOB_ID, componentName); builder.setPeriodic(1000 * 60 * 30); // Every 30 minutes JobInfo jobInfo = builder.build(); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(jobInfo); /*if (StartPrefsHelper.scheduleAfterBoot(context)){ scheduleAuthenticationJobs(context); } else { Log.i(getClass().getName(), "Authentication jobs won't be scheduled because the 7 days after first start-up haven't passed yet."); }*/ scheduleAuthenticationJobs(context); }
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)); } }
@Test public void testScheduledJob() { PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application) .edit() .putBoolean(RuntimeEnvironment.application.getString(R.string.pref_saved_item_sync), true) .apply(); shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)) .setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null, ConnectivityManager.TYPE_WIFI, 0, true, true)); new SyncScheduler().scheduleSync(RuntimeEnvironment.application, "1"); List<JobInfo> pendingJobs = shadowOf((JobScheduler) RuntimeEnvironment.application .getSystemService(Context.JOB_SCHEDULER_SERVICE)).getAllPendingJobs(); assertThat(pendingJobs).isNotEmpty(); JobInfo actual = pendingJobs.get(0); assertThat(actual.getService().getClassName()) .isEqualTo(ItemSyncJobService.class.getName()); }
private void waitForNetwork() { // SDK check! We'll go with JobScheduler if we can. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // JobScheduler time! It's fancier! JobScheduler js = (JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo job = new JobInfo.Builder( ALARM_CONNECTIVITY_JOB, new ComponentName(this, AlarmServiceJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); js.schedule(job); } else { // Otherwise, just use the ol' package component. AndroidUtil.setPackageComponentEnabled(this, NetworkReceiver.class, true); } }
private void showWaitingForConnectionNotification() { Notification.Builder builder = getFreshNotificationBuilder() .setOngoing(true) .setContentTitle(getString(R.string.wiki_notification_waiting_for_connection_title)) .setContentText(getString(R.string.wiki_notification_waiting_for_connection_content)) .setSmallIcon(R.drawable.ic_stat_navigation_more_horiz) .setContentIntent(getBasicCommandIntent(QueueService.COMMAND_RESUME)); mNotificationManager.notify(R.id.wiki_waiting_notification, builder.build()); // If we have JobScheduler (SDK 21 or higher), use that. Otherwise, go // with the old ConnectivityListener style. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { JobScheduler js = (JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo job = new JobInfo.Builder( WIKI_CONNECTIVITY_JOB, new ComponentName(this, WikiServiceJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); js.schedule(job); } else { // Make sure the connectivity listener's waiting for a connection. AndroidUtil.setPackageComponentEnabled(this, WikiServiceConnectivityListener.class, true); } }
@Override public void onClick(View view) { switch (view.getId()) { case R.id.button: JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(this, MyJobService.class)); builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setRequiresCharging(true); if (mScheduler.schedule(builder.build())<1) { Log.e(TAG, "Can't schedule job for some reason. Check your JobInfo parameters"); }; break; case R.id.cancel_button: mScheduler.cancel(JOB_ID); break; } }
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(); }
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"); } }
@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(endMs), Common.getRescheduleCount(request)); }
@Override public void plantPeriodic(JobRequest request) { long intervalMs = request.getIntervalMs(); long flexMs = request.getFlexMs(); JobInfo jobInfo = createBuilderPeriodic(createBaseBuilder(request, true), intervalMs, flexMs).build(); int scheduleResult = schedule(jobInfo); if (scheduleResult == ERROR_BOOT_PERMISSION) { jobInfo = createBuilderPeriodic(createBaseBuilder(request, false), intervalMs, flexMs).build(); scheduleResult = schedule(jobInfo); } mCat.d("Schedule periodic jobInfo %s, %s, interval %s, flex %s", scheduleResultToString(scheduleResult), request, JobUtil.timeToString(intervalMs), JobUtil.timeToString(flexMs)); }
@Override public void plantPeriodicFlexSupport(JobRequest request) { long startMs = Common.getStartMsSupportFlex(request); long endMs = Common.getEndMsSupportFlex(request); 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 periodic (flex support) jobInfo %s, %s, start %s, end %s, flex %s", scheduleResultToString(scheduleResult), request, JobUtil.timeToString(startMs), JobUtil.timeToString(endMs), JobUtil.timeToString(request.getFlexMs())); }
@Override public boolean isPlatformJobScheduled(JobRequest request) { List<JobInfo> pendingJobs; try { pendingJobs = getJobScheduler().getAllPendingJobs(); } catch (Exception e) { // it's possible that this throws an exception, see https://gist.github.com/vRallev/a59947dd3932d2642641 mCat.e(e); return false; } //noinspection ConstantConditions if (pendingJobs == null || pendingJobs.isEmpty()) { return false; } for (JobInfo info : pendingJobs) { if (isJobInfoScheduled(info, request)) { return true; } } return false; }
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"); } }
@VisibleForTesting static JobInfo createJobInfoFromTaskInfo(Context context, TaskInfo taskInfo) { PersistableBundle jobExtras = new PersistableBundle(); jobExtras.putString(BACKGROUND_TASK_CLASS_KEY, taskInfo.getBackgroundTaskClass().getName()); PersistableBundle persistableBundle = getTaskExtrasAsPersistableBundle(taskInfo); jobExtras.putPersistableBundle(BACKGROUND_TASK_EXTRAS_KEY, persistableBundle); JobInfo.Builder builder = new JobInfo .Builder(taskInfo.getTaskId(), new ComponentName(context, BackgroundTaskJobService.class)) .setExtras(jobExtras) .setPersisted(taskInfo.isPersisted()) .setRequiresCharging(taskInfo.requiresCharging()) .setRequiredNetworkType(getJobInfoNetworkTypeFromTaskNetworkType( taskInfo.getRequiredNetworkType())); if (taskInfo.isPeriodic()) { builder = getPeriodicJobInfo(builder, taskInfo); } else { builder = getOneOffJobInfo(builder, taskInfo); } return builder.build(); }
@Override public boolean schedule(Context context, TaskInfo taskInfo) { ThreadUtils.assertOnUiThread(); if (!BackgroundTaskScheduler.hasParameterlessPublicConstructor( taskInfo.getBackgroundTaskClass())) { Log.e(TAG, "BackgroundTask " + taskInfo.getBackgroundTaskClass() + " has no parameterless public constructor."); return false; } JobInfo jobInfo = createJobInfoFromTaskInfo(context, taskInfo); JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); if (taskInfo.shouldUpdateCurrent()) { jobScheduler.cancel(taskInfo.getTaskId()); } int result = jobScheduler.schedule(jobInfo); return result == JobScheduler.RESULT_SUCCESS; }
/** * Method used to register this service on the context. * * @param context The application context. */ @TargetApi(Build.VERSION_CODES.N) public void registerMediaContentJobService(Context context) { if (mSdkInt > Build.VERSION_CODES.N) { JobInfo.Builder builder = new JobInfo.Builder(MediaContentJobService.JOB_ID, new ComponentName(context, MediaContentJobService.class.getName())); builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Images.Media.INTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Video.Media.INTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); builder.setTriggerContentMaxDelay(1000); builder.setTriggerContentUpdateDelay(1000); builder.setRequiresDeviceIdle(false); logD(TAG, "registerMediaContentJobService"); scheduleMediaContentJobService(context, builder.build()); } }
@Deprecated public static void requestImmediateSync1(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 >= 22) { persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); persistableBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); } persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId); persistableBundle.putLong("bundle_key_sync_period", syncDuration); JobInfo.Builder builder = new JobInfo.Builder(1, jobServiceComponent); JobInfo jobInfo = builder .setExtras(persistableBundle) .setOverrideDeadline(1000) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); scheduleJob(context, jobInfo); Log.d(TAG, "Single job scheduled"); }
public static void setupIfNeededPeriodicWallpaperChange(Context context) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { Resources res = context.getResources(); JobScheduler scheduler = (JobScheduler) context .getSystemService(Context.JOB_SCHEDULER_SERVICE); if (scheduler.getAllPendingJobs().size() == 0) { ComponentName serviceEndpoint = new ComponentName(context, PeriodicWallpaperChangeService.class); JobInfo wallpaperChangeJob = new JobInfo.Builder( PeriodicWallpaperChangeService.JOB_ID, serviceEndpoint) .setRequiresCharging(false) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setPersisted(true) .setRequiresDeviceIdle(true) .setPeriodic(PERIOD_IN_HOURS * 60 * 60 * 1000) .build(); scheduler.schedule(wallpaperChangeJob); String scheduledMessage = res.getString(R.string.periodic_change_scheduled); Toast.makeText(context, scheduledMessage, Toast.LENGTH_SHORT).show(); } } }
@Override public void onReceive(Context context, Intent intent) { JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); // If there are not pending jobs. Create a sync job and schedule it. List<JobInfo> pendingJobs = jobScheduler.getAllPendingJobs(); if (pendingJobs.isEmpty()) { String inputId = context.getSharedPreferences(EpgSyncJobService.PREFERENCE_EPG_SYNC, Context.MODE_PRIVATE).getString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, null); if (inputId != null) { // Set up periodic sync only when input has set up. EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class)); } return; } // On L/L-MR1, reschedule the pending jobs. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { for (JobInfo job : pendingJobs) { if (job.isPersisted()) { jobScheduler.schedule(job); } } } }
/** * Initializes a job that will periodically update the app's channels and programs. * * @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 jobServiceComponent The {@link EpgSyncJobService} component name that will run. * @param fullSyncPeriod The period between when the job will run a full background sync in * milliseconds. * @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. */ public static void setUpPeriodicSync(Context context, String inputId, ComponentName jobServiceComponent, long fullSyncPeriod, long syncDuration) { if (jobServiceComponent.getClass().isAssignableFrom(EpgSyncJobService.class)) { throw new IllegalArgumentException("This class does not extend EpgSyncJobService"); } PersistableBundle persistableBundle = new PersistableBundle(); persistableBundle.putString(EpgSyncJobService.BUNDLE_KEY_INPUT_ID, inputId); persistableBundle.putLong(EpgSyncJobService.BUNDLE_KEY_SYNC_PERIOD, syncDuration); JobInfo.Builder builder = new JobInfo.Builder(PERIODIC_SYNC_JOB_ID, jobServiceComponent); JobInfo jobInfo = builder .setExtras(persistableBundle) .setPeriodic(fullSyncPeriod) .setPersisted(true) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build(); scheduleJob(context, jobInfo); if (DEBUG) { Log.d(TAG, "Job has been scheduled for every " + fullSyncPeriod + "ms"); } }
private void scheduleRetryArtworkDownload() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(new JobInfo.Builder(LOAD_ARTWORK_JOB_ID, new ComponentName(this, DownloadArtworkJobService.class)) .setRequiredNetworkType(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? JobInfo.NETWORK_TYPE_NOT_ROAMING : JobInfo.NETWORK_TYPE_ANY) .build()); } else { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); int reloadAttempt = sp.getInt(PREF_ARTWORK_DOWNLOAD_ATTEMPT, 0); sp.edit().putInt(PREF_ARTWORK_DOWNLOAD_ATTEMPT, reloadAttempt + 1).apply(); AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); long retryTimeMillis = SystemClock.elapsedRealtime() + (1 << reloadAttempt) * 2000; am.set(AlarmManager.ELAPSED_REALTIME, retryTimeMillis, TaskQueueService.getArtworkDownloadRetryPendingIntent(this)); } }
public static Intent maybeRetryDownloadDueToGainedConnectivity(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); List<JobInfo> pendingJobs = jobScheduler.getAllPendingJobs(); for (JobInfo pendingJob : pendingJobs) { if (pendingJob.getId() == LOAD_ARTWORK_JOB_ID) { return TaskQueueService.getDownloadCurrentArtworkIntent(context); } } return null; } return (PreferenceManager.getDefaultSharedPreferences(context) .getInt(PREF_ARTWORK_DOWNLOAD_ATTEMPT, 0) > 0) ? TaskQueueService.getDownloadCurrentArtworkIntent(context) : null; }