图
说明
??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.windfallsheng.networkstatusmonitor;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Build;
import androidx.annotation.NonNull;
import com.windfallsheng.by_lib.command.NetworkStatus;
import com.windfallsheng.by_lib.command.ObjectCachePool;
import com.windfallsheng.by_lib.utils.CollectionUtils;
import com.windfallsheng.by_lib.utils.LogUtils;
import com.windfallsheng.by_lib.utils.NetworkUtils;
import com.windfallsheng.networkstatusmonitor.broadcast.NetworkBroadcastReceiver;
import java.util.concurrent.CopyOnWriteArrayList;
public class NetworkListenerHelper {
private final String TAG = "NetworkListenerHelper";
private Context mContext;
private volatile CopyOnWriteArrayList<NetworkConnectedListener> mListenerList = null;
private NetworkListenerHelper(Context context) {
mContext = context.getApplicationContext();
}
public static synchronized NetworkListenerHelper obtain() {
NetworkListenerHelper obj = (NetworkListenerHelper) ObjectCachePool.getInstance()
.getObj(NetworkListenerHelper.class);
if (obj == null) {
throw new NullPointerException("The NetworkListenerHelper instance has not been initialized.");
}
return obj;
}
public static synchronized NetworkListenerHelper init(Context context) {
NetworkListenerHelper obj = (NetworkListenerHelper) ObjectCachePool.getInstance()
.getObj(NetworkListenerHelper.class);
if (obj == null) {
obj = new NetworkListenerHelper(context);
}
ObjectCachePool.getInstance().cache(obj);
return obj;
}
@SuppressLint("MissingPermission")
public void registerNetworkListener() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
LogUtils.el(TAG, "registerNetworkListener#return#connectivityManager=" + connectivityManager);
return;
}
connectivityManager.registerDefaultNetworkCallback(new MyNetworkCallback());
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
LogUtils.el(TAG, "registerNetworkListener#return#connectivityManager=" + connectivityManager);
return;
}
final NetworkRequest.Builder builder;
builder = new NetworkRequest.Builder();
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
NetworkRequest networkRequest = builder.build();
connectivityManager.registerNetworkCallback(networkRequest, new MyNetworkCallback());
} else {
NetworkBroadcastReceiver mNetworkBroadcastReceiver = new NetworkBroadcastReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mNetworkBroadcastReceiver, filter);
mNetworkBroadcastReceiver.setBroadcastCallback((isConnected, networkStatus) -> {
notifyAllListeners(isConnected, networkStatus);
});
}
}
private void notifyAllListeners(boolean isConnected, NetworkStatus networkStatus) {
if (CollectionUtils.isNotEmpty(mListenerList)) {
for (NetworkConnectedListener listener : mListenerList) {
if (listener != null) {
listener.onNetworkConnected(isConnected, networkStatus);
}
}
}
}
public synchronized void addListener(NetworkConnectedListener listener) {
if (listener == null) {
return;
}
if (mListenerList == null) {
mListenerList = new CopyOnWriteArrayList<>();
}
if (!mListenerList.contains(listener)) {
mListenerList.add(listener);
}
}
public synchronized void removeListener(NetworkConnectedListener listener) {
if (listener != null && CollectionUtils.isNotEmpty(mListenerList)) {
mListenerList.remove(listener);
}
}
public void unregisterNetworkCallback() {
if (mContext == null) {
return;
}
ConnectivityManager connectivityManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
LogUtils.el(TAG, "registerNetworkListener#return#connectivityManager=" + connectivityManager);
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(new ConnectivityManager.NetworkCallback());
}
}
public interface NetworkConnectedListener {
void onNetworkConnected(boolean isConnected, NetworkStatus networkStatus);
}
@SuppressLint("NewApi")
private class MyNetworkCallback extends ConnectivityManager.NetworkCallback {
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
LogUtils.d(TAG, "onAvailable#network=" + network);
final NetworkStatus netWorkState = NetworkUtils.getNetWorkState(mContext);
LogUtils.d(TAG, "onAvailable#netWorkState=" + netWorkState);
notifyAllListeners(true, netWorkState);
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
LogUtils.d(TAG, "onLost#network=" + network);
final NetworkStatus netWorkState = NetworkUtils.getNetWorkState(mContext);
LogUtils.d(TAG, "onLost#netWorkState=" + netWorkState);
notifyAllListeners(false, netWorkState);
}
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
LogUtils.d(TAG, "onCapabilitiesChanged#network=" + network);
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
LogUtils.d(TAG, "onCapabilitiesChanged#网络类型为wifi");
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
LogUtils.d(TAG, "onCapabilitiesChanged#蜂窝网络");
} else {
LogUtils.d(TAG, "onCapabilitiesChanged#其他网络");
}
}
}
}
}
广播NetworkBroadcastReceiver
package com.windfallsheng.networkstatusmonitor.broadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.text.TextUtils;
import com.windfallsheng.by_lib.command.NetworkStatus;
import com.windfallsheng.by_lib.utils.LogUtils;
import com.windfallsheng.by_lib.utils.NetworkUtils;
public class NetworkBroadcastReceiver extends BroadcastReceiver {
private final String TAG = "NetworkBroadcastReceiver";
private NetworkBroadcastCallback mBroadcastCallback;
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || intent.getAction() == null) {
LogUtils.el(TAG, "onReceive#intent=" + intent);
return;
}
final String action = intent.getAction();
LogUtils.d(TAG, "onReceive#action=" + action);
if (TextUtils.equals(intent.getAction(), ConnectivityManager.CONNECTIVITY_ACTION)) {
final boolean isOnline = NetworkUtils.isOnline(context);
final NetworkStatus networkStatus = NetworkUtils.getNetWorkState(context);
LogUtils.d(TAG, "onReceive#isOnline=" + isOnline + ", networdStatus=" + networkStatus);
if (mBroadcastCallback != null) {
mBroadcastCallback.onNetworkBroadcastCallback(isOnline, networkStatus);
}
}
}
public void setBroadcastCallback(NetworkBroadcastCallback broadcastCallback) {
mBroadcastCallback = broadcastCallback;
}
public interface NetworkBroadcastCallback {
void onNetworkBroadcastCallback(boolean isConnected, NetworkStatus networkStatus);
}
}
调用:
package com.windfallsheng.networkstatusmonitor;
import android.app.Application;
import com.windfallsheng.by_lib.command.BaseApplicationHelper;
import com.windfallsheng.by_lib.utils.LogUtils;
public class ApplicationSupporter extends Application {
private static ApplicationSupporter mApplicationSupporter;
private final String TAG = "ApplicationSupporter";
public static ApplicationSupporter getInstance() {
return mApplicationSupporter;
}
@Override
public void onCreate() {
super.onCreate();
mApplicationSupporter = this;
BaseApplicationHelper.getInstance()
.initApplicationContext(mApplicationSupporter);
LogUtils.initDebug(true);
NetworkListenerHelper.init(mApplicationSupporter)
.registerNetworkListener();
}
}
package com.windfallsheng.networkstatusmonitor;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.windfallsheng.by_lib.command.NetworkStatus;
import com.windfallsheng.by_lib.utils.LogUtils;
public class MainActivity extends AppCompatActivity implements NetworkListenerHelper.NetworkConnectedListener {
private final String TAG = "MainActivity";
private TextView mTvResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvResult = findViewById(R.id.tv_result);
NetworkListenerHelper.obtain()
.addListener(MainActivity.this);
}
@Override
public void onNetworkConnected(boolean isConnected, NetworkStatus networkStatus) {
LogUtils.d(TAG, "onNetworkConnected#isConnected=" + isConnected);
final String trim = mTvResult.getText().toString();
final int status = networkStatus.getStatus();
final String desc = networkStatus.getDesc();
mTvResult.post(() -> mTvResult.setText("\n网络变化通知:status=" + status + ", desc=" + desc + "\n" + trim));
}
@Override
protected void onDestroy() {
super.onDestroy();
NetworkListenerHelper.obtain()
.removeListener(MainActivity.this);
}
}
其它:
package com.windfallsheng.by_lib.command;
import android.text.TextUtils;
import com.windfallsheng.by_lib.utils.LogUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ObjectCachePool {
private static volatile ConcurrentMap<String, Object> OBJECT_CACHE = null;
private final String TAG = ObjectCachePool.class.getSimpleName();
private ObjectCachePool() {
}
public static ObjectCachePool getInstance() {
return SingletonHolder.INSTANCE;
}
public synchronized void cache(Object obj) {
if (OBJECT_CACHE == null) {
OBJECT_CACHE = new ConcurrentHashMap<>();
}
String key = obj.getClass().getName();
LogUtils.d(TAG, "method:cache#key=" + key + ", obj=" + obj);
OBJECT_CACHE.put(key, obj);
}
public synchronized void cache(String key, Object obj) {
if (OBJECT_CACHE == null) {
OBJECT_CACHE = new ConcurrentHashMap<>();
}
LogUtils.d(TAG, "method:cache#key=" + key + ", obj=" + obj);
OBJECT_CACHE.put(key, obj);
}
public synchronized boolean containsObj(String key) {
if (OBJECT_CACHE == null) {
return false;
}
Object obj = getObj(key);
if (obj != null) {
return true;
}
return false;
}
public Object getObj(Class<?> clazz) {
LogUtils.d(TAG, "method:getObj#clazz=" + clazz);
final String className = clazz.getName();
LogUtils.d(TAG, "method:getObj#className=" + className);
return getObj(className);
}
public Object getObj(String key) {
LogUtils.d(TAG, "method:getObj#key=" + key);
if (OBJECT_CACHE == null) {
return null;
}
return OBJECT_CACHE.get(key);
}
public synchronized void remove(Class<?> clazz) {
LogUtils.d(TAG, "method:getObj#clazz=" + clazz);
final String className = clazz.getName();
LogUtils.d(TAG, "method:getObj#className=" + className);
remove(className);
}
public synchronized void remove(String key) {
LogUtils.d(TAG, "method:remove#key=" + key);
if (OBJECT_CACHE != null && !TextUtils.isEmpty(key)) {
OBJECT_CACHE.remove(key);
}
LogUtils.d(TAG, "method:remove#OBJECT_CACHE=" + OBJECT_CACHE);
}
public synchronized void evictAll() {
LogUtils.d(TAG, "method:evictAll");
if (OBJECT_CACHE != null) {
OBJECT_CACHE.clear();
OBJECT_CACHE = null;
}
LogUtils.d(TAG, "method:evictAll#OBJECT_CACHE=" + OBJECT_CACHE);
}
public synchronized Object obtainInstance(Class<?> clazz) {
LogUtils.d(TAG, "method:obtainInstance#in#arguments:clazz=" + clazz);
final String className = clazz.getName();
LogUtils.d(TAG, "method:obtainInstance#className=" + className);
Object obj = getObj(className);
LogUtils.d(TAG, "method:obtainInstance#obj=" + obj);
if (obj == null) {
synchronized (ObjectCachePool.class) {
if (obj == null) {
try {
Constructor c0 = clazz.getDeclaredConstructor();
c0.setAccessible(true);
obj = c0.newInstance();
LogUtils.d(TAG, "method:obtainInstance#newInstance#obj=" + obj +
", hashCode=" + obj.hashCode());
} catch (IllegalAccessException e) {
LogUtils.el(TAG, "method:obtainInstance#e=" + e.getMessage());
} catch (InstantiationException e) {
LogUtils.el(TAG, "method:obtainInstance#e=" + e.getMessage());
} catch (NoSuchMethodException e) {
LogUtils.el(TAG, "method:obtainInstance#e=" + e.getMessage());
} catch (InvocationTargetException e) {
LogUtils.el(TAG, "method:obtainInstance#e=" + e.getMessage());
}
}
}
if (obj != null) {
LogUtils.d(TAG, "method:obtainInstance#cache#obj=" + obj);
cache(className, obj);
}
}
return obj;
}
private static class SingletonHolder {
private static ObjectCachePool INSTANCE = new ObjectCachePool();
}
}
package com.windfallsheng.by_lib.command;
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();
}
}
package com.windfallsheng.by_lib.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Build;
import com.windfallsheng.by_lib.command.NetworkStatus;
public class NetworkUtils {
@SuppressLint("MissingPermission")
public static NetworkStatus getNetWorkState(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mobileNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifiNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mobileNetInfo != null && mobileNetInfo.isAvailable()) {
return NetworkStatus.MOBILE;
} else if (wifiNetInfo != null && wifiNetInfo.isAvailable()) {
return NetworkStatus.WIFI;
} else {
return NetworkStatus.NONE;
}
} else {
if (isMobileConnected(context)) {
return NetworkStatus.MOBILE;
} else if (isWifiConnected(context)) {
return NetworkStatus.WIFI;
} else {
return NetworkStatus.NONE;
}
}
}
@SuppressLint("MissingPermission")
public static boolean isOnline(Context context) {
if (context == null) {
return false;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
ConnectivityManager connMgr = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isAvailable());
} else {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = connectivityManager.getActiveNetwork();
if (activeNetwork == null) {
return false;
}
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
if (networkCapabilities != null) {
return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
}
return false;
}
@SuppressLint("MissingPermission")
public static boolean isWifiConnected(Context context) {
if (context == null) {
return false;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo != null) {
return networkInfo.isAvailable();
}
} else {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = connectivityManager.getActiveNetwork();
if (activeNetwork == null) {
return false;
}
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
if (networkCapabilities != null) {
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
}
}
return false;
}
@SuppressLint("MissingPermission")
public static boolean isMobileConnected(Context context) {
if (context == null) {
return false;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (networkInfo != null) {
return networkInfo.isAvailable();
}
} else {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = connectivityManager.getActiveNetwork();
if (activeNetwork == null) {
return false;
}
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
if (networkCapabilities != null) {
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
}
}
return false;
}
}
总结
??业务并不复杂,不再详细赘述,查看下载地址:https://download.csdn.net/download/Silence1515/42476740
|