Skip to content

Instantly share code, notes, and snippets.

@Abhinav1217
Last active November 11, 2022 05:02
Show Gist options
  • Save Abhinav1217/0ff6b39e70fa38379d61e85e09b49fe7 to your computer and use it in GitHub Desktop.
Save Abhinav1217/0ff6b39e70fa38379d61e85e09b49fe7 to your computer and use it in GitHub Desktop.
Network Test on API 29 - Java
package com.example.simplenetwork;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.util.Log;
import androidx.annotation.NonNull;
public class CheckNetwork {
private Context context;
public CheckNetwork(Context context) {
this.context = context;
}
void registerDefaultNetworkCallback(){
try {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert connectivityManager != null;
connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(@NonNull android.net.Network network) {
super.onAvailable(network);
GlobalVars.isNetworkConnected = true;
Log.d("FLABS:", "onAvailable");
}
@Override
public void onLost(@NonNull android.net.Network network) {
super.onLost(network);
GlobalVars.isNetworkConnected = false;
Log.d("FLABS:", "onLost");
}
@Override
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {
super.onBlockedStatusChanged(network, blocked);
Log.d("FLABS:", "onBlockedStatusChanged");
}
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
Log.d("FLABS:", "onCapabilitiesChanged");
}
@Override
public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) {
super.onLinkPropertiesChanged(network, linkProperties);
Log.d("FLABS:", "onLinkPropertiesChanged");
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
Log.d("FLABS:", "onLosing");
}
@Override
public void onUnavailable() {
super.onUnavailable();
Log.d("FLABS:", "onUnavailable");
}
});
} catch (Exception e) {
Log.d("FLABS: Exception in registerDefaultNetworkCallback", "hello");
GlobalVars.isNetworkConnected = false;
}
}
void registerNetworkCallback(){
try {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
assert connectivityManager != null;
connectivityManager.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(@NonNull android.net.Network network) {
super.onAvailable(network);
GlobalVars.isNetworkConnected = true;
Log.d("FLABS:", "onAvailable");
}
@Override
public void onLost(@NonNull android.net.Network network) {
super.onLost(network);
GlobalVars.isNetworkConnected = false;
Log.d("FLABS:", "onLost");
}
@Override
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {
super.onBlockedStatusChanged(network, blocked);
Log.d("FLABS:", "onBlockedStatusChanged");
}
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
Log.d("FLABS:", "onCapabilitiesChanged");
}
@Override
public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) {
super.onLinkPropertiesChanged(network, linkProperties);
Log.d("FLABS:", "onLinkPropertiesChanged");
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
Log.d("FLABS:", "onLosing");
}
@Override
public void onUnavailable() {
super.onUnavailable();
Log.d("FLABS:", "onUnavailable");
}
});
} catch (Exception e) {
Log.d("FLABS: Exception in registerNetworkCallback", "hello");
GlobalVars.isNetworkConnected = false;
}
}
}
package com.example.simplenetwork;
public class GlobalVars {
public static int counter = 0;
public static boolean isNetworkConnected = false;
}
package com.example.simplenetwork;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Register NetworkCallback -- need to call this when activity starts
CheckNetwork network = new CheckNetwork(getApplicationContext());
/*
* registerNetworkCallback() is available from API-21 and above
* But it will show status of all available network. Hence you would
* to query onCapabilitiesChanged() to make sure your intended network is active or not.
*/
// network.registerNetworkCallback();
/*
* network.registerDefaultNetworkCallback() is available from API-24
* Unlike its counterpart, it will only register status of current active network
* Hence no need to check with onCapabilitiesChanged(). But downside is that it
* is available since API-24 while current recommendation (in 2019) is to maintain
* minimum support for API-23 Marshmallo.
*/
network.registerDefaultNetworkCallback();
final TextView text = findViewById(R.id.test_message);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@SuppressLint({"SetTextI18n", "DefaultLocale"})
@Override
public void onClick(View view) {
GlobalVars.counter++;
if (GlobalVars.isNetworkConnected) {
text.setText(String.format("Counter is %d, And network is Connected", GlobalVars.counter));
} else {
text.setText(String.format("Counter is %d, And network is Not Connected", GlobalVars.counter));
}
}
});
}
}
@Abhinav1217
Copy link
Author

Abhinav1217 commented Feb 1, 2021

@ksanbormukhim

How do i unregistered this callback?

From android documentation
Registers to receive notifications about changes in the system default network. The callbacks will continue to be called until either the application exits or unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback) is called.

There is a limit of 100 pending callbacks per app imposed by OS. Unless there is a leak in your code, it is almost impossible to reach that because most of the time Unregistration is automatically handled when Lifecycle ends. And also here you can see that we are using a static singleton to reuse object. But if you are really unsure what will your code do, you can unregisterNetworkCallback in your Activitiy onDestroy() . But I wont recommend that because that means that when next activity loads, you would register it again and destroy it again which is performance regression. Follow the clean architecture code principles.

Only place I have actually used unregister callback is quit menu within my app. But in reality, its just redundant because OS automatically handles it when app is closed. (See docs I linked).

The original gist from pranas has more detailed discussion on how to handle network.

@ksanbormukhim
Copy link

@Abhinav1217 thanks for the clarification

@cesarborrego
Copy link

I have a special scenario, onLost function does not work in api 31, android 12
I implemented registerDefaultNetworkCallback, but when wifi o cellular network is disconeted, the network call back doesn't call the onLost
Anyone has the similar issue?

@Abhinav1217
Copy link
Author

@cesarborrego

I have to check this. At my work, I am working with API-31 and didn't see this issue at my work.
It is working for other API+Android_Version combo?
Meanwhile check the original post, https://gist.github.com/PasanBhanu/730a32a9eeb180ec2950c172d54bb06a There are many other code snippets on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment