前言

查了一下判断网络是否可用,发现很多博客给的方法都是不正确的,大部分给的方法都是判断网络是否连接,一般来说,在大多数的情况下确实可以满足需求。但是有时会出现网络连接了却不能用的情况,这时就需要更精准的判断了。网上查到的有效的方法大多都是异步的,后来终于找到了一个不用异步的方法,只支持安卓 23 以上的版本,不过也够用了,已经覆盖 90%的机型了,低于 23 的依然判断是否连接就够用了。

方法列表

  1. isNetworkConnection :通过socket检查外网的连通性,需要在子线程执行
  2. ping :判断是否有外网连接
  3. ping2 :获取当前的网络状态,子线程执行
  4. openSetting :打开设置界面,requestCode 默认值 RESULT_SETTING
  5. openWiFiSetting :打开网络设置界面,requestCode 默认值 RESULT_WIFI
  6. isMobile :判断是否是移动网络
  7. isMobileConnected :判断是否是移动网络
  8. isWifi :判断是否是wifi连接
  9. isWifiConnected :判断是否是wifi连接
  10. getNetworkInfoType :获得当前的网络信息,返回值 WIFI ,MOBILE
  11. getConnectedType :获得当前的网络信息,,type = 1 WIFI,type = 0 MOBILE
  12. isNetworkConnected :判断是否有网络连接,不能判断网络是否可用
  13. isNetworkAvailable :判断当前网络是否可用,实时
  14. isNetworkAvailableAsync :判断当前网络是否可用,子线程执行

工具类

需要权限,在清单文件中加上:

  1. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  2. <uses-permission android:name="android.permission.INTERNET"/>
  1. object NetworkUtils {
  2. private var s: Socket? = null
  3. /**
  4. * 打开 wifi 设置界面 requestCode
  5. */
  6. const val RESULT_WIFI = 9999
  7. /**
  8. * 打开设置界面 requestCode
  9. */
  10. const val RESULT_SETTING = 99999
  11. /**
  12. *通过socket检查外网的连通性,需要在子线程执行
  13. * @param context
  14. * @return
  15. */
  16. fun isNetworkConnection(context: Context): Boolean {
  17. val connectivityManager =
  18. context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  19. val activeNetworkInfo = connectivityManager.activeNetworkInfo
  20. val connected = null != activeNetworkInfo && activeNetworkInfo.isConnected
  21. if (!connected) return false
  22. var routeExists: Boolean
  23. try {
  24. if (s == null) {
  25. s = Socket()
  26. }
  27. val host: InetAddress =
  28. InetAddress.getByName("114.114.114.114") //国内使用114.114.114.114,如果全球通用google:8.8.8.8
  29. s!!.connect(InetSocketAddress(host, 80), 5000) //google:53
  30. routeExists = true
  31. s!!.close()
  32. } catch (e: IOException) {
  33. routeExists = false
  34. }
  35. return connected && routeExists
  36. }
  37. /**判断是否有外网连接(普通方法不能判断外网的网络是否连接,比如连接上局域网)
  38. * 获取当前的网络状态,子线程执行
  39. * @return
  40. * @author suncat
  41. * @category
  42. */
  43. fun ping(): Boolean {
  44. var result: String? = null
  45. try {
  46. val ip = "www.baidu.com" // ping 的地址,可以换成任何一种可靠的外网
  47. val p = Runtime.getRuntime().exec("ping -c 3 -w 100 $ip") // ping网址3次
  48. // 读取ping的内容,可以不加
  49. val input: InputStream = p.inputStream
  50. val `in` = BufferedReader(InputStreamReader(input))
  51. val sb = StringBuilder()
  52. var content: String? = ""
  53. while (`in`.readLine().also { content = it } != null) {
  54. sb.append(content)
  55. }
  56. // ping的状态
  57. val status = p.waitFor()
  58. if (status == 0) {
  59. result = "success"
  60. return true
  61. } else {
  62. result = "failed"
  63. }
  64. } catch (e: IOException) {
  65. result = "IOException"
  66. } catch (e: InterruptedException) {
  67. result = "InterruptedException"
  68. } finally {
  69. }
  70. return false
  71. }
  72. /**
  73. * 获取当前的网络状态,子线程执行
  74. * 0:当前网络可用
  75. * 1:需要网页认证的wifi
  76. * 2:网络不可用的状态
  77. * 1000:方法错误
  78. */
  79. fun ping2(): Int {
  80. val runtime = Runtime.getRuntime()
  81. try {
  82. val p = runtime.exec("ping -c 3 www.baidu.com")
  83. return p.waitFor()
  84. } catch (e: Exception) {
  85. e.printStackTrace()
  86. }
  87. return 1
  88. }
  89. /**
  90. * 打开网络设置界面
  91. */
  92. fun openWiFiSetting(activity: Activity?, requestCode: Int = RESULT_WIFI) {
  93. val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
  94. activity?.startActivityForResult(intent, requestCode)
  95. }
  96. /**
  97. * 打开设置界面
  98. */
  99. fun openSetting(activity: Activity?, requestCode: Int = RESULT_SETTING) {
  100. val intent = Intent(Settings.ACTION_SETTINGS)
  101. activity?.startActivityForResult(intent, requestCode)
  102. }
  103. /**判断是否是移动网络
  104. * @param context
  105. * @return
  106. */
  107. fun isMobile(context: Context?): Boolean {
  108. if (context == null) return false
  109. val connectivity =
  110. context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  111. if (connectivity.activeNetworkInfo == null) return false
  112. return connectivity.activeNetworkInfo.type == ConnectivityManager.TYPE_MOBILE
  113. }
  114. /**
  115. * 判断是否是wifi连接
  116. */
  117. fun isWifi(context: Context?): Boolean {
  118. if (context == null) return false
  119. val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  120. if (cm.activeNetworkInfo == null) return false
  121. return cm.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
  122. }
  123. /**
  124. * 判断MOBILE网络是否连接
  125. *
  126. * @param context
  127. * @return
  128. */
  129. fun isMobileConnected(context: Context?): Boolean {
  130. if (context != null) {
  131. val mConnectivityManager = context
  132. .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  133. val mMobileNetworkInfo =
  134. mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
  135. if (mMobileNetworkInfo != null) {
  136. return mMobileNetworkInfo.isAvailable
  137. }
  138. }
  139. return false
  140. }
  141. /**
  142. * 判断WIFI网络是否连接
  143. *
  144. * @param context
  145. * @return
  146. */
  147. fun isWifiConnected(context: Context?): Boolean {
  148. if (context != null) {
  149. val mConnectivityManager =
  150. context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  151. val mWiFiNetworkInfo =
  152. mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
  153. if (mWiFiNetworkInfo != null) {
  154. return mWiFiNetworkInfo.isAvailable
  155. }
  156. }
  157. return false
  158. }
  159. /**
  160. *获得当前的网络信息,返回值 WIFI ,MOBILE
  161. * @param context
  162. * @return
  163. */
  164. fun getNetworkInfoType(context: Context): String? {
  165. val connectivityManager =
  166. context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  167. val activeNetworkInfo = connectivityManager.activeNetworkInfo
  168. if (activeNetworkInfo != null) {
  169. if (activeNetworkInfo.isConnected) {
  170. //获得当前的网络信息
  171. return activeNetworkInfo.typeName
  172. }
  173. }
  174. return null
  175. }
  176. /**
  177. * 获取当前网络连接的类型信息,type = 1 WIFI,type = 0 MOBILE
  178. *
  179. * @param context
  180. * @return
  181. */
  182. fun getConnectedType(context: Context?): Int {
  183. if (context != null) {
  184. val mConnectivityManager = context
  185. .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  186. val mNetworkInfo = mConnectivityManager.activeNetworkInfo
  187. if (mNetworkInfo != null && mNetworkInfo.isAvailable) {
  188. return mNetworkInfo.type
  189. }
  190. }
  191. return -1
  192. }
  193. /**
  194. * 判断是否有网络连接,不能判断网络是否可用
  195. *
  196. * @param context
  197. * @return
  198. */
  199. fun isNetworkConnected(context: Context?): Boolean {
  200. if (context != null) {
  201. val mConnectivityManager = context
  202. .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  203. val mNetworkInfo = mConnectivityManager.activeNetworkInfo
  204. if (mNetworkInfo != null) {
  205. return mNetworkInfo.isAvailable
  206. }
  207. }
  208. return false
  209. }
  210. /**
  211. * 判断当前网络是否可用,实时
  212. * @param context
  213. * @return
  214. */
  215. fun isNetworkAvailable(context: Context?): Boolean {
  216. if (context == null) return false
  217. var isNetUsable = false
  218. val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  219. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  220. val networkCapabilities = manager.getNetworkCapabilities(manager.activeNetwork)
  221. if (networkCapabilities != null) {
  222. isNetUsable =
  223. networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
  224. }
  225. } else {
  226. isNetUsable = isNetworkConnected(context)
  227. }
  228. return isNetUsable
  229. }
  230. /**
  231. * 判断当前网络是否可用,子线程执行
  232. * @param context
  233. * @return
  234. */
  235. fun isNetworkAvailableAsync(context: Context?): Boolean {
  236. val isConnected = isNetworkConnected(context)
  237. return if (isConnected) {
  238. ping()
  239. } else {
  240. false
  241. }
  242. }
  243. }

参考

判断当前网络是否可用两种方法