Skip to content

Commit

Permalink
fix(android): fix for outdated network states (#510)
Browse files Browse the repository at this point in the history
See: https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback

This fixed the problem with outdated network states.
  • Loading branch information
Willham12 committed Nov 15, 2021
1 parent 1062c52 commit d5f06ba
Showing 1 changed file with 15 additions and 33 deletions.
Expand Up @@ -28,8 +28,6 @@
@TargetApi(Build.VERSION_CODES.N)
class NetworkCallbackConnectivityReceiver extends ConnectivityReceiver {
private final ConnectivityNetworkCallback mNetworkCallback;
Network mNetwork = null;
NetworkCapabilities mNetworkCapabilities = null;

public NetworkCallbackConnectivityReceiver(ReactApplicationContext reactContext) {
super(reactContext);
Expand Down Expand Up @@ -60,37 +58,39 @@ void unregister() {

@SuppressLint("MissingPermission")
void updateAndSend() {
Network network = getConnectivityManager().getActiveNetwork();
NetworkCapabilities capabilities = getConnectivityManager().getNetworkCapabilities(network);
ConnectionType connectionType = ConnectionType.UNKNOWN;
CellularGeneration cellularGeneration = null;
NetworkInfo networkInfo = null;
boolean isInternetReachable = false;
boolean isInternetSuspended = false;

if (mNetworkCapabilities != null) {
if (capabilities != null) {
// Get the connection type
if (mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {
connectionType = ConnectionType.BLUETOOTH;
} else if (mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
connectionType = ConnectionType.CELLULAR;
} else if (mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
connectionType = ConnectionType.ETHERNET;
} else if (mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
connectionType = ConnectionType.WIFI;
} else if (mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
connectionType = ConnectionType.VPN;
}

if (mNetwork != null) {
if (network != null) {
// This may return null per API docs, and is deprecated, but for older APIs (< VERSION_CODES.P)
// we need it to test for suspended internet
networkInfo = getConnectivityManager().getNetworkInfo(mNetwork);
networkInfo = getConnectivityManager().getNetworkInfo(network);
}

// Check to see if the network is temporarily unavailable or if airplane mode is toggled on
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
isInternetSuspended = !mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
isInternetSuspended = !capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
} else {
if (mNetwork != null && networkInfo != null) {
if (network != null && networkInfo != null) {
NetworkInfo.DetailedState detailedConnectionState = networkInfo.getDetailedState();
if (!detailedConnectionState.equals(NetworkInfo.DetailedState.CONNECTED)) {
isInternetSuspended = true;
Expand All @@ -99,13 +99,13 @@ void updateAndSend() {
}

isInternetReachable =
mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& mNetworkCapabilities.hasCapability(
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& capabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_VALIDATED)
&& !isInternetSuspended;

// Get the cellular network type
if (mNetwork != null && connectionType == ConnectionType.CELLULAR && isInternetReachable) {
if (network != null && connectionType == ConnectionType.CELLULAR && isInternetReachable) {
cellularGeneration = CellularGeneration.fromNetworkInfo(networkInfo);
}
} else {
Expand All @@ -118,50 +118,32 @@ void updateAndSend() {
private class ConnectivityNetworkCallback extends ConnectivityManager.NetworkCallback {
@Override
public void onAvailable(Network network) {
mNetwork = network;
mNetworkCapabilities = getConnectivityManager().getNetworkCapabilities(network);
updateAndSend();
}

@Override
public void onLosing(Network network, int maxMsToLive) {
mNetwork = network;
mNetworkCapabilities = getConnectivityManager().getNetworkCapabilities(network);
updateAndSend();
}

@Override
public void onLost(Network network) {
mNetwork = null;
mNetworkCapabilities = null;
updateAndSend();
}

@Override
public void onUnavailable() {
mNetwork = null;
mNetworkCapabilities = null;
updateAndSend();
}

@Override
public void onCapabilitiesChanged(
Network network, NetworkCapabilities networkCapabilities) {
mNetwork = network;
mNetworkCapabilities = networkCapabilities;
updateAndSend();
}

@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
// as a work-around for Android 10 Network callback for onLinkPropertiesChanged being triggered after the network is already lost.
// the onLost and onUnavailable handlers above set mNetwork to null
// if this handler is triggered after either of those, e.g., after the network is lost,
// this will send accurate details in the event.
if (mNetwork != null) {
mNetwork = network;
mNetworkCapabilities = getConnectivityManager().getNetworkCapabilities(network);
}
updateAndSend();
}
}
Expand Down

0 comments on commit d5f06ba

Please sign in to comment.