Android network status change monitoring -- combining registerNetworkCallback and broadcasting (kotlin)

as shown in the picture

218416259a5147a4971f27e6518401e7.png

 

 

Explain that
  Android Android monitors network status changes. In the application, we generally need to monitor device network status changes and make corresponding business processing. A convenient and global monitoring implementation is required. .
  For the system version of different devices, use different API methods;
  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 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 monitors. When a page needs to monitor the network, it can be added to the listener collection, and the listener will be removed when the page is closed. An event bus can also be used;

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: 网络状态变化的监听类,根据android不同版本的系统,有 [ConnectivityManager.registerNetworkCallback]和注册广播两种实现方式;
 */
object NetworkListenerHelper {
    private val TAG = "NetworkListenerHelper"
    private var mContext: Context? = null

    @Volatile
    private var mListenerList: CopyOnWriteArrayList<NetworkConnectedListener>? = null

    /**
     * 注册网络状态的监听;
     */
    @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 -> {
                // 通过广播的方式监听网络;
                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!!)
                    }
                })
            }
        }
    }

    /**
     * 通知所有接收者;
     *
     * @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)
            }
        }
    }

    /**
     * 添加回调的监听者;
     */
    @Synchronized
    fun addListener(listener: NetworkConnectedListener?) {
        if (listener == null) {
            return
        }
        if (mListenerList == null) {
            mListenerList = CopyOnWriteArrayList()
        }
        // 防止重复添加;
        if (!mListenerList!!.contains(listener)) {
            mListenerList!!.add(listener)
        }
    }

    /**
     * 移除某个回调实例;
     *
     * @param listener
     */
    @Synchronized
    fun removeListener(listener: NetworkConnectedListener?) {
        if (listener != null && 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() {
        //当用户与网络连接(或断开连接)(可以是WiFi或蜂窝网络)时,这两个功能均作为默认回调;
        override fun onAvailable(network: Network) {
            super.onAvailable(network)
            LogUtils.d(TAG, "onAvailable#network=$network")
            // 需要同步获取一次网络状态;
            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")
            // 需要同步获取一次网络状态;
            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);
            // 表示能够和互联网通信(这个为true表示能够上网)
            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                when {
                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                        LogUtils.d(TAG, "onCapabilitiesChanged#网络类型为wifi")
                    }
                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                        LogUtils.d(TAG, "onCapabilitiesChanged#蜂窝网络")
                    }
                    else -> {
                        LogUtils.d(TAG, "onCapabilitiesChanged#其他网络")
                    }
                }
            }
        }
    }

    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)

        // 网络状态回调;
        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 = "\n网络变化通知:status=$status, desc=$desc\n$trim" }
    }
}

NetworkStatus

package com.let.networkstatusmonitor;

/**
 * @Author: let
 * @date: 2022/11/15 17:30
 * @description: 网络连接状态的枚举
 */
public enum NetworkStatus {

    /**
     * ;
     */
    NONE(-1, "无网络连接"),
    /**
     * 解析数据内容失败
     */
    MOBILE(0, "移动网络连接"),
    /**
     * 网络问题
     */
    WIFI(1, "WIFI连接");

    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 && mobileNetInfo.isAvailable) {
                //WIFI和移动网络均未连接
                NetworkStatus.MOBILE
            } else if (wifiNetInfo != null && wifiNetInfo.isAvailable) {
                //WIFI和移动网络均未连接
                NetworkStatus.WIFI
            } else {
                NetworkStatus.NONE
            }
        } else {
            when {
                isMobileConnected(context) -> {
                    NetworkStatus.MOBILE
                }
                isWifiConnected(context) -> {
                    NetworkStatus.WIFI
                }
                else -> {
                    NetworkStatus.NONE
                }
            }
        }

//            //获取所有网络连接的信息
//            Network[] networks = connMgr.getAllNetworks();
//            //通过循环将网络信息逐个取出来
//            for (int i = 0; i < networks.length; i++) {
//                //获取ConnectivityManager对象对应的NetworkInfo对象
//                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;
//                    }
//                }
//            }
    }

    /**
     * 判断网络是否连接
     *
     * @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 && 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: 网络状态的监听广播
 */
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)) {
            // 申请权限;
//        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() && !wifiNetInfo.isConnected()) {
//            //WIFI和移动网络均未连接
//            netContentListener.netContent(false);
//        } else {
//            //WIFI连接或者移动网络连接
//            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 {
        /**
         * 根据监听的结果返回连接状态和网络状态;
         *
         * @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)
        // 注册网络状态监听;
        NetworkListenerHelper.init(this).registerNetworkListener()
    }

    companion object {
        var instance: ApplicationSupporter? = null
    }
}

 

 

Guess you like

Origin blog.csdn.net/qq_36162336/article/details/128494247