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

这篇具有很好参考价值的文章主要介绍了Android网络状态变化监听 -- 结合registerNetworkCallback和广播(kotlin)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如图

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

 文章来源地址https://www.toymoban.com/news/detail-438727.html

 

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

 

 

到了这里,关于Android网络状态变化监听 -- 结合registerNetworkCallback和广播(kotlin)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android程序如何监听系统属性的变化

    Android 程序可以通过注册 android.os.SystemProperties 类的监听器来监听系统属性的变化。具体步骤如下: 实现 android.os.SystemProperties.OnPropertiesChangedListener 接口,该接口包含一个 onPropertiesChanged() 方法,在该方法中处理系统属性变化的逻辑。 在需要监听系统属性变化的地方,调用

    2024年02月14日
    浏览(30)
  • Android 之 监听 EditText 的内容变化

    在前面我们已经学过EditText控件了,本节来说下如何监听输入框的内容变化! 这个再实际开发中非常实用,另外,附带着说下如何实现EditText的密码可见与不可见! 由题可知,是基于监听的事件处理机制,好像前面的点击事件是OnClickListener,文本内容 变化的监听器则是:Te

    2024年02月12日
    浏览(28)
  • Android 如何优雅地监听SystemProperties属性值变化

    我司项目中会频繁用到persist.sys.xxx的属性值,系统中预埋接口,通过属性值控制,以应对客户多样化的需求定制。 以往都是先设置属性值,再重启设备使能生效,抽空研究一下实时监听属性值变化,最后在csdn上查到监听SystemProperties变化 这篇文章。 博主的实现方法给了我很

    2024年02月05日
    浏览(31)
  • Android监测手机网络状态变化的广播

    @Override public void onReceive(Context context, Intent intent) { int netWorkStates = NetworkUtil.getNetWorkStates(context); switch (netWorkStates) { case NetworkUtil.TYPE_NONE: //断网了 break; case NetworkUtil.TYPE_MOBILE: //打开了移动网络 break; case NetworkUtil.TYPE_WIFI: //打开了WIFI break; default: break; } } } 上述代码中使用到了Ne

    2024年04月12日
    浏览(34)
  • Android 蓝牙状态的监听

    客户在使用我公司的Flutter插件时,要求有一个蓝牙与设备重连的功能,我用公司提供的Android SDK只能实现超出和进入蓝牙范围进行重连,但是无法在蓝牙打开进行重连,这不得不让我使用Android手写一个广播监听。 1. 添加权限 2. 创建一个类继承 BroadcastReceiver 3. 动态注册和注销

    2024年02月10日
    浏览(31)
  • uniapp 安卓端实时监听网络状态

    写在uniapp的APP.vue的onShow方法中 uni.onNetworkStatusChange(function(res) {                 if (res.isConnected) {                     uni.showModal({                         title: \\\'系统提示\\\',                         content: \\\'当前设备网络已恢复\\\',                  

    2024年02月05日
    浏览(25)
  • uniapp切换路由监听导航跳转(在监听网络状态时非常常用)

    在实时监听网络状态的时候我们切换页面经常会用到此场景 注意:监听页面跳转变化要写在onLaunch方法里面         每次切换页面的时候都会执行调用watchRouter函数里面的方法 标题  

    2024年02月15日
    浏览(70)
  • uni-app中监听网络状态,并在嵌入webView页面的组件中添加网络监测

    下载插件 打开网络异常组件页面,点击\\\"下载插件并导入HBuilderX\\\"按钮,打开HBuilderX软件后,选择需要导入插件的项目,点击“确定即可”。 使用插件 pages/network/index页面,仿照微信。 效果展示 修改网络监测组件mz-network-error 当网络状态发生变化时emit相关事件 修改组件调用

    2024年02月12日
    浏览(34)
  • 监听数组Array变化或Obj属性变化

    工作中经常会遇到监听数组发生变化时执行相应的回调触发逻辑,客户应用场景中需要实现对象变量的动态监听,当变量发生变化时触发回调函数,实现事件发送等应用场景。       通常由以下两种方式实现需求 一.通过改变对象原型prototype方法实现回调监听 二.利用Proxy对象

    2024年02月09日
    浏览(31)
  • Vue组件使用(父组件监听子组件数据变化,子组件使用父组件的数据,并监听父组件的数据变化)

    父组件声明变量 父组件向子组件传递数据 Vue 数据类型 type 有以下几种: String:字符串类型。例如:“hello world”。 Number:数字类型。例如:12,1.5。 Boolean:布尔类型。例如:true,false。 Object:对象类型。例如:{name: ‘Tom’, age: 20}。 Array:数组类型。例如:[1, 2, 3]。 Fun

    2024年02月14日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包