0

My app is targeting Android 7, with minimum SDK Android 4.

Hence, listening to CONNECTIVITY_CHANGE (Even when the app is killed) no longer work anymore. What I wish to do is

  1. Even when my main app is killed, when the internet connectivity change from "not available" to "available", I would like to start an alarm broadcast receiver.

I try to achieve with the following code

MainActivity.java

@Override
public void onPause() {
    super.onPause();
    installJobService();
}

private void installJobService() {
    // Create a new dispatcher using the Google Play driver.
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));

    Job myJob = dispatcher.newJobBuilder()
            // the JobService that will be called
            .setService(MyJobService.class)
            // uniquely identifies the job
            .setTag("my-unique-tag")
            // one-off job
            .setRecurring(true)
            // persist forever
            .setLifetime(Lifetime.FOREVER)
            // start between 0 and 60 seconds from now
            .setTrigger(Trigger.executionWindow(0, 60))
            // overwrite an existing job with the same tag
            .setReplaceCurrent(true)
            // retry with exponential backoff
            .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
            // constraints that need to be satisfied for the job to run
            .setConstraints(
                    // only run on any network
                    Constraint.ON_ANY_NETWORK
            )
            .build();

    dispatcher.mustSchedule(myJob);
}

However,

MyJobService.java

import android.content.Context;

import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;

import org.yccheok.jstock.gui.JStockApplication;

/**
 * Created by yccheok on 21/5/2017.
 */

public class MyJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Context context = this.getApplicationContext();

        android.util.Log.i("CHEOK", "Internet -> " + Utils.isInternetAvailable(context));

        // Answers the question: "Is there still work going on?"
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        // Answers the question: "Should this job be retried?"
        return true;
    }
}

However, the above code isn't reliable. How I test is

  1. Quit my app.
  2. Kill my app explicitly via Settings using "Force stop".
  3. Turn off internet.
  4. Turn on internet.
  5. Wait for few minutes. MyJobService is never executed.

Is there any reliable way, to use FirebaseJobDispatcher to replace CONNECTIVITY_CHANGE reliably?

I had gone through Firebase JobDispatcher - how does it work compared to previous APIs (JobScheduler and GcmTaskService)? , but I still can't find a way to make it work reliably.

Community
  • 1
  • 1
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • Job dispatcher executes periodic jobs. The question is: why does your app need to monitor connectivity changes? Depending on the answer, you'll have to rethink the way your app works. – BladeCoder May 21 '17 at 12:17
  • We have a time-consuming stock market alert service. We only want to run such stock market alert service, just when the internet is available. We want to avoid running it, when internet is not available. We don't want to periodically run N minute checking, to check whether internet is available, before running stock alert service. It is not battery efficient. – Cheok Yan Cheng May 21 '17 at 14:02
  • Indeed. You should use Firebase push notifications in your case. They will be automatically delivered once the network comes back. – BladeCoder May 21 '17 at 15:07
  • The less optimal option is to use JobScheduler to schedule your update service every n hours, adding the network condition. This replaces both AlarmManager calls and listening to the connectivity broadcast. – BladeCoder May 21 '17 at 15:34
  • 1
    After reading and some experiment, I realize it is difficult to implement correctly for different version of Android. I choose to use library from evernote - https://github.com/evernote/android-job It works good so far. – Cheok Yan Cheng May 22 '17 at 10:37

1 Answers1

0

Not sure how you are detecting CONNECTIVITY_CHANGE through FirebaseJobDispatcher but for same situation I had used broadcast

public class ConnectivityStateReceiver extends BroadcastReceiver {
String TAG = "MyApp";

@Override
public void onReceive(Context context, Intent intent) {

    Intent serviceIntent = new Intent(context, NetworkService.class);

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (cm == null) {
        return;
    } else if (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected()) {
        Log.e(TAG, "Connected!");
        context.startService(serviceIntent);
    } else {
        Log.e(TAG, "Not Connected!");
        context.stopService(serviceIntent);
    }
}

}

Zeero0
  • 2,602
  • 1
  • 21
  • 36
  • Hi, there's change since Android 7. `Apps targeting Android 7.0 (API level 24) and higher do not receive CONNECTIVITY_ACTION broadcasts if they declare the broadcast receiver in their manifest.` - https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html – Cheok Yan Cheng May 21 '17 at 11:59