2

I've a web based application, where the url is loaded when the app starts. I'm trying to handle a issue when

Internet of WiFi is turned off when resources are loading( resources are loaded in async format).

I'm using onReceivedError(WebView view, int errorCode, String description, String failingUrl) of WebViewClient for checking url failure. I've also tried onReceivedError(WebView view, WebResourceRequest request, WebResourceError error).

But i'm not getting any failure callback when internet of WiFi is turned off during resources are loading.

Shahal
  • 1,008
  • 1
  • 11
  • 29
  • 1
    better approach to detect network connectivity, use broadcast receiver with the context of your application, that will notify you wherever no network is available. something like youTube do – Ashwini Saini Jan 28 '20 at 06:01
  • 1
    Will it notify when internet of WiFi is turned Off and On? Because i tried ```ConnectivityManager.NetworkCallback``` in that ```onLost()``` is called when internet is turned off but then in 1-2 seconds ```onAvailable()``` will get called. I've also tried broadcast receiver with ```WifiManager.NETWORK_STATE_CHANGED_ACTION``` and ```ConnectivityManager.CONNECTIVITY_ACTION``` still not getting proper call when internet of WiFi is turned Off and On. – Shahal Jan 28 '20 at 06:05
  • @Shahal check my answer you cant load your webview without internet so you can check like internet connection like this. – InsaneCat Jan 28 '20 at 06:53
  • Hey @Shahal issue resolved or not? – InsaneCat Jan 28 '20 at 11:40

3 Answers3

1

This may not be the most efficient approach, but it's serving my purpose in this scenario. I'm using ping service(8.8.8.8 for now), JS callback and ConnectivityManager NetworkCallback to achieve this.

We're using a JS to check whether all the resources are loaded on not, it'll either give error, 'no' or 'yes'. Error & 'no' means html is not loaded completely.

ConnectivityManager NetworkCallback is used to know when internet of the same WiFi comes back when user is in Settings screen because if internet comes back we need to redirect user back to App. onLinkPropertiesChanged will be called in this scenario and we check whether internet is available using Ping service.

Network flow chart

Registering NetworkCallback

connectivityManager =
                    (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkRequest.Builder builder = new NetworkRequest.Builder();
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
            builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
            builder.addTransportType(NetworkCapabilities.TRANSPORT_VPN);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                connectivityManager.registerNetworkCallback(builder.build(), networkCallback);
            }

networkCallback

ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {

        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onAvailable(Network network) {
            // network available
            networkCheck(network);
        }

        @Override
        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
            super.onLinkPropertiesChanged(network, linkProperties);
            networkCheck(network);
        }

        @Override
        public void onLost(Network network) {
            // network unavailable
            onDisconnected();
        }
    };

networkCheck to check whether internet is available or not. Maybe this step can be ignore, while writing i though NET_CAPABILITY_VALIDATED would check internet. But it is failing in some scenario.

private void networkCheck(Network network) {
        ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getNetworkInfo(network);
        boolean isConnected = (info != null && info.isConnectedOrConnecting());

        if (!isConnected) {
            onDisconnected();
            return;
        }
        NetworkCapabilities nc = cm.getNetworkCapabilities(network);
        if (nc == null || !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) || !checkPingService()) {
            onDisconnected();
            return;
        }
        onConnected();
    }

checkPingService to check internet is available

private boolean checkPingService() {
        try {
            Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 8.8.8.8");
            int returnVal = p1.waitFor();
            return (returnVal == 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

This is working in all the scenarios we tested so far. So feel free to comment in case any doubt.

Community
  • 1
  • 1
Shahal
  • 1,008
  • 1
  • 11
  • 29
0

Try this:

You can put the conditions for network check and than build your logic as you want

WebView mWebView;
NetworkInfo networkInfoWifi = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE).getNetworkInfo(ConnectivityManager.TYPE_WIFI);

mWebView.setWebViewClient(mWebClient);

WebViewClient mWebClient = new WebViewClient(){

    @Override
    public boolean shouldOverrideUrlLoading(WebView  view, String  url){
        return true;
    }

    @Override
    public void onLoadResource(WebView  view, String  url){
        if (networkInfoWifi.isConnected()) {
            //Take action
        }
    }

}

Hope this will work!

Kalpesh Rupani
  • 991
  • 4
  • 12
  • ```networkInfoWifi.isConnected()``` will only tell if WiFi is connected not internet availability. Also ```onLoadResource()``` don't work well when the resources are loaded in async format(that is why i mentioned it in question). – Shahal Jan 28 '20 at 05:53
0

Create receiver for network change you can detect network is off or on like below you can send local broadcast to your activity -

public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {

    ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE );
      NetworkInfo activeNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
      boolean isConnected = activeNetInfo != null && activeNetInfo.isConnectedOrConnecting();   
      if (isConnected)       
          Log.i("NET", "Connected" + isConnected);   
      else 
          Log.i("NET", "Not Connected" + isConnected);
    }
}

Add below lines in menifest.xml file

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.INTERNET" />
 <receiver
        android:name="NetworkChangeReceiver"
        android:label="NetworkChangeReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
        </intent-filter>
    </receiver>
Dipankar Baghel
  • 1,932
  • 2
  • 12
  • 24
  • Try this scenario, Connect to a WiFi(preferably hotspot) turn on and off the internet connection in that. When you turn off the internet, you'll get " Not connected - updatevariable" and after 1-2 seconds "connected - update variable" will be called. – Shahal Jan 28 '20 at 08:02
  • yeh on network connected send broadcast to your activity and show web view and when not connected error dialog. – Dipankar Baghel Jan 28 '20 at 08:40
  • When internet is turned off both " Not connected - updatevariable" and "connected - update variable" is getting called. – Shahal Jan 28 '20 at 10:19