当前位置:   article > 正文

Android开发——监听Android手机的网络状态_android 监听网络状态

android 监听网络状态

0. 前言

Android开发中监听手机的网络状态是一个常见的功能,比如在没网的状态下进行提醒并引导用户打开网络设置,或者在非wifi状态下开启无图模式等等。因此本篇将网上的资料进行了整理总结,方便大家用到的时候可以快速地获取到手机的网络状态,节省时间。

 

1.  主动获取

之所以叫主动获取,是获取网络状态的时机是我们来定的,因此主动获取的代码位置比较灵活,可以是加载网络数据前,也可以在刚开启APP时,若没网则引导用户打开网络设置。下面是主动获取的工具类代码。主要还是调用了ConnectivityManager的系统服务。获取网络状态下面第一个方法基本上就够用了,后面两个获取IP地址、是否可以连接外网一般用不到。

  1. public class NetStateUtils {
  2. /*
  3. * 获取当前的网络状态 :没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2
  4. */
  5. public static int getNetworkType(Context context) {
  6. int netType = 0;
  7. ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
  8. NetworkInfo networkInfo = manager.getActiveNetworkInfo();
  9. if (networkInfo == null || !networkInfo.isAvailable()) {
  10. return netType;
  11. }
  12. int nType = networkInfo.getType();
  13. if (nType == ConnectivityManager.TYPE_WIFI) {
  14. //WIFI
  15. netType = 1;
  16. } else if (nType == ConnectivityManager.TYPE_MOBILE) {
  17. int nSubType = networkInfo.getSubtype();
  18. TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
  19. if (nSubType == TelephonyManager.NETWORK_TYPE_LTE&&!telephonyManager.isNetworkRoaming()) {
  20. //4G
  21. netType = 4;
  22. } else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS
  23. || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA
  24. || nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0
  25. && !telephonyManager.isNetworkRoaming()) {
  26. //3G 联通的3G为UMTS或HSDPA 电信的3G为EVDO
  27. netType = 3;
  28. } else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS
  29. || nSubType == TelephonyManager.NETWORK_TYPE_EDGE
  30. || nSubType == TelephonyManager.NETWORK_TYPE_CDMA
  31. && !telephonyManager.isNetworkRoaming()) {
  32. //2G 移动和联通的2G为GPRS或EGDE,电信的2G为CDMA
  33. netType = 2;
  34. } else {
  35. netType = 2;
  36. }
  37. }
  38. return netType;
  39. }
  40. /**
  41. * 获得本机ip地址
  42. */
  43. public static String GetHostIp() {
  44. try {
  45. for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
  46. NetworkInterface intf = en.nextElement();
  47. for (Enumeration<InetAddress> ipAddr = intf.getInetAddresses(); ipAddr.hasMoreElements(); ) {
  48. InetAddress inetAddress = ipAddr.nextElement();
  49. if (!inetAddress.isLoopbackAddress()) {
  50. return inetAddress.getHostAddress();
  51. }
  52. }
  53. }
  54. } catch (Exception e) {
  55. }
  56. return null;
  57. }
  58. /*
  59. * 判断是否有外网连接
  60. */
  61. public static final boolean ping() {
  62. String result = null;
  63. try {
  64. String ip = "www.baidu.com";
  65. Process p = Runtime.getRuntime().exec("ping -c 3 -w 100 " + ip);// ping网址3次
  66. InputStream input = p.getInputStream();
  67. BufferedReader in = new BufferedReader(new InputStreamReader(input));
  68. StringBuffer stringBuffer = new StringBuffer();
  69. String content = "";
  70. while ((content = in.readLine()) != null) {
  71. stringBuffer.append(content);
  72. }
  73. int status = p.waitFor();
  74. if (status == 0) {
  75. return true;
  76. }
  77. } catch (Exception e) {
  78. }
  79. return false;
  80. }
  81. }

如果没有网络,可以弹出一个对话框来引导用户打开网络设置,这里可能你会用到的几个ACTION如下所示。

ACTION_DATA_ROAMING_SETTINGS : 跳转到移动网络设置界面
ACTION_WIFI_SETTINGS : 跳转到WIFI设置界面
ACTION_WIRELESS_SETTINGS : 跳转到无线控制界面,比如WIFI、蓝牙和移动网络设置界面。

  1. public static void showWifiDlg(final Context context) {
  2. AlertDialog.Builder builder = new AlertDialog.Builder(context.getApplicationContext());
  3. if (mWifiDialog == null) {
  4. mWifiDialog = builder.setIcon(R.drawable.ic_launcher).setTitle("wifi设置")
  5. .setMessage("无网络").setPositiveButton("设置", new DialogInterface.OnClickListener() {
  6. @Override
  7. public void onClick(DialogInterface dialog, int which) {
  8. // 跳转到系统的网络设置界面
  9. Intent intent = null;
  10. // 先判断当前系统版本
  11. if (android.os.Build.VERSION.SDK_INT > 10) { // 3.0以上
  12. intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
  13. } else {
  14. intent = new Intent();
  15. intent.setClassName("com.android.settings",Settings.ACTION_WIFI_SETTINGS);
  16. }
  17. if ((context instanceof Application)) {
  18. intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
  19. }
  20. context.startActivity(intent);
  21. }
  22. }).setNegativeButton("知道了", null).create();
  23. // 设置为系统的Dialog,这样使用Application的时候不会报错
  24. mWifiDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
  25. }
  26. mWifiDialog.show();
  27. }

在上述代码中,如果上下文信息是全局的上下文,则需要addFlags并且加入倒数第二行代码,否则会出错,还有就是不要忘记声明权限,最后一条权限即允许弹出系统级别的AlertDialog

  1. <uses-permission android:name="android.permission.INTERNET"/>
  2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  4. <!--允许弹出系统级别的AlertDialog-->
  5. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

2.  被动获取

被动获取是监听系统网络状态的广播。如果需要监听比如用户Wifi/移动网打开和关闭,以及连接上可用的连接等等行为,那么可以使用广播接收者来完成。因为不需要在APP退出后继续监听,因此可以使用动态的形式注册广播。

<receiver android:name=".NetworkConnectChangedReceiver"/>

接着在代码里动态的注册广播:

  1. IntentFilter filter = new IntentFilter();
  2. filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
  3. filter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
  4. filter.addAction("android.net.wifi.STATE_CHANGE");
  5. registerReceiver(mNetworkChangeListener,filter);

最后是广播接收者的具体代码如下,主要是几个广播的几个intent.getAction()的含义,需要多注意。

注释里已经写的很明白了,得感谢一下gdutxiaoxu,省的我们自己去查了。

  1. public class NetworkConnectChangedReceiver extends BroadcastReceiver {
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. // 这个监听wifi的打开与关闭,与wifi的连接无关
  5. if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
  6. int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
  7. switch (wifiState) {
  8. case WifiManager.WIFI_STATE_DISABLED:
  9. //引导用户打开设置
  10. break;
  11. case WifiManager.WIFI_STATE_DISABLING:
  12. break;
  13. case WifiManager.WIFI_STATE_ENABLING:
  14. break;
  15. case WifiManager.WIFI_STATE_ENABLED:
  16. //网络可用
  17. break;
  18. case WifiManager.WIFI_STATE_UNKNOWN:
  19. break;
  20. default:
  21. break;
  22. }
  23. }
  24. // 这个监听wifi的连接状态即是否连上了一个有效无线路由,当上边广播的状态是WifiManager
  25. // .WIFI_STATE_DISABLING,和WIFI_STATE_DISABLED的时候,根本不会接到这个广播。
  26. // 在上边广播接到广播是WifiManager.WIFI_STATE_ENABLED状态的同时也会接到这个广播,
  27. // 当然刚打开wifi肯定还没有连接到有效的无线
  28. if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
  29. Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
  30. if (null != parcelableExtra) {
  31. NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
  32. State state = networkInfo.getState();
  33. boolean isConnected = state == State.CONNECTED;
  34. if (isConnected) {
  35. //网络可用
  36. } else {
  37. //网络不可用
  38. }
  39. }
  40. }
  41. // 最好用的还是这个监听。Wifi/移动网打开,关闭,以及连接上可用的连接都会接到监听
  42. // 这个广播的最大弊端是比上边两个广播的反应要慢,如果只是要监听wifi用上边两个配合比较合适
  43. if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
  44. ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
  45. NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
  46. if (activeNetwork != null) { // connected to the internet
  47. if (activeNetwork.isConnected()) {
  48. if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
  49. // connected to wifi
  50. } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
  51. // connected to the mobile signal
  52. }
  53. } else {
  54. //无网络连接
  55. }
  56. } else { // not connected to the internet
  57. }
  58. }
  59. }
  60. }

感谢:

http://blog.csdn.net/gdutxiaoxu/article/details/53008266

http://www.jianshu.com/p/10ed9ae02775

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/576759
推荐阅读
相关标签
  

闽ICP备14008679号