1

I am attempting to check for an internet connection with a NetworkCallBack. However, my code returns weird results. Please assist. Any help will be appreciated.

CheckNetwork.java

    import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkRequest;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

public class CheckNetwork {

    private Context context;
    
    public CheckNetwork(Context context) {
        this.context = context;
    }
    
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void registerNetworkCallback()
    {
        try {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkRequest.Builder builder = new NetworkRequest.Builder();

            connectivityManager.registerDefaultNetworkCallback( new ConnectivityManager.NetworkCallback(){
                                                                   @Override
                                                                   public void onAvailable(Network network) {
                                                                       Log.d("available", "internet");
                                                                       Variables.isNetworkConnected = true;
                                                                       Log.d("Net_Var_In", String.valueOf(Variables.isNetworkConnected));
                                                                   }
                                                                   @Override
                                                                   public void onLost(Network network) {
                                                                       Log.d("not_av", "internet");
                                                                       Variables.isNetworkConnected = false;
                                                                   }
                                                               }

            );
        }catch (Exception e){
            e.printStackTrace();
            Variables.isNetworkConnected = false;
        }

        Log.d("Net_Var_End", String.valueOf(Variables.isNetworkConnected));

    }
}

MainActivity.java

CheckNetwork checkNetwork = new CheckNetwork(getApplicationContext());
    checkNetwork.registerNetworkCallback();
    Log.d("Net_Var_Main", String.valueOf(Variables.isNetworkConnected));

    if(Variables.isNetworkConnected)
    {
        Log.d("Internet", "available");
    }
    else
    {
        setContentView(R.layout.activity_internet);
        return false;
    }

Logcat:

When internet is connected/available: (Even though it prints that internet is available, it still goes to layout_internet..which is the layout for when internet is NOT available)

    2020-07-17 14:07:09.735 3671-3671/com.example.scrollingtext D/Net_Var_End: false
2020-07-17 14:07:09.735 3671-3671/com.example.scrollingtext D/Net_Var_Main: false
2020-07-17 14:07:09.794 3671-3671/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2020-07-17 14:07:09.795 3671-3671/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2020-07-17 14:07:09.816 3671-3702/com.example.scrollingtext D/available: internet
2020-07-17 14:07:09.816 3671-3702/com.example.scrollingtext D/Net_Var_In: true

When internet is not connected/available: (Even though it prints that internet is available, it still goes to layout_internet..which is the layout for when internet is NOT available)

    2020-07-17 14:09:31.611 3744-3744/com.example.scrollingtext D/Net_Var_End: false
2020-07-17 14:09:31.611 3744-3744/com.example.scrollingtext D/Net_Var_Main: false
2020-07-17 14:09:31.663 3744-3744/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2020-07-17 14:09:31.663 3744-3744/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2020-07-17 14:09:31.678 3744-3776/com.example.scrollingtext D/available: internet
2020-07-17 14:09:31.678 3744-3776/com.example.scrollingtext D/Net_Var_In: true

EDIT

Based on CheckNetwork.java, which monitors the state of the network using a NetworkCallBack..how would you go about changing layout in front of the users screen when OnAvailable() and OnLost() is run? I would like to open layout_internet when OnLost() is run...and then layout_activity_main when OnAvailable is run. This needs to happen from within CheckNetwork. So, it seems that I am looking for access to setContentView (which is only available in MainActivity) from OnAvailable or OnLost. Or is there another way that I can open layout_internet and layout_activity_main when internet is available/lost?

imim
  • 53
  • 1
  • 8
  • You register a new default NetworkCallback which goes off and does some work in another thread. In the mean time the value of isNetworkConnected is logged twice: Net_Var_End, and Net_Var_Main. Your main goes off and displays this for you. Later the NetworkCallback finally gets to the onAvailable call and changes isNetworkConnected to true. – V.C. Jul 17 '20 at 12:40
  • Thanks. But why does it go to onAvailable in the case of when there is no internet connection? – imim Jul 17 '20 at 12:43
  • Are you sure there is no Network available and not just no Internet available? Is the local WiFi off And/Or is the internal Network device inactive or is your DSL connection off? – V.C. Jul 17 '20 at 12:51
  • The internet is not available. I manually disconnected the WIFI and have no mobile network. That is the case that I am testing. Sorry for the misinformation. – imim Jul 17 '20 at 12:53
  • It looks like a cell netowork also counts as a network, so only switching off the WiFi will not count on a device with a Simcard. https://stackoverflow.com/questions/53863034/difference-between-registerdefaultnetworkcallback-and-registernetworkcallback Also dont forget to call the Super on your callback: `super.onAvailable(network);` – V.C. Jul 17 '20 at 13:32
  • Ok thanks. What is the best way to test if an internet connection is available or not, be it WIFI (connected or connected but no internet available) or mobile network? – imim Jul 17 '20 at 13:33
  • That link show how to make a caller that differentiates between them, The default one doesnt. You have to set the NetworkCapabilities: `val builder = NetworkRequest.Builder() builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) //or NET_CAPABILITY_INTERNET or TRANSPORT_WIFI` – V.C. Jul 17 '20 at 13:40
  • Thanks I have added this, and now note that when WIFI is lost but Cell is available it will present a lost network (from WIFI) and then found network (from mobile network). – imim Jul 18 '20 at 07:40
  • It sounds like you have an answer for your question. Do you have the ability to post answers yet? or do you need more reputation? Maybe you have to edit your question so that others benefit from what you found out. Also if you found any of my comments helpful feel free to upvote them so they are more visible for others. – V.C. Jul 20 '20 at 08:39

3 Answers3

2

ConnectivityManager#registerDefaultNetworkCallback will return the default network for the device (or the app itself for Android 12+). Now, the default network doesn't always have full internet connectivity.

I'm not going to go too deep into how Android sets the default network but to fix you issue, change your call to registerDefaultNetworkCallback to instead use registerNetworkCallback with a NetworkRequest that includes the VALIDATED capability like so:

NetworkRequest nr = 
    new NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
    .build();

connectivityManager.registerNetworkCallback(
    nr, 
    new ConnectivityManager.NetworkCallback(){
        //REST OF YOUR CODE YOU ALREADY HAVE HERE

This works because now you will only be notified about networks that are VALIDATED (link) as opposed to the default network which may not be VALIDATED.

NET_CAPABILITY_VALIDATED

Indicates that connectivity on this network was successfully validated. For example, for a network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully detected.

Always Learning
  • 2,623
  • 3
  • 20
  • 39
1

You can review this code: https://github.com/vladan29/internet_monitor This is a working code that notifies subscribed classes about network changes continually. You can use standard android receiver instead EventBus but sticky intent is deprecated and you will have problems with start state. If you clone this app you can follow the connection state and some other values at the screen of the phone.

I must add some explanation. You can't simply use onLost() to detect when there is no internet connection. This has the correct work only if you have one internet in the area. If you have WIFI and CELLULAR available when one starts to lose signal another trigger onAvailable(), but onLost() is triggered later. At that moment you already have an alive connection and isConnected should be true.

Now, you can use a library at the link: https://github.com/vladan29/internet_checker/blob/master/README.md#internet_checker

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

    @Override
    public void onAvailable(@NonNull Network network) {
        super.onAvailable(network);
    }

    @Override
    public void onLost(@NonNull Network network) {
        super.onLost(network);
    }

    @Override
    public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
        super.onCapabilitiesChanged(network, networkCapabilities);
        final boolean unmetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
    }
};
Saeed Zhiany
  • 2,051
  • 9
  • 30
  • 41