前言
查了一下判斷網(wǎng)絡(luò)是否可用,發(fā)現(xiàn)很多博客給的方法都是不正確的,大部分給的方法都是判斷網(wǎng)絡(luò)是否連接,一般來說,在大多數(shù)的情況下確實(shí)可以滿足需求。但是有時(shí)會(huì)出現(xiàn)網(wǎng)絡(luò)連接了卻不能用的情況,這時(shí)就需要更精準(zhǔn)的判斷了。網(wǎng)上查到的有效的方法大多都是異步的,后來終于找到了一個(gè)不用異步的方法,只支持安卓 23 以上的版本,不過也夠用了,已經(jīng)覆蓋 90%的機(jī)型了,低于 23 的依然判斷是否連接就夠用了。
方法列表
isNetworkConnection :通過socket檢查外網(wǎng)的連通性,需要在子線程執(zhí)行
ping :判斷是否有外網(wǎng)連接
ping2 :獲取當(dāng)前的網(wǎng)絡(luò)狀態(tài),子線程執(zhí)行
openSetting :打開設(shè)置界面,requestCode 默認(rèn)值 RESULT_SETTING
openWiFiSetting :打開網(wǎng)絡(luò)設(shè)置界面,requestCode 默認(rèn)值 RESULT_WIFI
isMobile :判斷是否是移動(dòng)網(wǎng)絡(luò)
isMobileConnected :判斷是否是移動(dòng)網(wǎng)絡(luò)
isWifi :判斷是否是wifi連接
isWifiConnected :判斷是否是wifi連接
getNetworkInfoType :獲得當(dāng)前的網(wǎng)絡(luò)信息,返回值 WIFI ,MOBILE
getConnectedType :獲得當(dāng)前的網(wǎng)絡(luò)信息,,type = 1 WIFI,type = 0 MOBILE
isNetworkConnected :判斷是否有網(wǎng)絡(luò)連接,不能判斷網(wǎng)絡(luò)是否可用
isNetworkAvailable :判斷當(dāng)前網(wǎng)絡(luò)是否可用,實(shí)時(shí)
isNetworkAvailableAsync :判斷當(dāng)前網(wǎng)絡(luò)是否可用,子線程執(zhí)行
工具類
需要權(quán)限,在清單文件中加上:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
object NetworkUtils {
private var s: Socket? = null
/**
* 打開 wifi 設(shè)置界面 requestCode
*/
const val RESULT_WIFI = 9999
/**
* 打開設(shè)置界面 requestCode
*/
const val RESULT_SETTING = 99999
/**
*通過socket檢查外網(wǎng)的連通性,需要在子線程執(zhí)行
* @param context
* @return
*/
fun isNetworkConnection(context: Context): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
val connected = null != activeNetworkInfo && activeNetworkInfo.isConnected
if (!connected) return false
var routeExists: Boolean
try {
if (s == null) {
s = Socket()
}
val host: InetAddress =
InetAddress.getByName("114.114.114.114") //國(guó)內(nèi)使用114.114.114.114,如果全球通用google:8.8.8.8
s!!.connect(InetSocketAddress(host, 80), 5000) //google:53
routeExists = true
s!!.close()
} catch (e: IOException) {
routeExists = false
}
return connected && routeExists
}
/**判斷是否有外網(wǎng)連接(普通方法不能判斷外網(wǎng)的網(wǎng)絡(luò)是否連接,比如連接上局域網(wǎng))
* 獲取當(dāng)前的網(wǎng)絡(luò)狀態(tài),子線程執(zhí)行
* @return
* @author suncat
* @category
*/
fun ping(): Boolean {
var result: String? = null
try {
val ip = "www.baidu.com" // ping 的地址,可以換成任何一種可靠的外網(wǎng)
val p = Runtime.getRuntime().exec("ping -c 3 -w 100 $ip") // ping網(wǎng)址3次
// 讀取ping的內(nèi)容,可以不加
val input: InputStream = p.inputStream
val `in` = BufferedReader(InputStreamReader(input))
val sb = StringBuilder()
var content: String? = ""
while (`in`.readLine().also { content = it } != null) {
sb.append(content)
}
// ping的狀態(tài)
val status = p.waitFor()
if (status == 0) {
result = "success"
return true
} else {
result = "failed"
}
} catch (e: IOException) {
result = "IOException"
} catch (e: InterruptedException) {
result = "InterruptedException"
} finally {
}
return false
}
/**
* 獲取當(dāng)前的網(wǎng)絡(luò)狀態(tài),子線程執(zhí)行
* 0:當(dāng)前網(wǎng)絡(luò)可用
* 1:需要網(wǎng)頁(yè)認(rèn)證的wifi
* 2:網(wǎng)絡(luò)不可用的狀態(tài)
* 1000:方法錯(cuò)誤
*/
fun ping2(): Int {
val runtime = Runtime.getRuntime()
try {
val p = runtime.exec("ping -c 3 www.baidu.com")
return p.waitFor()
} catch (e: Exception) {
e.printStackTrace()
}
return 1
}
/**
* 打開網(wǎng)絡(luò)設(shè)置界面
*/
fun openWiFiSetting(activity: Activity?, requestCode: Int = RESULT_WIFI) {
val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
activity?.startActivityForResult(intent, requestCode)
}
/**
* 打開設(shè)置界面
*/
fun openSetting(activity: Activity?, requestCode: Int = RESULT_SETTING) {
val intent = Intent(Settings.ACTION_SETTINGS)
activity?.startActivityForResult(intent, requestCode)
}
/**判斷是否是移動(dòng)網(wǎng)絡(luò)
* @param context
* @return
*/
fun isMobile(context: Context?): Boolean {
if (context == null) return false
val connectivity =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (connectivity.activeNetworkInfo == null) return false
return connectivity.activeNetworkInfo.type == ConnectivityManager.TYPE_MOBILE
}
/**
* 判斷是否是wifi連接
*/
fun isWifi(context: Context?): Boolean {
if (context == null) return false
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (cm.activeNetworkInfo == null) return false
return cm.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
}
/**
* 判斷MOBILE網(wǎng)絡(luò)是否連接
*
* @param context
* @return
*/
fun isMobileConnected(context: Context?): Boolean {
if (context != null) {
val mConnectivityManager = context
.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val mMobileNetworkInfo =
mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
if (mMobileNetworkInfo != null) {
return mMobileNetworkInfo.isAvailable
}
}
return false
}
/**
* 判斷WIFI網(wǎng)絡(luò)是否連接
*
* @param context
* @return
*/
fun isWifiConnected(context: Context?): Boolean {
if (context != null) {
val mConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val mWiFiNetworkInfo =
mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
if (mWiFiNetworkInfo != null) {
return mWiFiNetworkInfo.isAvailable
}
}
return false
}
/**
*獲得當(dāng)前的網(wǎng)絡(luò)信息,返回值 WIFI ,MOBILE
* @param context
* @return
*/
fun getNetworkInfoType(context: Context): String? {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
if (activeNetworkInfo != null) {
if (activeNetworkInfo.isConnected) {
//獲得當(dāng)前的網(wǎng)絡(luò)信息
return activeNetworkInfo.typeName
}
}
return null
}
/**
* 獲取當(dāng)前網(wǎng)絡(luò)連接的類型信息,type = 1 WIFI,type = 0 MOBILE
*
* @param context
* @return
*/
fun getConnectedType(context: Context?): Int {
if (context != null) {
val mConnectivityManager = context
.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val mNetworkInfo = mConnectivityManager.activeNetworkInfo
if (mNetworkInfo != null && mNetworkInfo.isAvailable) {
return mNetworkInfo.type
}
}
return -1
}
/**
* 判斷是否有網(wǎng)絡(luò)連接,不能判斷網(wǎng)絡(luò)是否可用
*
* @param context
* @return
*/
fun isNetworkConnected(context: Context?): Boolean {
if (context != null) {
val mConnectivityManager = context
.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val mNetworkInfo = mConnectivityManager.activeNetworkInfo
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable
}
}
return false
}
/**
* 判斷當(dāng)前網(wǎng)絡(luò)是否可用,實(shí)時(shí)
* @param context
* @return
*/
fun isNetworkAvailable(context: Context?): Boolean {
if (context == null) return false
var isNetUsable = false
val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = manager.getNetworkCapabilities(manager.activeNetwork)
if (networkCapabilities != null) {
isNetUsable =
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
} else {
isNetUsable = isNetworkConnected(context)
}
return isNetUsable
}
/**
* 判斷當(dāng)前網(wǎng)絡(luò)是否可用,子線程執(zhí)行
* @param context
* @return
*/
fun isNetworkAvailableAsync(context: Context?): Boolean {
val isConnected = isNetworkConnected(context)
return if (isConnected) {
ping()
} else {
false
}
}
}