android wifi是否可用,Android判断网络是否可用、区分WiFi和数据、是否被安全软件拦截...
Android判断网络是否可用、区分WiFi和数据、是否被安全软件拦截网络请求失败的原因有很多,手机没有连网是很常见的原因,这时需要提醒用户打开网络。怎么从众多可能的失败原因中判断是不是手机没连网呢?播放视频或者声音是很费流量的,如果用户用的是数据而非WiFi,就需要提醒他是否继续使用。怎么判断手机当前的网络是WiFi还是数据呢?手机连着网,但是用户在安全软件中设置了本应用禁用网络,这种情况与手机
Android判断网络是否可用、区分WiFi和数据、是否被安全软件拦截
网络请求失败的原因有很多,手机没有连网是很常见的原因,这时需要提醒用户打开网络。怎么从众多可能的失败原因中判断是不是手机没连网呢?
播放视频或者声音是很费流量的,如果用户用的是数据而非WiFi,就需要提醒他是否继续使用。怎么判断手机当前的网络是WiFi还是数据呢?
手机连着网,但是用户在安全软件中设置了本应用禁用网络,这种情况与手机没联连网是不一样的。怎么能区分出来并提示用户呢?
下面我们一一解答以上问题:
网络请求失败后,首先要判断手机是否联连着网,谷歌提供了网络连接的系统服务,可以用来判断手机是否连网:
// 判断网络是否可用
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (manager !=null){
NetworkInfo info = manager.getActiveNetworkInfo();
return info != null && info.isAvailable();
} else {
return false;
}
}
调用以上方法,如果返回false,提示用户“网络不可用,请检查网络设置”就好了。
有些情况下我们要实时接收网络状态的变化,这就需要注册广播接收者,接收网络状态的变化:
// 广播接收者,接收网络状态的变化
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
// 有网了
...
} else {
// 断网了
...
}
}
}
注册广播接收者:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
取消注册:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
对于只需要运行一次就够了的代码,可以在“有网了”的地方需要运行的代码后面取消注册。
以上广播接收者,会在注册之后接收一次,不会等到下次网络变化时才第一次接收。适用于用户进入APP之前没有打开网络,进入之后才去开启网络的情况,开启网络之后做一次网络请求刷新数据。
对于第二个问题,要分辨用户当前使用的是WiFi还是数据网络:
// 获取当前网络类型
public String getNetworkType(Context context) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mobileInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifiInfo != null && wifiInfo.isConnectedOrConnecting()) {
return "wifi_network";
} else if (mobileInfo != null && mobileInfo.isConnectedOrConnecting()) {
return "mobile_network";
} else {
return "no_network";
}
}
当然,也可以实时获取,注册广播接收者即可,前面写过,不再赘述。
对于第三个问题,比较麻烦,安全软件禁用当前APP的网络之后,调用网络是否可用的方法返回的是true,但是网络请求都是失败的,这时只能从失败原因里去找:
网络请求失败了,并且排除了手机没有连网的原因之后,如果以下代码成立,则很有可能是被安全管家禁网了:
if (e instanceof SocketException && e.getMessage().equals("Network is unreachable")) {
Toast.makeText(context, "网络请求失败,APP可能被安全软件禁网了", Toast.LENGTH_SHORT).show();
}
由于存在这种被安全管家禁网并且不能在网络请求之前判断出来,当然也不能实时监测出来,所以对于获取token和服务器时间戳之类的请求应该拦截器获取;页面中也不能完全依赖于自动刷新,还需要增加手动刷新、失败重试的功能。
更多推荐
所有评论(0)