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