需求:
- 獲取當前的網絡狀態與類型(WIFI、數據流量)
- 監聽網絡狀態真正變化
- 監聽網絡類型發生變化
業務場景:
- 用戶打開 App 時、使用過程中,出現無網絡時,顯示 Toast 提示。但當 wifi、數據流量 互相切換的過程中不要有提示。
- 下載功能支持檢測到用戶連接上 wifi 時開啟靜默下載,當換成 數據流量 時停止靜默下載。
需求分析:
獲取當前網絡狀態與類型
即提供兩個方法,用于獲取當前的網絡狀態、網絡類型。
監聽網絡狀態真正變化
網絡狀態真正變化,首先明確網絡狀態只有【有網】與【無網】,所以當 WIFI 和 數據流量 同時開啟的情況下,僅關閉一項,不會提示網絡狀態的變更。
監聽網絡類型發生變化
網絡類型發生變化,是指當前使用的網絡類型發生變化。舉個例子,WIFI、數據流量同時開啟,理論上當前網絡類型是 WIFI,所以當僅關閉 數據流量 時,不會提示網絡類型變更,但僅關閉 WIFI 時,會提示網絡類型變更為 數據流量。
這里還需要注意一點,有一個“系統默認網絡”的概念:系統通常首選不按流量計費的網絡而非按流量計費的網絡,首選網速較快的網絡而非網速較慢的網絡。
技術實現:
常見監聽網絡狀態有三種方式:
- 監聽廣播
- ConnectivityManager#registerDefaultNetworkCallback()
- ConnectivityManager#registerNetworkCallback()
下面逐一實現看效果:
監聽網絡狀態變化廣播
kotlin
復制代碼
class NetConnectReceiver: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Log.e("qingshan", "網絡狀態改變") context?.getSystemService(ConnectivityManager::class.java)?.allNetworkInfo?.filter { it.typeName == "MOBILE" || it.typeName == "WIFI" }?.forEach {networkInfo -> Log.e("qingshan", "${networkInfo?.typeName}, isConnect= ${networkInfo?.isConnected}") } } } //動態注冊廣播監聽 class CustomApplication: Application() { override fun onCreate() { super.onCreate() //這里模擬工具類場景:全局一個監聽,然后在工具類中分發。 registerReceiver(NetConnectReceiver(), IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) } }
效果:
- 數據流量、wifi 全關,冷啟動。收到兩次廣播,均表示【數據流量、wifi 】無連接。
kotlin
復制代碼
2023-11-10 14:21:58.081 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:21:58.082 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:21:58.082 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:21:58.083 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:21:58.083 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:21:58.083 13917-13917 qingshan E WIFI, isConnect= false
- 數據流量、wifi 全開,冷啟動。收到連續兩次廣播,均表示當前【WIFI】連接。
kotlin
復制代碼
2023-11-10 14:13:46.002 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:13:46.002 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:13:46.002 13917-13917 qingshan E WIFI, isConnect= true 2023-11-10 14:13:46.003 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:13:46.003 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:13:46.003 13917-13917 qingshan E WIFI, isConnect= true
- 數據流量、wifi 全開,僅關閉流量。無廣播。
- 數據流量、wifi 全開,僅關閉wifi(用于模擬斷開wifi 或 wifi網絡不佳時系統自動啟用數據流量)。收到多次廣播,有時表示先【數據流量、wifi 】無連接,然后又出現【數據流量】連接,有時均表示當前【數據流量】連接。
kotlin
復制代碼
2023-11-10 14:18:46.622 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:18:46.624 13917-13917 qingshan E MOBILE, isConnect= true 2023-11-10 14:18:46.624 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:18:46.624 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:18:46.624 13917-13917 qingshan E MOBILE, isConnect= true 2023-11-10 14:18:46.624 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:18:46.665 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:18:46.666 13917-13917 qingshan E MOBILE, isConnect= true 2023-11-10 14:18:46.666 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:18:46.666 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:18:46.666 13917-13917 qingshan E MOBILE, isConnect= true 2023-11-10 14:18:46.666 13917-13917 qingshan E WIFI, isConnect= false
有時日志如下:
kotlin
復制代碼
2023-11-10 14:25:03.460 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:25:03.461 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:25:03.461 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:25:03.461 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:25:03.462 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:25:03.462 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:25:03.527 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:25:03.528 13917-13917 qingshan E MOBILE, isConnect= true 2023-11-10 14:25:03.528 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:25:03.528 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:25:03.528 13917-13917 qingshan E MOBILE, isConnect= true 2023-11-10 14:25:03.528 13917-13917 qingshan E WIFI, isConnect= false
- 數據流量、wifi 全關。收到兩次廣播,均表示【數據流量、wifi 】無連接。
注意:先關 wifi 再關數據時,先打印上面(“數據流量、wifi 全開,僅關閉wifi”場景)日志,再打印下面日志。
kotlin
復制代碼
2023-11-10 14:21:58.081 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:21:58.082 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:21:58.082 13917-13917 qingshan E WIFI, isConnect= false 2023-11-10 14:21:58.083 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:21:58.083 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:21:58.083 13917-13917 qingshan E WIFI, isConnect= false
- 僅開數據流量,再開 wifi(用于模擬使用過程中自動連接上wifi)。收到多次廣播,均表示【wifi】連接。
kotlin
復制代碼
2023-11-10 14:31:21.285 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:31:21.286 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:31:21.286 13917-13917 qingshan E WIFI, isConnect= true 2023-11-10 14:31:21.287 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:31:21.287 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:31:21.287 13917-13917 qingshan E WIFI, isConnect= true 2023-11-10 14:31:21.317 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:31:21.319 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:31:21.319 13917-13917 qingshan E WIFI, isConnect= true 2023-11-10 14:31:21.319 13917-13917 qingshan E 網絡狀態改變 2023-11-10 14:31:21.320 13917-13917 qingshan E MOBILE, isConnect= false 2023-11-10 14:31:21.320 13917-13917 qingshan E WIFI, isConnect= true
ConnectivityManager#registerDefaultNetworkCallback()
要求 android sdk >=24 用于監聽“系統默認網絡”發生變更。 請勿在回調中調用 ConnectivityManager 的同步方法來查找新可用網絡的屬性,因為這會受到競態條件的影響。例如:在 onLost() 回調中調用 connectivityManager.getNetworkCapabilities()。
kotlin
復制代碼
class CustomApplication: Application() { override fun onCreate() { super.onCreate() //這里模擬工具類場景:全局一個監聽,然后在工具類中分發。 getSystemService(ConnectivityManager::class.java).apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { registerDefaultNetworkCallback(object : NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) Log.e("qingshan", "def -> onAvailable") } override fun onLost(network: Network) { super.onLost(network) Log.e("qingshan", "def -> onLost") } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) Log.e("qingshan", "def -> 可正常訪問網絡 = ${networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)} " + "& 數據連接 = ${networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)} " + "& wifi連接= ${networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)}") } }) } } } }
效果
- 數據流量、wifi 全關,冷啟動。無回調觸發。
- 數據流量、wifi 全開,冷啟動。觸發 onAvailable() 和 onCapabilitiesChanged() 回調。表示當前【WIFI】連接。
kotlin
復制代碼
2023-11-10 15:22:31.427 8342-12273 qingshan E def -> onAvailable 2023-11-10 15:22:31.427 8342-12273 qingshan E def -> 可正常訪問網絡 = true & 數據連接 = false & wifi連接= true
- 數據流量、wifi 全開,僅關閉流量。無回調觸發。
- 數據流量、wifi 全開,僅關閉wifi(用于模擬斷開wifi 或 wifi網絡不佳時系統自動啟用數據流量)。觸發一次 onLost() 和 onAvailable() 回調,觸發多次 onCapabilitiesChanged() 回調。表示當前【數據流量】連接。
kotlin
復制代碼
2023-11-10 15:30:26.103 8342-12273 qingshan E def -> onLost 2023-11-10 15:30:26.150 8342-12273 qingshan E def -> onAvailable 2023-11-10 15:30:26.151 8342-12273 qingshan E def -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false
- 數據流量、wifi 全關。數據流量和 wifi 誰先關閉觸發的回調不同,wifi 先關會觸發兩次 onLost() 回調。有時表示【數據流量、wifi】無連接,有時先表示【wifi】無連接,切換為【數據流量】連接,再表示【數據流量、wifi】無連接。
注意:先關 wifi 再關數據時,先打印上面(“數據流量、wifi 全開,僅關閉wifi”場景)日志,再打印下面日志。
kotlin
復制代碼
2023-11-10 15:35:42.923 8342-12273 qingshan E def -> onLost
- 僅開數據流量,再開 wifi(用于模擬使用過程中自動連接上wifi)。觸發一次 onAvailable() 回調,觸發多次 onCapabilitiesChanged() 回調。表示當前【wifi】連接,但有時會有不同的網絡狀態。
kotlin
復制代碼
2023-11-10 15:33:05.596 8342-12273 qingshan E def -> onAvailable 2023-11-10 15:33:05.596 8342-12273 qingshan E def -> 可正常訪問網絡 = true & 數據連接 = false & wifi連接= true
有時日志如下:
kotlin
復制代碼
2023-11-10 15:39:22.644 8342-12273 qingshan E def -> onAvailable 2023-11-10 15:39:22.645 8342-12273 qingshan E def -> 可正常訪問網絡 = false & 數據連接 = true & wifi連接= false 2023-11-10 15:39:22.842 8342-12273 qingshan E def -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false
ConnectivityManager#registerNetworkCallback()
用于監聽所有網絡發生變更。 請勿在回調中調用 ConnectivityManager 的同步方法來查找新可用網絡的屬性,因為這會受到競態條件的影響。例如:在 onLost() 回調中調用 connectivityManager.getNetworkCapabilities()。
kotlin
復制代碼
class CustomApplication: Application() { override fun onCreate() { super.onCreate() //這里模擬工具類場景:全局一個監聽,然后在工具類中分發。 getSystemService(ConnectivityManager::class.java).apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { registerNetworkCallback(NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) .build(), object : NetworkCallback(){ override fun onAvailable(network: Network) { super.onAvailable(network) Log.e("qingshan", "all -> onAvailable") } override fun onLost(network: Network) { super.onLost(network) Log.e("qingshan", "all -> onLost") } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) Log.e("qingshan", "all -> 可正常訪問網絡 = ${networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)} " + "& 數據連接 = ${networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)} " + "& wifi連接= ${networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)}") } }) } } } }
效果
- 數據流量、wifi 全關,冷啟動。無回調觸發。
- 數據流量、wifi 全開,冷啟動。觸發兩次 onAvailable() 和 onCapabilitiesChanged() 回調,表示當前【數據流量、wifi】均連接。
kotlin
復制代碼
2023-11-10 17:24:37.153 10713-6397 qingshan E all -> onAvailable 2023-11-10 17:24:37.153 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = false & wifi連接= true 2023-11-10 17:24:37.155 10713-6397 qingshan E all -> onAvailable 2023-11-10 17:24:37.155 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false
- 數據流量、wifi 全開,僅關閉流量。觸發一次 onLost() 回調,表示當前有網絡關閉,具體是什么不知道。
kotlin
復制代碼
2023-11-10 17:26:28.243 10713-6397 qingshan E all -> onLost
- 數據流量、wifi 全開,僅關閉wifi(用于模擬斷開wifi 或 wifi網絡不佳時系統自動啟用數據流量)。觸發一次 onLoast() 回調,表示當前有網絡關閉。因為關閉的是“系統默認網絡”,所以會觸發多次 onCapabilitiesChanged() 回調,表示當前變成【數據流量】連接。
kotlin
復制代碼
2023-11-10 17:30:43.302 10713-6397 qingshan E all -> onLost 2023-11-10 17:30:45.464 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false
- 數據流量、wifi 全關。觸發兩次 onLost() 回調,但先 wifi 時會在兩次 onLost() 中間觸發一次 onCapabilitiesChanged() 回調。表示當前網絡逐個不可用。
先關wifi,再關數據流量,日志如下:
kotlin
復制代碼
2023-11-10 17:36:19.335 10713-6397 qingshan E all -> onLost 2023-11-10 17:36:19.475 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false 2023-11-10 17:36:20.802 10713-6397 qingshan E all -> onLost
先關數據流量,再關wifi,日志如下:
kotlin
復制代碼
2023-11-10 17:37:20.487 10713-6397 qingshan E all -> onLost 2023-11-10 17:37:22.176 10713-6397 qingshan E all -> onLost
- 僅開數據流量,再開 wifi(用于模擬使用過程中自動連接上wifi)。會觸發一次 onAvailable(),觸發多次 onCapabilitiesChanged() 回調。表示當前【wifi】已連接(但不意味著正在使用的是 wifi,具體正在使用的網絡類型由系統決定,即系統默認網絡)。
kotlin
復制代碼
2023-11-10 17:33:42.284 10713-6397 qingshan E all -> onAvailable 2023-11-10 17:33:42.284 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = false & wifi連接= true
- 僅開wifi,再開數據流量。會觸發一次 onAvailable(),觸發多次 onCapabilitiesChanged() 回調。表示當前【數據流量】已連接(但不意味著正在使用的是數據流量,具體正在使用的網絡類型由系統決定,即系統默認網絡)。
kotlin
復制代碼
2023-11-10 17:27:49.875 10713-6397 qingshan E all -> onAvailable 2023-11-10 17:27:49.876 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false 2023-11-10 17:27:49.878 10713-6397 qingshan E all -> 可正常訪問網絡 = true & 數據連接 = true & wifi連接= false
總結
根據上面的實際運行效果可以得知:
- ConnectivityManager#registerNetworkCallback() 是監聽所有網絡變換的,監聽范圍廣,但無法得知當前“系統默認網絡”是什么,可以實現判斷網絡狀態,但無法判斷網絡類型。
- 廣播監聽 與 ConnectivityManager#registerDefaultNetworkCallback() 都是監聽“系統默認網絡”,所以可以實現網絡狀態與類型的判斷,但都存在重復回調的情況,所以要做過濾處理,以及“系統默認網絡”切換到普通網絡時會有偶現短暫“無網絡”狀態,需要做延遲處理。
- 廣播監聽所使用的方式有標記為“廢棄”,同時 ConnectivityManager#registerDefaultNetworkCallback() 也有版本的限制,所以可以兩者結合使用,優先使用 egisterDefaultNetworkCallback(),廣播監聽用于兜底。
所以,綜合上述,得出如下工具類實現:
kotlin
復制代碼
import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.os.Build import android.os.Handler import android.os.Looper sealed class ConnectType(val value: Int) { object Mobile : ConnectType(0) object Wifi : ConnectType(1) object None : ConnectType(-1) companion object { fun convert2Type(value: Int): ConnectType { return when (value) { Mobile.value -> Mobile Wifi.value -> Wifi else -> None } } } } object NetConnectManager { private var mConnectivityManager: ConnectivityManager? = null private val mainHandler = Handler(Looper.getMainLooper()) private val mNetTypeListener = mutableListOf<(type: ConnectType) -> Unit>() private val mNetStateListener = mutableListOf<(isAvailable: Boolean) -> Unit>() private var mCurrentConnectType: ConnectType? = null private var mIsNetAvailable: Boolean? = null /** * 初始化 */ fun init(context: Context) { mConnectivityManager = context.getSystemService(ConnectivityManager::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mConnectivityManager?.registerDefaultNetworkCallback(DefaultNetConnectCallback()) } else { context.registerReceiver( NetConnectReceiver(), IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) ) } } /** * 注冊網絡類型監聽 */ fun addNetTypeChangeListener(listener: (type: ConnectType) -> Unit) { mNetTypeListener.add(listener) } /** * 反注冊網絡類型監聽 */ fun removeNetTypeChangeListener(listener: (type: ConnectType) -> Unit) { mNetTypeListener.remove(listener) } /** * 注冊網絡狀態監聽 */ fun addNetStatusChangeListener(listener: (isAvailable: Boolean) -> Unit) { mNetStateListener.add(listener) } /** * 反注冊網絡狀態監聽 */ fun removeNetStatusChangeListener(listener: (isAvailable: Boolean) -> Unit) { mNetStateListener.remove(listener) } /** * 獲取當前網絡類型 */ fun getConnectType(): ConnectType { if (mConnectivityManager == null) { throw UninitializedPropertyAccessException("請先調用init()初始化") } return mCurrentConnectType ?: mConnectivityManager?.getNetworkCapabilities( mConnectivityManager?.activeNetwork ).let { return if (it?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true) { ConnectType.Mobile } else if (it?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true) { ConnectType.Wifi } else { ConnectType.None } } } /** * 獲取當前是否網絡已連接 */ fun isConnected(): Boolean { if (mConnectivityManager == null) { throw UninitializedPropertyAccessException("請先調用init()初始化") } return (mIsNetAvailable ?: mConnectivityManager?.getNetworkCapabilities(mConnectivityManager?.activeNetwork) ?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) == true } private class DefaultNetConnectCallback : ConnectivityManager.NetworkCallback() { override fun onLost(network: Network) { super.onLost(network) mCurrentConnectType = ConnectType.None mainHandler.postDelayed({ if (mCurrentConnectType == ConnectType.None && mIsNetAvailable == true) { mIsNetAvailable = false mNetStateListener.forEach { it.invoke(false) } mNetTypeListener.forEach { it(ConnectType.None) } } }, 500) } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) mainHandler.post { val isConnected = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) val isCellular = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) val isWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) if (isConnected) { val newConnectType = if (isCellular) ConnectType.Mobile else if (isWifi) ConnectType.Wifi else ConnectType.None if (mIsNetAvailable == null || mIsNetAvailable == false) { mIsNetAvailable = true mNetStateListener.forEach { it(true) } } if (mCurrentConnectType != newConnectType) { mCurrentConnectType = newConnectType mNetTypeListener.forEach { it(newConnectType) } } } } } } private class NetConnectReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val activityNetworkInfo = context?.getSystemService(ConnectivityManager::class.java)?.allNetworkInfo?.filter { (it.type == ConnectType.Mobile.value || it.type == ConnectType.Wifi.value) && it.isConnected }?.firstOrNull() if (activityNetworkInfo != null) { if (mIsNetAvailable == null || mIsNetAvailable == false) { mIsNetAvailable = true mNetStateListener.forEach { it(true) } } ConnectType.convert2Type(activityNetworkInfo.type).let { connectType -> if (connectType != mCurrentConnectType) { mCurrentConnectType = connectType mNetTypeListener.forEach { it(connectType) } } } return } mCurrentConnectType = ConnectType.None mainHandler.postDelayed({ if (mCurrentConnectType == ConnectType.None && mIsNetAvailable == true) { mIsNetAvailable = false mNetStateListener.forEach { it(false) } mNetTypeListener.forEach { it(ConnectType.None) } } }, 500) } } }
效果:
測試代碼:
kotlin
復制代碼
class MainActivity : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.e("qingshan", "網絡是否連接= ${NetConnectManager.isConnected()} & 網絡類型= ${NetConnectManager.getConnectType()}") NetConnectManager.addNetTypeChangeListener { Log.e("qingshan", "網絡類型[監聽]= $it") } NetConnectManager.addNetStatusChangeListener { Log.e("qingshan", "網絡是否已連接[監聽]= $it") } } }
- 數據流量、wifi 全關,冷啟動。
kotlin
復制代碼
qingshan E 網絡是否連接= false & 網絡類型= com.stefan.simpleskin.ConnectType$None@6f21c25
- 數據流量、wifi 全開,冷啟動。
kotlin
復制代碼
qingshan E 網絡是否連接= true & 網絡類型= com.stefan.simpleskin.ConnectType$Wifi@34771fa qingshan E 網絡類型[監聽]= com.stefan.simpleskin.ConnectType$Wifi@34771fa
- 數據流量、wifi 全開,僅關閉流量。 無監聽回調。
- 數據流量、wifi 全開,僅關閉wifi(用于模擬斷開wifi 或 wifi網絡不佳時系統自動啟用數據流量)。
kotlin
復制代碼
qingshan E 網絡類型[監聽]= com.stefan.simpleskin.ConnectType$Mobile@cf38ed1
- 數據流量、wifi 全關。
kotlin
復制代碼
qingshan E 網絡是否已連接[監聽]= false qingshan E 網絡類型[監聽]= com.stefan.simpleskin.ConnectType$None@fddad36
- 僅開數據流量,再開 wifi(用于模擬使用過程中自動連接上wifi)。
kotlin
復制代碼
qingshan E 網絡類型[監聽]= com.stefan.simpleskin.ConnectType$Wifi@34771fa
- 僅開wifi,再開數據流量。無監聽回調。