Reputation: 63
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?
Upvotes: 1
Views: 6895
Reputation: 2743
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.
Upvotes: 2
Reputation: 1
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);
}
};
Upvotes: 0
Reputation: 11
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
Upvotes: 1