赞
踩
0. 前言
在Android开发中监听手机的网络状态是一个常见的功能,比如在没网的状态下进行提醒并引导用户打开网络设置,或者在非wifi状态下开启无图模式等等。因此本篇将网上的资料进行了整理总结,方便大家用到的时候可以快速地获取到手机的网络状态,节省时间。
1. 主动获取
之所以叫主动获取,是获取网络状态的时机是我们来定的,因此主动获取的代码位置比较灵活,可以是加载网络数据前,也可以在刚开启APP时,若没网则引导用户打开网络设置。下面是主动获取的工具类代码。主要还是调用了ConnectivityManager的系统服务。获取网络状态下面第一个方法基本上就够用了,后面两个获取IP地址、是否可以连接外网一般用不到。
- public class NetStateUtils {
- /*
- * 获取当前的网络状态 :没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2
- */
- public static int getNetworkType(Context context) {
- int netType = 0;
- ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = manager.getActiveNetworkInfo();
- if (networkInfo == null || !networkInfo.isAvailable()) {
- return netType;
- }
- int nType = networkInfo.getType();
- if (nType == ConnectivityManager.TYPE_WIFI) {
- //WIFI
- netType = 1;
- } else if (nType == ConnectivityManager.TYPE_MOBILE) {
- int nSubType = networkInfo.getSubtype();
- TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- if (nSubType == TelephonyManager.NETWORK_TYPE_LTE&&!telephonyManager.isNetworkRoaming()) {
- //4G
- netType = 4;
- } else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS
- || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA
- || nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0
- && !telephonyManager.isNetworkRoaming()) {
- //3G 联通的3G为UMTS或HSDPA 电信的3G为EVDO
- netType = 3;
- } else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS
- || nSubType == TelephonyManager.NETWORK_TYPE_EDGE
- || nSubType == TelephonyManager.NETWORK_TYPE_CDMA
- && !telephonyManager.isNetworkRoaming()) {
- //2G 移动和联通的2G为GPRS或EGDE,电信的2G为CDMA
- netType = 2;
- } else {
- netType = 2;
- }
- }
- return netType;
- }
- /**
- * 获得本机ip地址
- */
- public static String GetHostIp() {
- try {
- for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
- NetworkInterface intf = en.nextElement();
- for (Enumeration<InetAddress> ipAddr = intf.getInetAddresses(); ipAddr.hasMoreElements(); ) {
- InetAddress inetAddress = ipAddr.nextElement();
- if (!inetAddress.isLoopbackAddress()) {
- return inetAddress.getHostAddress();
- }
- }
- }
- } catch (Exception e) {
- }
- return null;
- }
-
- /*
- * 判断是否有外网连接
- */
- public static final boolean ping() {
- String result = null;
- try {
- String ip = "www.baidu.com";
- Process p = Runtime.getRuntime().exec("ping -c 3 -w 100 " + ip);// ping网址3次
- InputStream input = p.getInputStream();
- BufferedReader in = new BufferedReader(new InputStreamReader(input));
- StringBuffer stringBuffer = new StringBuffer();
- String content = "";
- while ((content = in.readLine()) != null) {
- stringBuffer.append(content);
- }
- int status = p.waitFor();
- if (status == 0) {
- return true;
- }
- } catch (Exception e) {
- }
- return false;
- }
- }
如果没有网络,可以弹出一个对话框来引导用户打开网络设置,这里可能你会用到的几个ACTION如下所示。
ACTION_DATA_ROAMING_SETTINGS : 跳转到移动网络设置界面
ACTION_WIFI_SETTINGS : 跳转到WIFI设置界面
ACTION_WIRELESS_SETTINGS : 跳转到无线控制界面,比如WIFI、蓝牙和移动网络设置界面。
- public static void showWifiDlg(final Context context) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context.getApplicationContext());
- if (mWifiDialog == null) {
- mWifiDialog = builder.setIcon(R.drawable.ic_launcher).setTitle("wifi设置")
- .setMessage("无网络").setPositiveButton("设置", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // 跳转到系统的网络设置界面
- Intent intent = null;
- // 先判断当前系统版本
- if (android.os.Build.VERSION.SDK_INT > 10) { // 3.0以上
- intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
- } else {
- intent = new Intent();
- intent.setClassName("com.android.settings",Settings.ACTION_WIFI_SETTINGS);
- }
- if ((context instanceof Application)) {
- intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
- }
- context.startActivity(intent);
- }
- }).setNegativeButton("知道了", null).create();
- // 设置为系统的Dialog,这样使用Application的时候不会报错
- mWifiDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- }
- mWifiDialog.show();
- }
在上述代码中,如果上下文信息是全局的上下文,则需要addFlags并且加入倒数第二行代码,否则会出错,还有就是不要忘记声明权限,最后一条权限即允许弹出系统级别的AlertDialog。
- <uses-permission android:name="android.permission.INTERNET"/>
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- <!--允许弹出系统级别的AlertDialog-->
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
2. 被动获取
被动获取是监听系统网络状态的广播。如果需要监听比如用户Wifi/移动网打开和关闭,以及连接上可用的连接等等行为,那么可以使用广播接收者来完成。因为不需要在APP退出后继续监听,因此可以使用动态的形式注册广播。
<receiver android:name=".NetworkConnectChangedReceiver"/>
接着在代码里动态的注册广播:
- IntentFilter filter = new IntentFilter();
- filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
- filter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
- filter.addAction("android.net.wifi.STATE_CHANGE");
- registerReceiver(mNetworkChangeListener,filter);
最后是广播接收者的具体代码如下,主要是几个广播的几个intent.getAction()的含义,需要多注意。
注释里已经写的很明白了,得感谢一下gdutxiaoxu,省的我们自己去查了。
- public class NetworkConnectChangedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // 这个监听wifi的打开与关闭,与wifi的连接无关
- if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
- int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
- switch (wifiState) {
- case WifiManager.WIFI_STATE_DISABLED:
- //引导用户打开设置
- break;
- case WifiManager.WIFI_STATE_DISABLING:
- break;
- case WifiManager.WIFI_STATE_ENABLING:
- break;
- case WifiManager.WIFI_STATE_ENABLED:
- //网络可用
- break;
- case WifiManager.WIFI_STATE_UNKNOWN:
- break;
- default:
- break;
- }
- }
- // 这个监听wifi的连接状态即是否连上了一个有效无线路由,当上边广播的状态是WifiManager
- // .WIFI_STATE_DISABLING,和WIFI_STATE_DISABLED的时候,根本不会接到这个广播。
- // 在上边广播接到广播是WifiManager.WIFI_STATE_ENABLED状态的同时也会接到这个广播,
- // 当然刚打开wifi肯定还没有连接到有效的无线
- if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
- Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- if (null != parcelableExtra) {
- NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
- State state = networkInfo.getState();
- boolean isConnected = state == State.CONNECTED;
- if (isConnected) {
- //网络可用
- } else {
- //网络不可用
- }
- }
- }
- // 最好用的还是这个监听。Wifi/移动网打开,关闭,以及连接上可用的连接都会接到监听
- // 这个广播的最大弊端是比上边两个广播的反应要慢,如果只是要监听wifi用上边两个配合比较合适
- if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
- ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
- if (activeNetwork != null) { // connected to the internet
- if (activeNetwork.isConnected()) {
- if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
- // connected to wifi
- } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
- // connected to the mobile signal
- }
- } else {
- //无网络连接
- }
- } else { // not connected to the internet
- }
- }
- }
- }
感谢:
http://blog.csdn.net/gdutxiaoxu/article/details/53008266
http://www.jianshu.com/p/10ed9ae02775
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。