为了在设备连接/断开互联网时收到通知,我采取了以下方法:
ConnectivityManager connectivityManager = activity.getSystemService(ConnectivityManager.class);
ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
try {
activity.runOnUiThread(() -> {
tvNoInternet.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
MiscellaneousUtils.hideView(tvNoInternet, View.GONE);
}
});
behaviour.onConnected();
// behaviour is an interface named NetworkConnectionBehaviour (check the following snippet for its implementation)
});
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
try {
activity.runOnUiThread(() -> {
if (isInternetConnected(activity)) {
// check internet connection status because onLost() is called
// after onAvailable() when the device automatically switches
// internet connection from cellular to wifi
return;
}
tvNoInternet.animate().alpha(1f).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
MiscellaneousUtils.showView(tvNoInternet);
}
});
behaviour.onDisconnected();
});
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
};
try {
NetworkRequest networkRequest = getNetworkRequest();
// implementation of getNetworkRequest() is added in next snippet
connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
} catch (Exception e) {
Toast.makeText(activity, "Unexpected interruption! please try again later", Toast.LENGTH_SHORT).show();
}
接口网络连接行为:
public interface NetworkConnectionBehaviour {
void onConnected();
void onDisconnected();
}
实施
getNetworkRequest()
:
public static NetworkRequest getNetworkRequest() {
return new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build();
}
此方法适用于所有物理设备和android studio的模拟器。
但是,如果有人在 Bluestacks 5 模拟器上运行该应用程序,则根本不会调用 ConnectivityManager 的回调。而且它也不会产生任何异常。
我在这里遗漏了什么吗?有其他方法可以使用 BlueStacks ConnectivityManager 吗?
注意:它也显示了游戏循环模拟器的相同行为。
解决方案是删除传输类型:
TRANSPORT_WIFI
和 TRANSPORT_CELLULAR
,因为 BlueStacks 5 仿真器无法将其连接识别为这些传输类型之一。
功能
NET_CAPABILITY_INTERNET
将确保连接正常工作并且可以按照docs访问互联网:
表示该网络应该能够访问互联网。
现在
NetworkRequest
的代码应该如下:
public static NetworkRequest getNetworkRequest() {
return new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build();
}
为了在设备连接/断开互联网时收到通知,最好使用
registerDefaultNetworkCallback
而不是仅使用 registerNetworkCallback
。
“默认网络”是指应用程序用于互联网连接的默认网络。根据文档。
https://developer.android.com/reference/android/net/ConnectivityManager
尝试
connectivityManager.registerDefaultNetworkCallback(networkCallback);
您可以使用问题中定义的回调。
而且,如果您想检查它是否已连接,您应该同时检查
NET_CAPABILITY_INTERNET
和 NET_CAPABILITY_VALIDATED
。
所以我使用了如下所示的连接检查。
val caps = mConnectivityManager.getNetworkCapabilities(network)
if (caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
// connected
}