New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update NetworkCallbackConnectivityReceiver.java #510
Conversation
See: https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback This fixed the problem with outdated network states.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!!
Stacking these PRs up, I'll merge them one by one as we work through them (that generates a release each time which is actually a plus as testers can then easily bisect on the changes in case there are some follow-on problems, but I see no issues with this
I added the github-special syntax |
Everything's merged and released off the PR queue except this one, just hoping for another set of eyes here but this is in "merge unless there is dissent" status for me, in other words if for some reason no one else looks at it, and I forget, please ping me to merge it and ship it |
Cool. This looks to me like a good change, which will have most of the same effect as reverting #443. (And I think #508 is another report of the same issue as #481.) Specifically, this makes it so that when one of the callback methods is invoked, instead of using the Before #443, we used the The
So I think the network it returns will always be the same one that we were getting updates about before #443. Even after this PR, I think it will still be helpful to revert #443, because otherwise we'd still be getting updates whenever some non-default network changes; we'd just redundantly look again at the default network's information. Conversely, even with #443 reverted, this PR would no longer change the behavior (with or without this PR, we'd always be looking at the information for the default network), but it looks like it would still be a helpful simplification. We're not using these (I guess a still-cleaner version would be for Oh, there is one bit that looks like it might be an undesired behavior change here: we'd be dropping this workaround logic: @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(); It looks like that was added in #265, to fix #244. I haven't dug into that issue to try to understand whether that's still likely to be needed. |
I guess in short:
|
Hello, Is there any estimate on when should we expect a fix for this? |
Sorry - project work taking priority at the moment. It appears a local patch via https://github.com/ds300/patch-package to revert #443 may be your best pending investigation of whether this one will cause #244 to come back - that investigation is the current hold up |
We have released quite recently at least, so once investigation is satisfactory, the merge --> release pathway is clean and ready to go. |
@DanijelBojcic try this patch, i have no problems. const netInfo = useNetInfo();
React.useEffect(() => {
if (netInfo.isConnected ?? false) {
console.log(connected);
}
}, [netInfo]); diff --git a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/NetworkCallbackConnectivityReceiver.java b/android/src/main/java/com/reactnativecommunity/netinfo/NetworkCallbackConnectivityReceiver.java
index 84d5088..68aedfd 100644
--- a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/NetworkCallbackConnectivityReceiver.java
+++ b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/NetworkCallbackConnectivityReceiver.java
@@ -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);
@@ -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;
@@ -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 {
@@ -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();
}
}
diff --git a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java
index 99ad861..837ccb7 100644
--- a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java
+++ b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java
@@ -59,7 +60,7 @@ public class BroadcastReceiverConnectivityReceiver extends ConnectivityReceiver
try {
NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
- if (networkInfo == null || !networkInfo.isConnected()) {
+ if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) {
connectionType = ConnectionType.NONE;
} else {
// Check if the internet is reachable
@@ -88,6 +89,8 @@ public class BroadcastReceiverConnectivityReceiver extends ConnectivityReceiver
case ConnectivityManager.TYPE_VPN:
connectionType = ConnectionType.VPN;
break;
+ default:
+ connectionType = ConnectionType.UNKNOWN;
}
}
} catch (SecurityException e) {
diff --git a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/types/CellularGeneration.java b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/types/CellularGeneration.java
index c64dfbf..8b56484 100644
--- a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/types/CellularGeneration.java
+++ b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/types/CellularGeneration.java
@@ -16,7 +16,8 @@ public enum CellularGeneration {
// We need to prefix these with "CG_" because they cannot start with numbers
CG_2G("2g"),
CG_3G("3g"),
- CG_4G("4g");
+ CG_4G("4g"),
+ CG_5G("5g");
public final String label;
@@ -49,6 +50,8 @@ public enum CellularGeneration {
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_LTE:
return CellularGeneration.CG_4G;
+ case TelephonyManager.NETWORK_TYPE_NR:
+ return CellularGeneration.CG_5G;
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return null;
diff --git a/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.h b/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.h
index 99d811d..8c86e55 100644
--- a/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.h
+++ b/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.h
@@ -23,6 +23,7 @@ static NSString *const RNCConnectionTypeEthernet = @"ethernet";
static NSString *const RNCCellularGeneration2g = @"2g";
static NSString *const RNCCellularGeneration3g = @"3g";
static NSString *const RNCCellularGeneration4g = @"4g";
+static NSString *const RNCCellularGeneration5g = @"5g";
@interface RNCConnectionState : NSObject
diff --git a/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.m b/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.m
index ef377e5..6607a09 100644
--- a/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.m
+++ b/node_modules/@react-native-community/netinfo/ios/RNCConnectionState.m
@@ -62,6 +62,9 @@ - (instancetype)initWithReachabilityFlags:(SCNetworkReachabilityFlags)flags
_cellularGeneration = RNCCellularGeneration3g;
} else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
_cellularGeneration = RNCCellularGeneration4g;
+ } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyNRNSA] ||
+ [netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyNR]) {
+ _cellularGeneration = RNCCellularGeneration5g;
}
}
} |
@Willham12 |
Just a note that I really appreciate the testing and results reports here - I am listening. I really do not have much time right now but I do have release capabilities on the repo so to be very prescriptive: Once there are test results you are confident in, if you could post a comment a fresh PR that represents tested code and specifies how it handles the problem introduced by #443 while hopefully not bringing #244 back, I can merge it and we can hopefully clean up this whole mess for everyone This seems to be the only active issue in the project so it would be great to see this nailed down |
I am about the merge the 5G patch, which will remove some of the non-callback noise from the above diff: #436 |
We have tried it in release and its working so far. |
I really appreciate the testing feedback.
diff --git a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java
index 99ad861..837ccb7 100644
--- a/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java
+++ b/node_modules/@react-native-community/netinfo/android/src/main/java/com/reactnativecommunity/netinfo/BroadcastReceiverConnectivityReceiver.java
@@ -59,7 +60,7 @@ public class BroadcastReceiverConnectivityReceiver extends ConnectivityReceiver
try {
NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
- if (networkInfo == null || !networkInfo.isConnected()) {
+ if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) {
connectionType = ConnectionType.NONE;
} else {
// Check if the internet is reachable
@@ -88,6 +89,8 @@ public class BroadcastReceiverConnectivityReceiver extends ConnectivityReceiver
case ConnectivityManager.TYPE_VPN:
connectionType = ConnectionType.VPN;
break;
+ default:
+ connectionType = ConnectionType.UNKNOWN;
}
}
} catch (SecurityException e) { If that's an important change (and honestly, it looks like it is...) could someone post that as a separate PR with some commentary on the what and the why 🙏 ? I'll continue do my best to keep this package alive and merge things that appear reasonable, I appreciate the patience and any help anyone can offer with regard to triage of issues, posting PRs, and testing reports, that's what will make this package work. Cheers! |
## [6.2.1](v6.2.0...v6.2.1) (2021-11-15) ### Bug Fixes * **android:** fix for outdated network states ([#510](#510)) ([d5f06ba](d5f06ba))
🎉 This PR is included in version 6.2.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Note the above comment ☝️
|
@Willham12 can you review your PR for the issues reported here? #542 Looks like something within these changes is causing the above issue. The issue does not happen for 6.2.0. |
When testing #542 I noticed that this line here https://github.com/react-native-netinfo/react-native-netinfo/pull/510/files#diff-7c418da854f11570a41e64f7d6917e2f8e57800a29bb581591f9072098c93241R69 returns WIFI capabilities (passing the null check) even though WiFi was turned off. Perhaps it is an Android 12 bug? |
After further digging, the Edit: looks like that only fixed it with the debugger attached, but still happens without it. |
that implies somehow a difference between whatever the javascript engine on device is (hermes? jsc?) and v8 (where the bundle runs with debugger attached). There are subtle differences like that when you use JSC (the debugger) which is why I always do print debugging for react-native basically, or now you may use Flipper and that won't alter the actual runtime - unless you already were using flipper then I don't understand (a common thing, always something to understand better...) ? I really really appreciate the digging here though. This stale state issue is the one and only hot topic here. It's causing many people pain |
I’m using android studio native debugger, I guess there’s a race condition or something there. I’m also not using Hermes. I don’t really understand why it would return that the current connection is wifi after it is actually off. |
Ah, native debugger should not be perturbing the |
@mikehardy the only thing I've seen that works is running all the network code from
However, from my testing, onLinkPropertiesChanged doesn't get called all the time, so we still need the above events. For the record, this is what I'm testing that seems to resolve the issue, but I'm not happy with the work around: https://github.com/cristianoccazinsp/react-native-netinfo/tree/android-fix |
@Willham12 the bug happens with this library's |
Well, after testing the above, the delay fixes turning on/off wifi changes, but wifi still gets reported as offline after the app is resumed from background for a long time. Something else is going on. |
Yeah, that package is really stale. Nothing useful for years https://github.com/flutter/plugins/commits/master/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity - I normally do like looking at flutter packages for inspiration but that one is not useful 🤷 |
could maybe work around that by having an AppState listener and re-fetch, that was already a workaround in our troubleshooting IIRC, and I thought at the time it was a candidate for module integration so it was just done by default, it would solve the iOS problem it's targeted at and the android problem at the same time. |
Seems like a lot of work for something that worked fine before this change :(, but maybe. |
I do see what you mean, but that one is broken for iOS out of the box too - it's problems with state staleness all around... |
Some more android testing... Force the device to sleep (with the device locked and screen off, and the app in background): Wake up the device: At this point, if you have a debugger on (native), it will fire
Unlock the device, open the app. The network info event fires a None/null from |
6.0.1版本,修改NetworkCallbackConnectivityReceiver文件: |
See: https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback
This fixed the problem with outdated network states.
Fixes #508