1

I followed some online tutorials about jobscheduling in android and I tried doing it and found out that the below code compiles without errors. But the problem is there is no toast from the onPostExecute/doInBackground return message. Is there anything that might be required? Its like I just run the code and placed some toasts and notice that myScheduler.schedule(myjobInfo); works, background tasks is carrying out.

my gradle file is not touched at all

compileSdkVersion 26
 defaultConfig {
    applicationId "com.example.umarmalik.myapplication"
    minSdkVersion 21
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

This is my JobScheduler class

  public class MJobScheduler extends JobService {

private MJobExecutor executor;


@Override
public boolean onStartJob(final JobParameters params) {

executor = new MJobExecutor(){
    @Override
    protected void onPostExecute(String s) {
        Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
       jobFinished(params,true);
    }
};
    executor.execute();
    return true;
}

@Override
public boolean onStopJob(JobParameters params) {
    executor.cancel(true);
    return false;
}
}

This is my JobExecutor

public class MJobExecutor extends AsyncTask<Void,Void,String> {

@Override
protected String doInBackground(Void... voids) {
    return "Background task running";
}
}

my Main activity class is as following:

public class MainActivity extends AppCompatActivity {


private static final int JOBID = 110;
private JobScheduler myScheduler;
private JobInfo myjobInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ComponentName myComp = new ComponentName(this,MJobScheduler.class);
    JobInfo.Builder myBuilder = new JobInfo.Builder(JOBID,myComp);

    myBuilder.setPeriodic(6000);
    myBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
    myBuilder.setPersisted(true);


    myScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
    myjobInfo = myBuilder.build();


    myScheduler.schedule(myjobInfo);
}
}

My Manifest

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name=".MJobScheduler"
        android:permission="android.permission.BIND_JOB_SERVICE"
        android:exported="true" />

</application>
Ümañg ßürmån
  • 9,695
  • 4
  • 24
  • 41
CigarDon
  • 79
  • 1
  • 4
  • 14
  • Don't use an `AsyncTask`. At best, that is for UI stuff, where you need to do things on the main application thread. Use a regular `Thread`. Also, `setPeriodic()` does not support 6-second periods. Beyond that, as Viktoriia notes, use something other than `Toast` for debugging: `Log` statements, breakpoints, etc. – CommonsWare Mar 07 '18 at 14:20
  • "setPeriodic() does not support 6-second periods" so what is the number that i can use for this? – CigarDon Mar 07 '18 at 14:29
  • 2
    You can call `getMinPeriodMillis()` on a `JobInfo` to find the minimum period for the device you're running on. On many versions, it is 15 minutes (see [the Android 8.1 source](https://github.com/aosp-mirror/platform_frameworks_base/blob/android-cts-8.1_r2/core/java/android/app/job/JobInfo.java#L110), for example). – CommonsWare Mar 07 '18 at 14:36
  • Suppose if i start i a Job right now, when i will be notified that the job is done? is it within 15 minutes or exactly 15 min? – Aman Verma Jun 06 '18 at 11:01

1 Answers1

3

According to this answer the minimum possible time for periodic job is 15 minutes, that's why it doesn't work for you. https://stackoverflow.com/a/48337856/5604896

The better approach to update activity when job finished is to use broadcast receiver. If activity is running it will be notified.

public class MJobScheduler extends JobService {

    private MJobExecutor executor;


    @Override
    public boolean onStartJob(final JobParameters params) {

        executor = new MJobExecutor(this, params);
        executor.execute();
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        executor.cancel(true);
        return false;
    }

    private static class MJobExecutor extends AsyncTask<Void, Void, String> {
        private WeakReference<JobService> jobServiceReference;
        private JobParameters params;

        MJobExecutor(JobService jobService, JobParameters params) {
            jobServiceReference = new WeakReference<>(jobService);
            this.params = params;
        }

        @Override
        protected String doInBackground(Void... voids) {
            return "Background task running";
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            JobService jobService = jobServiceReference.get();
            if (jobService != null) {
                Intent intent = new Intent("JOB_FINISHED");
                intent.putExtra("result", s);
                LocalBroadcastManager.getInstance(jobService).sendBroadcast(intent);
                jobService.jobFinished(params, true);
            }
        }
    }
}

And your activity:

public class MainActivity extends AppCompatActivity {


    private static final int JOBID = 110;
    private JobScheduler myScheduler;
    private JobInfo myjobInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ComponentName myComp = new ComponentName(this, MJobScheduler.class);
        JobInfo.Builder myBuilder = new JobInfo.Builder(JOBID, myComp);
        myBuilder.setPeriodic(15 * 60 * 1000);

        myBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        myBuilder.setPersisted(true);

        myScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        myjobInfo = myBuilder.build();


        myScheduler.schedule(myjobInfo);

        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("JOB_FINISHED"));
    }

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, intent.getStringExtra("result"), Toast.LENGTH_LONG).show();
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
    }
}
  • Thank you works better, but regarding the interval of the background running tasks, it is inconsistent. for eg, running in background appears, then after 5 secs appears again then after 30 sec then 1 min......... is there any explanantion to it? and also where is the toast from? – CigarDon Mar 07 '18 at 16:39
  • @CigarDon about intervals - it shouldn't be the way you described. Can you try to remove the app and install it again, will it be the same? It should be fired every 15 mins or rarer - depends on the interval you set. According to the documentation "setPeriodic (long intervalMillis) - Specify that this job should recur with the provided interval, not more than once per period. You have no control over when within this interval this job will be executed, only the guarantee that it will be executed at most once within this interval. " – Viktoriia Chebotar Mar 08 '18 at 19:45
  • @CigarDon Regarding the second question I am not sure I understand. What do you mean by "where is the toast from"? – Viktoriia Chebotar Mar 08 '18 at 19:46