Code Monkey home page Code Monkey logo

jobschedulercompat's Introduction

JobSchedulerCompat

Warning this project is not maintained! Check out https://developers.google.com/cloud-messaging/network-manager for a possibly better solution.

Maven Central

A backport of Android Lollipop's JobScheduler to api 10+.

All JobScheduler features are implemented. However, this library has not been well-tested, so I would advise not using in production at this time. There are no guarantees that this will not run down your battery or cause your device to explode.

Gradle

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

Maven

<dependency>
  <groupId>me.tatarka.support</groupId>
  <artifactId>jobscheduler</artifactId>
  <version>0.1.1</version>
  <type>aar</type>
</dependency>

You also have to enable manifest merging to ensure the services and receivers are added to your manifest.

<plugin>
  <groupId>com.jayway.maven.plugins.android.generation2</groupId>
  <artifactId>android-maven-plugin</artifactId>
  <configuration>
    <mergeManifests>true</mergeManifests>
  </configuration>
</plugin>

Usage

The api is identical to the official JobScheduler, the only differences will be what you import.

First create a service to run your job.

import me.tatarka.support.job.JobParameters;
import me.tatarka.support.job.JobService;

/**
 * Service to handle callbacks from the JobScheduler. Requests scheduled with the JobScheduler
 * ultimately land on this service's "onStartJob" method.
 */
public class TestJobService extends JobService {
  @Override
  public boolean onStartJob(JobParameters params) {
    // Start your job in a seperate thread, calling jobFinished(params, needsRescheudle) when you are done.
    // See the javadoc for more detail.
    return true;
  }

  @Override
  public boolean onStopJob(JobParameters params) {
    // Stop the running job, returing true if it needs to be recheduled.
    // See the javadoc for more detail.
    return true;
  }

Then use the JobScheduler to schedule the job.

import me.tatarka.support.job.JobInfo;
import me.tatarka.support.job.JobScheduler;
import me.tatarka.support.os.PersistableBundle;

// Get an instance of the JobScheduler, this will delegate to the system JobScheduler on api 21+ 
// and to a custom implementataion on older api levels.
JobScheduler jobScheduler = JobScheduler.getInstance(context);

// Extras for your job.
PersistableBundle extras = new PersistableBundle();
extras.putString("key", "value");

// Construct a new job with your service and some constraints.
// See the javadoc for more detail.
JobInfo job = new JobInfo.Builder(0 /*jobid*/, new ComponentName(context, TestJobService.class))
  .setMinimumLatency(1000)
  .setOverrideDeadline(2000)
  .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
  .setRequiresCharging(true)
  .setExtras(extras)
  .build();

jobScheudler.scheduleJob(job);

Finally, register your JobService in the Manifest. Since on api < 21 the JobScheduler runs within your app, you may need additional permissions depending on what you are doing.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="me.tatarka.support.job.sample">

  <!-- Always required on api < 21, needed to keep a wake lock while your job is running -->
  <uses-permission android:name="android.permission.WAKE_LOCK" />
  <!-- Required on api < 21 if you are using setRequiredNetworkType(int) -->
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <!-- Required on all api levels if you are using setPersisted(true) -->
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

  <application>
    ...
    
    <!-- Define your service, make sure to add the permision! -->
    <service
        android:name=".service.TestJobService"
        android:permission="android.permission.BIND_JOB_SERVICE"
        android:exported="true" />
  </application>
</manifest>

Important caveats when running on api < 21

  1. Pending jobs will be stored in <privateappdir>/system/job/jobs.xml. Do not delete this file as it will causing jobs to not run.

  2. If you use setRequiresDeviceIdle(true) then it may not immediately run in the first idle window. If your app is not running, it will no longer receive notifications on when the device is idle, therefore, it will awake every 91 minutes to check. This is hopefully a reasonable compromise between preserving battery life and ensuring your job is run.

  3. There may be other subtle differences on when and how many jobs run at the same time. This is because, unlike the system JobScheduler, the current implementatoin cannot detect the state of other jobs running on the system and batch them together.

Contributing

The best way to help out right now is by testing, run it for a while and see if it behaves like expected. Creating apps that would help log long-term usage would be helpful as well.

If you want to do something more specific, feel free to leave a comment on any of the unassigned issues, or create your own.

jobschedulercompat's People

Contributors

evant avatar fxp avatar nsk-mironov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jobschedulercompat's Issues

Proguard issue

I seem to be getting this issue when trying to minify. Anyone having the same issue?

Warning:android.app.job.IJobService: can't find referenced class android.app.job.JobParameters
Warning:android.app.job.IJobService$Stub: can't find referenced class android.app.job.JobParameters
Warning:android.app.job.IJobService$Stub$Proxy: can't find referenced class android.app.job.JobParameters
Warning:com.google.android.gms.common.GooglePlayServicesUtil: can't find referenced class android.content.pm.PackageInstaller
Warning:com.google.android.gms.common.GooglePlayServicesUtil: can't find referenced class android.content.pm.PackageInstaller$SessionInfo
Warning:com.google.android.gms.common.GooglePlayServicesUtil: can't find referenced class android.content.pm.PackageInstaller
Warning:com.google.android.gms.common.GooglePlayServicesUtil: can't find referenced class android.content.pm.PackageInstaller$SessionInfo
Warning:com.google.android.gms.common.GooglePlayServicesUtil: can't find referenced method 'android.content.pm.PackageInstaller getPackageInstaller()' in library class android.content.pm.PackageManager
Warning:me.tatarka.support.internal.IJobServiceCompat: can't find referenced class android.app.job.JobParameters
Warning:me.tatarka.support.internal.IJobServiceCompat$1: can't find referenced class android.app.job.JobParameters
Warning:me.tatarka.support.internal.IJobServiceCompat$3: can't find referenced class android.app.job.JobParameters
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobScheduler
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobScheduler
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo$Builder
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.os.PersistableBundle
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo$Builder
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo$Builder
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobScheduler
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo$Builder
Warning:me.tatarka.support.internal.JobSchedulerLollipopDelegate: can't find referenced class android.app.job.JobInfo
Warning:me.tatarka.support.os.PersistableBundleCompat: can't find referenced class android.os.PersistableBundle
Warning:me.tatarka.support.os.PersistableBundleCompat: can't find referenced method 'void writePersistableBundle(android.os.PersistableBundle)' in library class android.os.Parcel
Warning:me.tatarka.support.os.PersistableBundleCompat: can't find referenced method 'android.os.PersistableBundle readPersistableBundle()' in library class android.os.Parcel
Warning:me.tatarka.support.os.PersistableBundleCompat: can't find referenced class android.os.PersistableBundle
Warning:there were 112 unresolved references to classes or interfaces.
         You may need to add missing library jars or update their versions.
         If your code works fine without the missing classes, you can suppress
         the warnings with '-dontwarn' options.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Warning:there were 3 unresolved references to library class members.
         You probably need to update the library versions.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)
:app:proguardRelease FAILED

Could not find class 'android.os.PersistableBundle' on devices < API21

I tried to implement this library into one of my applications.
If I run the app on a device with API21 everything works fine, but with devices < API21 there's this error:

03-05 12:28:34.380    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve static field 96 (EMPTY) in Landroid/os/PersistableBundle;
03-05 12:28:34.390    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x62 at 0x0006
03-05 12:28:34.390    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.clear
03-05 12:28:34.440    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.440    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.440    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.containsKey
03-05 12:28:34.440    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.get
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getDouble
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getDouble
03-05 12:28:34.490    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getDoubleArray
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getInt
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getInt
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getIntArray
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getLong
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getLong
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getLongArray
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getPersistableBundle
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.500    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.550    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getString
03-05 12:28:34.550    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.550    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.630    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getString
03-05 12:28:34.630    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.630    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.getStringArray
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.instanceOf
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve instanceof 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x20 at 0x0006
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.isEmpty
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.keySet
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.newInstance
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve new-instance 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.640    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x22 at 0x0006
03-05 12:28:34.740    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.newInstance
03-05 12:28:34.750    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve new-instance 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.750    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x22 at 0x0006
03-05 12:28:34.760    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.newInstance
03-05 12:28:34.760    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve new-instance 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.760    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x22 at 0x0006
03-05 12:28:34.820    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putAll
03-05 12:28:34.820    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.820    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.820    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putDouble
03-05 12:28:34.820    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.820    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.940    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putDoubleArray
03-05 12:28:34.940    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:34.950    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:34.960    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putInt
03-05 12:28:34.960    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putIntArray
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putLong
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.010    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putLongArray
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putPersistableBundle
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putString
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.putStringArray
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug I/dalvikvm﹕ Could not find method android.os.Parcel.readPersistableBundle, referenced from method me.tatarka.support.os.PersistableBundleCompat.read
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve virtual method 1051: Landroid/os/Parcel;.readPersistableBundle ()Landroid/os/PersistableBundle;
03-05 12:28:35.020    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0006
03-05 12:28:35.080    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.remove
03-05 12:28:35.080    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.080    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.080    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.size
03-05 12:28:35.080    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.090    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.090    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug E/dalvikvm﹕ Could not find class 'android.os.PersistableBundle', referenced from method me.tatarka.support.os.PersistableBundleCompat.write
03-05 12:28:35.090    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug W/dalvikvm﹕ VFY: unable to resolve check-cast 207 (Landroid/os/PersistableBundle;) in Lme/tatarka/support/os/PersistableBundleCompat;
03-05 12:28:35.090    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ VFY: replacing opcode 0x1f at 0x0006
03-05 12:28:35.090    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ DexOpt: unable to opt direct call 0x0432 at 0x08 in Lme/tatarka/support/os/PersistableBundleCompat;.newInstance
03-05 12:28:35.150    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ DexOpt: unable to opt direct call 0x0433 at 0x08 in Lme/tatarka/support/os/PersistableBundleCompat;.newInstance
03-05 12:28:35.150    1019-1096/de.carstenbaumhoegger.tambourcorps_app.pro.debug D/dalvikvm﹕ DexOpt: unable to opt direct call 0x0434 at 0x0a in Lme/tatarka/support/os/PersistableBundleCompat;.newInstance

I took the code from your Readme.
Do I have to manually import your PersistableBundleCompat?
I really like this lib, would be nice if you can help me with this error :)

android.app.ServiceConnectionLeaked

test sample with android 4.4.2 , this is the log :

E/ActivityThread﹕ Service me.tatarka.support.internal.job.JobSchedulerService has leaked ServiceConnection me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection@41d7c648 that was originally bound here
android.app.ServiceConnectionLeaked: Service me.tatarka.support.internal.job.JobSchedulerService has leaked ServiceConnection me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection@41d7c648 that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:1009)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:903)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1656)
at android.app.ContextImpl.bindService(ContextImpl.java:1639)
at android.content.ContextWrapper.bindService(ContextWrapper.java:517)
at me.tatarka.support.internal.job.JobSchedulerService.handleStartJob(JobSchedulerService.java:82)
at me.tatarka.support.internal.job.JobSchedulerService.access$400(JobSchedulerService.java:29)
at me.tatarka.support.internal.job.JobSchedulerService$1.handleMessage(JobSchedulerService.java:310)
at me.tatarka.support.internal.job.JobSchedulerService.onStartCommand(JobSchedulerService.java:46)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2868)
at android.app.ActivityThread.access$2100(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1418)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)

Bug fix: Rescheduling has problem (refers to issues #25 and #18)

The problem is occurred when you've recently scheduled an unmetered network triggered periodic job and after a while you want to schedule another job(e.g. an unmetered network triggered periodic job as the second job).

Issue : When the 2'nd job is going to add, the job scheduler stops the first job and in the following needs to reschedule it again. The scheduler probably has missed some operations within rescheduling process.

Solution : If you review the "scheduleJob(JobStatus job) { ... }" method in the "me.tatarka.support.internal.job.JobServiceCompat" class, you can find out there is a bug in the "me.tatarka.support.internal.job.JobSchedulerService" class exactly the "rescheduleJob(JobStatus job, boolean wasFailure) { ... }" method and you must change it. In the following there is a new implementation of the mentioned method.

In the JobSchedulerService class ==>

private void rescheduleJob(JobStatus job, boolean wasFailure) {
    JobStatus newJob;
    if (wasFailure) {
        newJob = rescheduleFailedJob(job);
    } else {
        newJob = reschedulePeriodicJob(job);
    }

    JobStore jobStore = JobStore.initAndGet(this);
    synchronized (jobStore) {
        jobStore.remove(job);
        jobStore.add(newJob);
    }

    TimeReceiver.setAlarmsForJob(this, newJob);
    if (job.hasIdleConstraint()) {
        IdleReceiver.setIdleForJob(this, newJob);
    }

    /**
     * The following constraints must be set and it is clear that those probably were forgotten
     */
    if (newJob.hasConnectivityConstraint() || newJob.hasUnmeteredConstraint()) {
        NetworkReceiver.setNetworkForJob(this, newJob);
        ReceiverUtils.enable(this, NetworkReceiver.class);
    }

    if (job.hasChargingConstraint()) {
        PowerReceiver.setPowerForJob(this, job);
        ReceiverUtils.enable(this, PowerReceiver.class);
    }

    if (job.isPersisted()) {
        ReceiverUtils.enable(this, BootReceiver.class);
    }
}

It is tested for 10 unmetered network triggered periodic job ( every job had a period of 500ms) and their worked without any error nonstop at least for 30 minutes.

Run Service only after run application

Dear Mr.evant
after set service to my application in api<21 service run only after run application and when I close app service don't run,But in api>21 service all of time run,
and
What is the difference between the two values
NETWORK_TYPE_UNMETERED
and
NETWORK_TYPE_ANY

Please give me an approach for fix this bug.

thank you,

ClassCastException proguard only on 5.0 Nexus 7

Error:

java.lang.RuntimeException: java.lang.ClassCastException: android.app.job.IJobCallback$Stub$Proxy cannot be cast to android.a.a.a
    at me.tatarka.support.job.JobService$JobHandler.handleMessage(Unknown Source)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5221)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
 Caused by: java.lang.ClassCastException: android.app.job.IJobCallback$Stub$Proxy cannot be cast to android.a.a.a
    at me.tatarka.support.internal.IJobServiceCompat.getCallback(Unknown Source)
    at me.tatarka.support.internal.IJobServiceCompat.access$100(Unknown Source)
    at me.tatarka.support.internal.IJobServiceCompat$3.acknowledgeStartMessage(Unknown Source)
    at me.tatarka.support.job.JobService$JobHandler.ackStartMessage(Unknown Source)
    ... 8 more

On Nexus 7 with Android 5.0.
Proguard rules:

-keep class me.tatarka.** { *; }
-dontwarn me.tatarka.**

Question about the documentation

In the README it states that you should use the JobScheduler-Singleton to schedule jobs, but the sample uses the service - which one should be used, or can both be used?

Client timed out while executing (no jobFinished received)

Hi,

First of all thanks for great compat library.

But I have an issue with long running operations.

I am scheduling a job

 JobInfo job = new JobInfo.Builder(taskId++,
                jobService)
                .setExtras(extras)
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                .setPersisted(true)
                .setOverrideDeadline(12000000)
                .build();
        jobScheduler.schedule(job);

And I have an JobService with AndroidAnnotations:

public class UploadImageJobService extends JobService {

       private final SparseArrayCompat<JobParameters> jobParamsMap = new SparseArrayCompat<>();

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        // extracting params and uploading large image
            jobParamsMap.put(jobParameters.getJobId(), jobParameters);
            uploadImage(params);
            return true;
     }
   @Background
   void uploadImage(){
   //uploading image using Retrofit
   if(success)  jobFinished(jobParamsMap.get(jobId), false);
   }
    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        //checking if image is sent 
        if (imageSent) {
            return false;
        }
        sendActionLog("onStopJob",
                    jobParameters.getJobId(), "sending not finished retry");
        return true;
    }
}

Uploading begins when there is internet connection but after some time Service just receives onStopJob()
logs:

01-11 13:58:14.756      554-554/? I/JobServiceContext﹕ Client timed out while executing (no jobFinished received). sending onStop. test.UploadImageJobService_ jId=0, u0
01-11 13:58:14.773  11487-11542/test E/UploadImageJobService﹕ job=0 | exam=1981 [onStopJob] PersistableBundle[{Id=1981}]

even if I call

 .setOverrideDeadline(12000000)

Is it a bug or am I doing smth wrong?

How can I force JobServiceContext to wait until I call jobFinished()?

Thanks.

Will it unbindService twice?

java.lang.IllegalArgumentException: Service not registered: me.tatarka.support.internal.job.a@42778390
at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:922)
at android.app.ContextImpl.unbindService(ContextImpl.java:1740)
at android.content.ContextWrapper.unbindService(ContextWrapper.java:536)
at me.tatarka.support.internal.job.JobSchedulerService.a(JobSchedulerService.java:212)
at me.tatarka.support.internal.job.JobSchedulerService.a(JobSchedulerService.java:29)
at me.tatarka.support.internal.job.a$1.jobFinished(JobSchedulerService.java:123)
at me.tatarka.support.job.d.handleMessage(JobService.java:122)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5426)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)

When the version is different from 21(LOLIPOP), it runs only once and stops.

Good night.
When I ran the program in KITKAT the program did not go into Loop, run the code only once, but shows no error, just stopped, follows the JobService class, thanks:

public class JobSchedulerService extends JobService {

public static final String TAG = "LOG";

@Override
public boolean onStartJob(JobParameters params) {
    Log.i(TAG, "onStartJob("+params.getExtras().getString("string")+")");
    new MyAsyncTask(this).execute(params);
    return true;
}

@Override
public boolean onStopJob(JobParameters params) {
    Log.i(TAG, "onStopJob()");
    return true;
}

// INNER CLASS
    private static class MyAsyncTask extends AsyncTask<JobParameters, Void, String>{
        private JobSchedulerService jss;

        public MyAsyncTask(JobSchedulerService j){
            jss = j;
        }

        @Override
        protected String doInBackground(JobParameters... params) {
            Log.i(TAG, "doInBackground()");

            SystemClock.sleep(5000);

            String answer = HttpConnection
                                .getSetDataWeb("http://www.villopim.com.br/android/ExampleJobScheduler/get-random.php",
                                        "method");

            jss.jobFinished(params[0], true);

            return answer;
        }
        @Override
        protected void onPostExecute(String s) {
            Log.i(TAG, "onPostExecute()");

            EventBus.getDefault().post( new MessageEB( s ));
        }
    }

}

A proper testing story

Right now this library has only been lightly tested (i.e. running jobs manually from the sample app and seeing if they appear to do the right thing). One idea I had was to create an app that will run a bunch of jobs for both the lollipop and compat versions and log when they start/stop. Then I can compare them and look for any instances where they differ.

Service not registered

java.lang.IllegalArgumentException: Service not registered: me.tatarka.support.internal.job.a@42778390
at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:922)
at android.app.ContextImpl.unbindService(ContextImpl.java:1740)
at android.content.ContextWrapper.unbindService(ContextWrapper.java:536)
at me.tatarka.support.internal.job.JobSchedulerService.a(JobSchedulerService.java:212)
at me.tatarka.support.internal.job.JobSchedulerService.a(JobSchedulerService.java:29)
at me.tatarka.support.internal.job.a$1.jobFinished(JobSchedulerService.java:123)
at me.tatarka.support.job.d.handleMessage(JobService.java:122)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5426)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)

java.lang.IllegalArgumentException: Service not registered

test your sample with android 4.4.2 , this is the log:

java.lang.IllegalArgumentException: Service not registered: me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection@42055c48
at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:961)
at android.app.ContextImpl.unbindService(ContextImpl.java:1690)
at android.content.ContextWrapper.unbindService(ContextWrapper.java:529)
at me.tatarka.support.internal.job.JobSchedulerService.finishJob(JobSchedulerService.java:212)
at me.tatarka.support.internal.job.JobSchedulerService.access$000(JobSchedulerService.java:29)
at me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection$1.acknowledgeStopMessage(JobSchedulerService.java:143)
at me.tatarka.support.job.JobService$JobHandler.ackStopMessage(JobService.java:158)
at me.tatarka.support.job.JobService$JobHandler.handleMessage(JobService.java:111)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)

Exception JobSchedulerService has leaked ServiceConnection

I encountered this issue 2 times today. Is anyone having this issue?

05-01 21:13:47.653: E/ActivityThread(11140): android.app.ServiceConnectionLeaked: Service me.tatarka.support.internal.job.JobSchedulerService has leaked ServiceConnection me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection@430e3130 that was originally bound here
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:988)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:882)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1912)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.ContextImpl.bindService(ContextImpl.java:1895)
05-01 21:13:47.653: E/ActivityThread(11140): at android.content.ContextWrapper.bindService(ContextWrapper.java:529)
05-01 21:13:47.653: E/ActivityThread(11140): at me.tatarka.support.internal.job.JobSchedulerService.handleStartJob(JobSchedulerService.java:82)
05-01 21:13:47.653: E/ActivityThread(11140): at me.tatarka.support.internal.job.JobSchedulerService.access$0(JobSchedulerService.java:55)
05-01 21:13:47.653: E/ActivityThread(11140): at me.tatarka.support.internal.job.JobSchedulerService$1.handleMessage(JobSchedulerService.java:310)
05-01 21:13:47.653: E/ActivityThread(11140): at me.tatarka.support.internal.job.JobSchedulerService.onStartCommand(JobSchedulerService.java:46)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2860)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.ActivityThread.access$2200(ActivityThread.java:161)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362)
05-01 21:13:47.653: E/ActivityThread(11140): at android.os.Handler.dispatchMessage(Handler.java:102)
05-01 21:13:47.653: E/ActivityThread(11140): at android.os.Looper.loop(Looper.java:157)
05-01 21:13:47.653: E/ActivityThread(11140): at android.app.ActivityThread.main(ActivityThread.java:5356)
05-01 21:13:47.653: E/ActivityThread(11140): at java.lang.reflect.Method.invokeNative(Native Method)
05-01 21:13:47.653: E/ActivityThread(11140): at java.lang.reflect.Method.invoke(Method.java:515)
05-01 21:13:47.653: E/ActivityThread(11140): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
05-01 21:13:47.653: E/ActivityThread(11140): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
05-01 21:13:47.653: E/ActivityThread(11140): at dalvik.system.NativeStart.main(Native Method)
05-01 21:13:47.673: D/AndroidRuntime(11140): Shutting down VM
05-01 21:13:47.673: W/dalvikvm(11140): threadid=1: thread exiting with uncaught exception (group=0x41831da0)
05-01 21:13:47.673: E/AndroidRuntime(11140): FATAL EXCEPTION: main
05-01 21:13:47.673: E/AndroidRuntime(11140): Process: com.example.mobile.ui, PID: 11140
05-01 21:13:47.673: E/AndroidRuntime(11140): java.lang.IllegalArgumentException: Service not registered: me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection@42f60160
05-01 21:13:47.673: E/AndroidRuntime(11140): at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:940)
05-01 21:13:47.673: E/AndroidRuntime(11140): at android.app.ContextImpl.unbindService(ContextImpl.java:1946)
05-01 21:13:47.673: E/AndroidRuntime(11140): at android.content.ContextWrapper.unbindService(ContextWrapper.java:541)
05-01 21:13:47.673: E/AndroidRuntime(11140): at me.tatarka.support.internal.job.JobSchedulerService.finishJob(JobSchedulerService.java:212)
05-01 21:13:47.673: E/AndroidRuntime(11140): at me.tatarka.support.internal.job.JobSchedulerService.access$4(JobSchedulerService.java:210)
05-01 21:13:47.673: E/AndroidRuntime(11140): at me.tatarka.support.internal.job.JobSchedulerService$JobServiceConnection$1.jobFinished(JobSchedulerService.java:123)
05-01 21:13:47.673: E/AndroidRuntime(11140): at me.tatarka.support.job.JobService$JobHandler.handleMessage(JobService.java:122)
05-01 21:13:47.673: E/AndroidRuntime(11140): at android.os.Handler.dispatchMessage(Handler.java:102)
05-01 21:13:47.673: E/AndroidRuntime(11140): at android.os.Looper.loop(Looper.java:157)
05-01 21:13:47.673: E/AndroidRuntime(11140): at android.app.ActivityThread.main(ActivityThread.java:5356)
05-01 21:13:47.673: E/AndroidRuntime(11140): at java.lang.reflect.Method.invokeNative(Native Method)
05-01 21:13:47.673: E/AndroidRuntime(11140): at java.lang.reflect.Method.invoke(Method.java:515)
05-01 21:13:47.673: E/AndroidRuntime(11140): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
05-01 21:13:47.673: E/AndroidRuntime(11140): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
05-01 21:13:47.673: E/AndroidRuntime(11140): at dalvik.system.NativeStart.main(Native Method)

Looking for a maintainer

After building this, I've discovered that I really don't have the interest in maintaining it. It still requires significant work to get into a production-quality state. And above all, it needs significant work monitoring battery usage and finding the optimal strategies between battery usage and running jobs in a timely manner. If anyone is interested, I'll gladly answer any question about implementation details and what needs to be fixed. I won't however, spend time tracking down bugs.

Caused by: java.lang.NullPointerException

when i test your sample application i found this problem , this is the log:

Process: me.tatarka.support.job.sample, PID: 29234
java.lang.RuntimeException: Unable to start service me.tatarka.support.job.sample.service.TestJobService@41e617c8 with null: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2885)
at android.app.ActivityThread.access$2100(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1418)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at me.tatarka.support.job.sample.service.TestJobService.onStartCommand(TestJobService.java:59)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2868)
            at android.app.ActivityThread.access$2100(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1418)
            at android.os.Handler.dispatchMessage(Handler.java:110)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:5292)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
            at dalvik.system.NativeStart.main(Native Method)

Marketing your library

Hi, I had made a video on your library to my thousands of subscribers out there and they still love it https://www.youtube.com/playlist?list=PLonJJ3BVjZW6CtAMbJz1XD8ELUs1KXaTD videos 44 45 46 cover it, I read in your README file that you were no longer gonna maintain this library actively and are looking for people who can do so, though I personally don't have the time, I can feature your video across my 50000+ subscribers and ask them whose interested to help you out, are you okay with that? if Yes lets talk about when , where, how and other items of interest, if NO, no problems, all the best and thanks for your efforts

Implemented Features?

I'm interested in contributing; what features are currently implemented and which ones need to be? Is this production-usable? (Probably not...)

JobSchedulerCompat could easily drain the battery

Hi evant

Thanks for creating this library and bringing one of the best feature of android L to the real world.

I tried to apply JobSchedulerCompat in one of my project, but I soon give it up. cause it consume the battery with unacceptable speed (40% for one night)

I simplely create 3 jobs, each jobs will run a intentservice, there is only one periodic job, and all 3 jobs require network connection.

I check a little bit and turns out that jobscheduler will frequently wake the phone,and last for quite long time. This is a energy killer, I think without resolving this problem, this library could not used in real project ( I know you pointed this out in readme, but I do wish it could be better)

And another issue I try to arise is the sample application could not running correctly (at least) on android 2.3 because of android:permission="android.permission.BIND_JOB_SERVICE" , I don't know if I use this correctly, but not works here~~

Investigate the viability of cross-app communication.

It's possible to use broadcasts to send information across apps sharing this library. This could be used, for example, to limit the number of jobs run at the same time, or to attempt to batch jobs across apps.

A couple of questions to answer:

  • Is such a system light-weight enough to improve battery performance?
  • Are there security concerns about what we send to other apps? Should be ok, as long as we are careful what we send!

Wrong README code snippet

There is misspelled "PersistableBundle" (correct one) instead of "PersitableBundle". Not a big deal but still it is there.

This library should wastes more battery for Android versions before Lollipop!

The mechanism of Lollipop JobScheduler is that, the service is inside a system process, which tracks the status of the device and wakes up our app processes when necessary. It's more battery-friendly compared to AlarmManager is that the condition-checking of the business logic is partly moved to JobScheduler service (in system process), so our app process don't need to frequently waked up.

I took a review of the code, for Lollipop it just delegates the job to official JobScheduler; while for API <= 4.4, BroadcastReceivers and WakeLocks are used in this library, so all the condition-checking is now inside app process, which is meaningless for using the lib. Even worse, the lib call PackageManager.setComponentEnabledSetting() with DONT_KILL_APP flag, which means the process of the app is less likely to be killed than normal. So using this lib may consume more battery power for devices before Lollipop.

NoSuchMethodException: putAll on 4.3

Tested the library on 4.3 today and got this error:

E/AndroidRuntime﹕ FATAL EXCEPTION: IntentService[JobServiceCompat]
    java.lang.RuntimeException: java.lang.NoSuchMethodException: putAll [interface java.util.Map]
            at me.tatarka.support.os.PersistableBundleCompat.putAll(PersistableBundleCompat.java:164)
            at me.tatarka.support.os.PersistableBundle.putAll(PersistableBundle.java:144)
            at me.tatarka.support.os.PersistableBundle.<init>(PersistableBundle.java:55)
            at me.tatarka.support.os.PersistableBundle.restoreFromXml(PersistableBundle.java:513)
            at me.tatarka.support.internal.job.JobStore$ReadJobMapFromDiskRunnable.restoreJobFromXml(JobStore.java:546)
            at me.tatarka.support.internal.job.JobStore$ReadJobMapFromDiskRunnable.readJobMapImpl(JobStore.java:443)
            at me.tatarka.support.internal.job.JobStore$ReadJobMapFromDiskRunnable.run(JobStore.java:388)
            at me.tatarka.support.internal.job.JobStore.readJobMapFromDisk(JobStore.java:229)
            at me.tatarka.support.internal.job.JobStore.<init>(JobStore.java:108)
            at me.tatarka.support.internal.job.JobStore.initAndGet(JobStore.java:88)
            at me.tatarka.support.internal.job.JobServiceCompat.handleSchedule(JobServiceCompat.java:94)
            at me.tatarka.support.internal.job.JobServiceCompat.onHandleIntent(JobServiceCompat.java:63)
            at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:61)
     Caused by: java.lang.NoSuchMethodException: putAll [interface java.util.Map]
            at java.lang.Class.getConstructorOrMethod(Class.java:423)
            at java.lang.Class.getDeclaredMethod(Class.java:589)
            at me.tatarka.support.os.PersistableBundleCompat.putAll(PersistableBundleCompat.java:158)
            at me.tatarka.support.os.PersistableBundle.putAll(PersistableBundle.java:144)
            at me.tatarka.support.os.PersistableBundle.<init>(PersistableBundle.java:55)
            at me.tatarka.support.os.PersistableBundle.restoreFromXml(PersistableBundle.java:513)
            at me.tatarka.support.internal.job.JobStore$ReadJobMapFromDiskRunnable.restoreJobFromXml(JobStore.java:546)
            at me.tatarka.support.internal.job.JobStore$ReadJobMapFromDiskRunnable.readJobMapImpl(JobStore.java:443)
            at me.tatarka.support.internal.job.JobStore$ReadJobMapFromDiskRunnable.run(JobStore.java:388)
            at me.tatarka.support.internal.job.JobStore.readJobMapFromDisk(JobStore.java:229)
            at me.tatarka.support.internal.job.JobStore.<init>(JobStore.java:108)
            at me.tatarka.support.internal.job.JobStore.initAndGet(JobStore.java:88)
            at me.tatarka.support.internal.job.JobServiceCompat.handleSchedule(JobServiceCompat.java:94)
            at me.tatarka.support.internal.job.JobServiceCompat.onHandleIntent(JobServiceCompat.java:63)
            at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:61)

Too much internal state is public

methods like JobParameters.getCallback() and PersistableBundle.saveToXml() should not be public. May require a package restructure.

JobService is not running

I have used this library Its working before. I don't no what I changed suddenly its not working

this my activity
private void setUpJobScheduler() {
jobScheduler = JobScheduler.getInstance(this);

    JobInfo job = new JobInfo.Builder(0, new ComponentName(this, NotificationJobService.class))
            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
            .setRequiresCharging(false)
            .setPeriodic(10000)
            /*.setExtras(extras)*/
            .build();
    System.out.println("======= inside job scheduler");
    jobScheduler.schedule(job);
}

this is my job service

public class NotificationJobService extends JobService implements BroadcastListCallback,TextToSpeech.OnInitListener{
private final LinkedList jobParamsMap = new LinkedList();
Cache session;
TextToSpeech speech;
@OverRide
public boolean onStartJob(JobParameters params) {
jobParamsMap.add(params);
System.out.println("====== inside job "+session.getNotificationFlag());
if(session.getLogin() && session.getNotificationFlag()) {
System.out.println("=========== yes");
NotificationServiceTask task = new NotificationServiceTask(this, session.getUserID(), "received", "", "");
task.execute();
}else{
JobParameters parameters=jobParamsMap.poll();
if (parameters == null) {

        }else {
            jobFinished(parameters, false);
        }
    }
    return false;
}

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

@Override
public void onBroadcastList(ArrayList<BroadcastRequests> list) {
    JobParameters parameters=jobParamsMap.poll();
    if (parameters == null) {

    }else {
        jobFinished(parameters, true);
    }

    System.out.println("======="+session.getRequestsCount() +"==="+ list.size());
    if(session.getType().equals("Retailer")){
        if(RetailersNavigationActivity.requestsCounter != null)
            RetailersNavigationActivity.requestsCounter.setText(list.size()+"");
    }else{
        if(NavigationActivity.requestsCounter != null)
            NavigationActivity.requestsCounter.setText(list.size()+"");
    }


}

@Override
public void onInit(int status) {
    if(status !=TextToSpeech.ERROR)
        speech.setLanguage(Locale.UK);
}

@Override
public void onCreate() {
    super.onCreate();
    session=new Cache(this);
    speech=new TextToSpeech(getApplicationContext(),this);
}

}

this service is not calling.

My manifest is


Tel me what is the reason

.setPeriodic does not work?

It seems to only run once. No matter the value. The task will run, and then never run again

JobScheduler jobScheduler = JobScheduler.getInstance(getActivity());
JobInfo job = new JobInfo.Builder(0 , new ComponentName(getActivity(), StartQuestionnaireTask.class))
.setPeriodic(1000)
.build();
jobScheduler.schedule(job);

The task just opens a toast

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.