Android网络状态变化监听 -- 结合registerNetworkCallback和广播(kotlin)

如图

218416259a5147a4971f27e6518401e7.png

说明
  AndroidAndroid针对网络状态变化的监听,在应用内我们通用需要监听设备网络状态的变化,作出相应的业务处理,需要一个方便的、全局的监听实现。。
  针对不同设备的系统版本,使用不同的API方法实现;
  注意使用广播监听网络状态在高版本的适配问题;

  1、Build.VERSION.SDK_INT >= Build.VERSION_CODES.N,使用connectivityManager.registerDefaultNetworkCallback()方法;
  2、Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP,使用connectivityManager.registerNetworkCallback(networkRequest, new MyNetworkCallback());方法;
  3、其它系统版本使用广播监听;
  4、NetworkListenerHelper可以添加多个页面的监听,当某个页面需要监听网络时,就可以添加到监听者集合中,页面关闭时移除这个监听者,也可以使用事件总线;

核心实现

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
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36162336/article/details/128494247