0

Here is what I want to achieve:

  1. Monitor network state in the background.
  2. When the device doesn't have internet.
  3. Trigger a Job.

Currently I see, there is no possibility to trigger a job when the device goes in "No Internet" state. Any workaround or solutions?

Note: I wouldn't prefer monitoring device internet connectivity via a foreground service.

Vickyexpert
  • 3,147
  • 5
  • 21
  • 34
shailesh mota
  • 309
  • 2
  • 7
  • I know you've already said you wouldn't prefer foreground services but Would you mind using a Handler's postDelayed for every minute or 10 minutes to check whether the internet is connected or not and if disconnected then a method call. – Lalit Fauzdar Oct 16 '17 at 15:27
  • `A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue`. So a handler is associated with a Thread. Which thread should I do this periodic check-up with ? If I do such operation on `main` thread wouldn't that be abuse of resources ? To get fine-grained control I might even need to perform such periodic checkups once every 5 seconds or so. – shailesh mota Oct 16 '17 at 15:42
  • Answering with similar thing I'm using. – Lalit Fauzdar Oct 16 '17 at 16:18
  • is your application running all the time? As workaround you can schedule periodic job with NETWORK_TYPE_NONE, say every minute and it will check network status, if device offline execute your logic. it will guarantee that job will not be executed while sleeping – Viktor Yakunin Oct 16 '17 at 18:48
  • My application is not running all the time in foreground. Isn't the minimum interval for a periodic job 15 minutes for Android O ? – shailesh mota Oct 17 '17 at 07:47

1 Answers1

0

Here's what you can use wherever you want but remember it should be started at least once which means either put this in an onCreate or if in a method then call the method at least once.

Handler handler = new Handler();
int timeDelay = 5000;     //5 seconds
handler.postDelayed(new Runnable(){
    public void run(){
        if(!isOnline)
         {
           yourMethodCall();
         }            
        handler.postDelayed(this, timeDelay );
    }
}, delay);

public boolean isOnline() throws InterruptedException, IOException {
        String command = "ping -c 1 google.com";
        return (Runtime.getRuntime().exec(command).waitFor() == 0);
    }

This is the code which will check for WORKING internet connection for every 5 seconds and if the connection is not working then it will call your method in it. Also, notice that Handler code is to be placed in a method and isOnline() is a method.

Working here is highlighted because the most common way to check for internet connection actually return true if a WiFi is connected without internet (basically a hotspot with no internet). But as you just want to check for no connection, you can use this code too.

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
          = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

But if using this way, you'll have to declare a permission in AndroidManifest.XML which is <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Use this, it will work great.

And Yes, it will run in the background. Not a problem in my app but some users reported that isOnline() method which is using ping to check connection can sometimes freeze the thread in case of no ping received for 5 seconds. So if this happens with you, you'll have to use isNetworkAvailable() method till then isOnline() is better.

EDIT -

When looking in Android References, I found this: void onDataConnectionStateChanged (int state)

This can be used to determine network state change. Default states are:

DATA_DISCONNECTED
DATA_CONNECTING
DATA_CONNECTED
DATA_SUSPENDED
Lalit Fauzdar
  • 5,953
  • 2
  • 26
  • 50
  • Thanks for the code. But this will run on `main` thread. What I will do is rather run it on a separate worker thread. I guess there is no other way than periodic network check up – shailesh mota Oct 16 '17 at 17:43
  • Exactly as whatever you do will either use a timer or an Alarm Manager or Handler as There's nothing like NetworkStateChangeListener so from these three, the best is Handler if the delay is less than 10 minutes. – Lalit Fauzdar Oct 16 '17 at 17:54
  • @Shaileshmota I just looked in Android References and found [this](https://developer.android.com/reference/android/telephony/PhoneStateListener.html#onDataConnectionStateChanged(int)), this can be useful. – Lalit Fauzdar Oct 16 '17 at 17:58
  • But those will not work in background. It needs a context which is alive. So with O onwards either a foreground service or an activity running in the foreground. However, what I want is to invisibly do things in background. – shailesh mota Oct 17 '17 at 07:50
  • That's why I said, Handler. – Lalit Fauzdar Oct 17 '17 at 07:53