illustrate
Android Android monitors network status changes. In applications, we generally need to monitor changes in device network status and make corresponding business processing. We need a convenient and global monitoring implementation. .
Use different API methods for different device system versions;
Pay attention to the adaptation problem of using broadcast to monitor network status in higher versions;
1. Build.VERSION.SDK_INT >= Build.VERSION_CODES.N, use the connectivityManager.registerDefaultNetworkCallback() method;
2. Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP, use connectivityManager.registerNetworkCallback(networkRequest, new MyNetworkCallback()); method;
3. Other system versions use broadcast monitoring;
4. NetworkListenerHelper can add multiple page listeners. When a page needs to monitor the network, it can be added to the listener collection. The listener can be removed when the page is closed. You can also use the event bus;
Core implementation
NetworkListenerHelper
package com.let.networkstatusmonitor import android.annotation.SuppressLint import android.content.Context import android.content.IntentFilter import android.net.ConnectivityManager import android.net.ConnectivityManager.NetworkCallback import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest import android.os.Build import com.let.networkstatusmonitor.NetworkBroadcastReceiver.NetworkBroadcastCallback import com.let.networkstatusmonitor.NetworkUtils.getNetWorkState import java.util.concurrent.CopyOnWriteArrayList /** * @Author: let * @date: 2022/11/15 17:29 * @description: The monitoring class for network status changes. According to different versions of Android systems, there are two implementation methods: [ConnectivityManager.registerNetworkCallback] and registration broadcast; */ object NetworkListenerHelper { private val TAG = "NetworkListenerHelper" private var mContext: Context? = null @Volatile private var mListenerList: CopyOnWriteArrayList<NetworkConnectedListener>? = null /** * Register for monitoring network status; */ @SuppressLint("MissingPermission") fun registerNetworkListener() { when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> { val connectivityManager = mContext!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager if (connectivityManager == null) { LogUtils.el( TAG, "registerNetworkListener#return#connectivityManager=$connectivityManager" ) return } connectivityManager.registerDefaultNetworkCallback(MyNetworkCallback()) } Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> { val connectivityManager = mContext .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager if (connectivityManager == null) { LogUtils.el( TAG, "registerNetworkListener#return#connectivityManager=$connectivityManager" ) return } val builder: NetworkRequest.Builder builder = NetworkRequest.Builder() builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) val networkRequest = builder.build() connectivityManager.registerNetworkCallback(networkRequest, MyNetworkCallback()) } else -> { // Monitor the network through broadcast; val mNetworkBroadcastReceiver = NetworkBroadcastReceiver() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) mContext!!.registerReceiver(mNetworkBroadcastReceiver, filter) mNetworkBroadcastReceiver.setBroadcastCallback(object : NetworkBroadcastCallback { override fun onNetworkBroadcastCallback( isConnected: Boolean, networkStatus: NetworkStatus? ) { // notifyAllListeners(isConnected, networkStatus!!) } }) } } } /** * Notify all recipients; * * @param isConnected * @param networkStatus */ private fun notifyAllListeners( isConnected: Boolean, networkStatus: NetworkStatus ) { if (CollectionUtils.isNotEmpty(mListenerList)) { // mListenerList.stream().forEach(networkConnectedListener -> { // networkConnectedListener.onNetworkConnected(isConnected, networdStatus); // }); for (listener in mListenerList!!) { listener?.onNetworkConnected(isConnected, networkStatus) } } } /** * Add a callback listener; */ @Synchronized fun addListener(listener: NetworkConnectedListener?) { if (listener == null) { return } if (mListenerList == null) { mListenerList = CopyOnWriteArrayList() } // Prevent duplicate addition; if (!mListenerList!!.contains(listener)) { mListenerList!!.add(listener) } } /** * Remove a callback instance; * * @param listener */ @Synchronized fun removeListener(listener: NetworkConnectedListener?) { if (listener != null & amp; & amp; CollectionUtils.isNotEmpty(mListenerList)) { mListenerList!!.remove(listener) } } fun unregisterNetworkCallback() { if (mContext == null) { return } val connectivityManager = mContext .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager if (connectivityManager == null) { LogUtils.el( TAG, "registerNetworkListener#return#connectivityManager=$connectivityManager" ) return } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { connectivityManager.unregisterNetworkCallback(NetworkCallback()) } } interface NetworkConnectedListener { /** * @param isConnected * @param networkStatus */ fun onNetworkConnected( isConnected: Boolean, networkStatus: NetworkStatus? ) } @SuppressLint("NewApi") My private class MyNetworkCallback : NetworkCallback() { //Both functions serve as default callbacks when the user is connected (or disconnected) from a network (can be WiFi or cellular); override fun onAvailable(network: Network) { super.onAvailable(network) LogUtils.d(TAG, "onAvailable#network=$network") //Need to obtain network status synchronously; val netWorkState = getNetWorkState(mContext!!) LogUtils.d(TAG, "onAvailable#netWorkState=$netWorkState") // notifyAllListeners(true, netWorkState) } override fun onLost(network: Network) { super.onLost(network) LogUtils.d(TAG, "onLost#network=$network") //Need to obtain network status synchronously; val netWorkState = getNetWorkState(mContext!!) LogUtils.d(TAG, "onLost#netWorkState=$netWorkState") // notifyAllListeners(false, netWorkState) } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) LogUtils.d(TAG, "onCapabilitiesChanged#network=$network") // LogUtils.d(TAG, "onCapabilitiesChanged#network=" + network + ", networkCapabilities=" + networkCapabilities); // Indicates that it can communicate with the Internet (this is true to indicate that it can access the Internet) if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) { when { networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> { LogUtils.d(TAG, "onCapabilitiesChanged#The network type is wifi") } networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> { LogUtils.d(TAG, "onCapabilitiesChanged#Cellular Network") } else -> { LogUtils.d(TAG, "onCapabilitiesChanged#Other networks") } } } } } fun init(context: Context): NetworkListenerHelper { mContext = context return this } }
MainActivity
package com.let.networkstatusmonitor import android.os.Bundle import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import com.let.networkstatusmonitor.NetworkListenerHelper.NetworkConnectedListener /** * @Author: let * @date: 2021/11/15 17:29 * @description: */ class MainActivity : AppCompatActivity(), NetworkConnectedListener { private val TAG = "MainActivity" private var mTvResult: TextView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mTvResult = findViewById(R.id.tv_result) //Network status callback; NetworkListenerHelper.addListener(this@MainActivity) } override fun onDestroy() { super.onDestroy() NetworkListenerHelper.removeListener(this@MainActivity) } override fun onNetworkConnected(isConnected: Boolean, networkStatus: NetworkStatus?) { LogUtils.d(TAG, "onNetworkConnected#isConnected=$isConnected") val trim = mTvResult!!.text.toString() val status = networkStatus.status val desc = networkStatus.desc mTvResult!!.post { mTvResult!!.text = "\\ Network change notification: status=$status, desc=$desc\\ $trim" } } }
NetworkStatus
package com.let.networkstatusmonitor; /** * @Author: let * @date: 2022/11/15 17:30 * @description: Enumeration of network connection status */ public enum NetworkStatus { /** *; */ NONE(-1, "No network connection"), /** * Failed to parse data content */ MOBILE(0, "Mobile network connection"), /** * Internet problem */ WIFI(1, "WIFI connection"); private int status; private String desc; NetworkStatus(int code, String msg) { this.status = code; this.desc = msg; } public int getStatus() { return status; } public String getDesc() { return desc; } @Override public String toString() { return "NetwordStatus{" + "status=" + status + ", desc='" + desc + '\'' + "} " + super.toString(); } }
NetworkUtils
package com.let.networkstatusmonitor import android.annotation.SuppressLint import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.os.Build /** * @Author: let * @date: 2022/11/15 17:31 * @description: */ object NetworkUtils { @JvmStatic @SuppressLint("MissingPermission") fun getNetWorkState(context: Context): NetworkStatus { return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val mobileNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) val wifiNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) if (mobileNetInfo != null & amp; & amp; mobileNetInfo.isAvailable) { //WIFI and mobile network are not connected NetworkStatus.MOBILE } else if (wifiNetInfo != null & amp; & amp; wifiNetInfo.isAvailable) { //WIFI and mobile network are not connected NetworkStatus.WIFI } else { NetworkStatus.NONE } } else { when { isMobileConnected(context) -> { NetworkStatus.MOBILE } isWifiConnected(context) -> { NetworkStatus.WIFI } else -> { NetworkStatus.NONE } } } // //Get information about all network connections // Network[] networks = connMgr.getAllNetworks(); // //Get network information one by one through loop // for (int i = 0; i < networks.length; i + + ) { // //Get the NetworkInfo object corresponding to the ConnectivityManager object // NetworkInfo networkInfo = connMgr.getNetworkInfo(networks[i]); // if (networkInfo.isConnected()) { // if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { // return NetwordStatus.WIFI; // } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { // return NetwordStatus.MOBILE; // } // } // } } /** * Determine whether the network is connected * * @param context * @return */ @SuppressLint("MissingPermission") fun isOnline(context: Context?): Boolean { if (context == null) { return false } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkInfo = connMgr.activeNetworkInfo return networkInfo != null & amp; & amp; networkInfo.isAvailable } else { val connectivityManager = context .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork = connectivityManager.activeNetwork ?: return false val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) if (networkCapabilities != null) { return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) } } return false } @SuppressLint("MissingPermission") fun isWifiConnected(context: Context?): Boolean { if (context == null) { return false } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { val connectivityManager = context .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkInfo = connectivityManager .getNetworkInfo(ConnectivityManager.TYPE_WIFI) if (networkInfo != null) { return networkInfo.isAvailable } } else { val connectivityManager = context .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork = connectivityManager.activeNetwork ?: return false val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) if (networkCapabilities != null) { return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) } } return false } @SuppressLint("MissingPermission") fun isMobileConnected(context: Context?): Boolean { if (context == null) { return false } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { val connectivityManager = context .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkInfo = connectivityManager .getNetworkInfo(ConnectivityManager.TYPE_MOBILE) if (networkInfo != null) { return networkInfo.isAvailable } } else { val connectivityManager = context .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork = connectivityManager.activeNetwork ?: return false val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork) if (networkCapabilities != null) { return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) } } return false } }
NetworkBroadcastReceiver
package com.let.networkstatusmonitor import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.net.ConnectivityManager import android.text.TextUtils /** * @Author: let * @date: 2021/11/15 17:28 * @description: Monitoring broadcast of network status */ class NetworkBroadcastReceiver : BroadcastReceiver() { private val TAG = "NetworkBroadcastReceiver" private var mBroadcastCallback: NetworkBroadcastCallback? = null override fun onReceive(context: Context, intent: Intent) { if (intent.action == null) { LogUtils.el(TAG, "onReceive#intent=$intent") return } val action = intent.action LogUtils.d(TAG, "onReceive#action=$action") if (TextUtils.equals(intent.action, ConnectivityManager.CONNECTIVITY_ACTION)) { // request for access; // if (!XXPermissions.isGrantedPermission(context, Permission.WRITE_EXTacERNAL_STORAGE, // Permission.READ_EXTERNAL_STORAGE)) { // } // NetworkInfo mobNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); // NetworkInfo wifiNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); // if (!mobNetInfo.isConnected() & amp; & amp; !wifiNetInfo.isConnected()) { // //Neither WIFI nor mobile network is connected // netContentListener.netContent(false); // } else { // //WIFI connection or mobile network connection // netContentListener.netContent(true); // } val isOnline = NetworkUtils.isOnline(context) val networkStatus = NetworkUtils.getNetWorkState(context) LogUtils.d(TAG, "onReceive#isOnline=$isOnline, networdStatus=$networkStatus") if (mBroadcastCallback != null) { mBroadcastCallback!!.onNetworkBroadcastCallback(isOnline, networkStatus) } } } fun setBroadcastCallback(broadcastCallback: NetworkBroadcastCallback?) { mBroadcastCallback = broadcastCallback } interface NetworkBroadcastCallback { /** * Return the connection status and network status according to the monitoring results; * * @param isConnected * @param networkStatus */ fun onNetworkBroadcastCallback( isConnected: Boolean, networkStatus: NetworkStatus? ) } }
ApplicationSupporter
package com.let.networkstatusmonitor import android.app.Application /** * @Author: let * @date: 2022/11/15 17:28 * @description: */ class ApplicationSupporter : Application() { private val TAG = "ApplicationSupporter" override fun onCreate() { super.onCreate() instance = this BaseApplicationHelper.getInstance() .initApplicationContext(this) //Register network status monitoring; NetworkListenerHelper.init(this).registerNetworkListener() } companion object { var instance: ApplicationSupporter? = null } }
—————-
Copyright statement: This article is an original article by CSDN blogger “Kezhou Qiujian” and follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this statement when reprinting.
Original link: https://blog.csdn.net/qq_36162336/article/details/128494247