在App开发中, 我们常常遇到网络不稳定的情况, 这时候要及时做一些事情, 防止App的崩溃.我们往往使用BroadCastReceiver来实现这个功能, 但是他有个问题, 用到网络监听的地方都需要注册一个, 造成了资源的浪费,于是.
我们可以使用一个观察者模式,这样系统只需要注册一个Receiver就可以把网络变化通知到所有注册他的地方了.
用法:
1.继承 NetworkStatusListener
2.注册
NetworkDetector.registerNetworkStatusListener(this);
3.然后就可以使用了:
@Override
public void onNetworkStatusChanged(boolean isAvaliable, int state) {
AppLog.i(TAG, "---onNetworkStatusChanged isAvaliable=" + isAvaliable + ", state=" + state);
isNetworkAvaliable = isAvaliable;
networkType = state;
refreshAvatarDefinition();
}
在manifest中注册
<!-- 网络变化检测广播接收器 -->
<receiver android:name="com.prone.vyuan.internet.NetworkDetector" >
<intent-filter android:priority="1000" >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.GTALK_CONNECTED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
代码:
/**
* 网络状态检测类
* 需要监听网络状态的地方只需要注册一个监听,如果网络有变化会回调网络改变接口,不需要监听的时候需要反注册
*/
public class NetworkDetector extends BroadcastReceiver {
private static String TAG = "NetworkDetector";
private static ArrayList<NetworkStatusListener> mListenerList = new ArrayList<NetworkStatusListener>();
private static boolean isAvaliable = false;
/** 没有网络 */
public static final int NETWORKTYPE_INVALID = 0;
/** wifi网络 */
public static final int NETWORKTYPE_WIFI = 1;
/** 2G网络 */
public static final int NETWORKTYPE_2G = 2;
/** 3G和3G以上网络,或统称为快速网络 */
public static final int NETWORKTYPE_3G = 3;
/** 其他网络 */
public static final int NETWORKTYPE_OTHER = 4;
public static void registerNetworkStatusListener(NetworkStatusListener listener) {
if (!mListenerList.contains(listener))
mListenerList.add(listener);
}
public static void unregisterNetworkStatusListener(NetworkStatusListener listener) {
mListenerList.remove(listener);
}
/**
* 判断网络是否可用
* @param context
* @return
*/
public static synchronized boolean isNetworkAvaliable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetInfo = cm.getActiveNetworkInfo();
if (null == activeNetInfo || !activeNetInfo.isAvailable() || !activeNetInfo.isConnected()) {
AppLog.e(TAG, "NetWork is unavailable");
return false;
}
return true;
}
/**
* 判断网络是否可用
* @param context
* @return true 网络可用,false其他
*/
public static boolean isNetworkAvaliable() {
ConnectivityManager cm = (ConnectivityManager) App.appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetInfo = cm.getActiveNetworkInfo();
if (null == activeNetInfo || !activeNetInfo.isAvailable() || !activeNetInfo.isConnected()) {
AppLog.e(TAG, "NetWork is unavailable");
return false;
}
return true;
}
/**
* 判断wifi 的设置 是否是一直 链接
* @return true一直链接或者当前网络不是wifi,false当前网络是wifi并且设置不是一直链接
*/
public static boolean isWifiAlwaysConnect(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.getType() == ConnectivityManager.TYPE_WIFI) {
int wifiSleepPolicy = Settings.System.getInt(context.getContentResolver(), "wifi_sleep_policy",
Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
if (wifiSleepPolicy != Settings.System.WIFI_SLEEP_POLICY_NEVER) {
return false;
}
}
return true;
}
public static String getNetworkName() {
ConnectivityManager cm = (ConnectivityManager) App.appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
return (info == null) ? "No network" : info.getTypeName();
}
//其实可以通过
//boolean nextIsAvaliable = intent.getBooleanExtra(android.net.ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
//来拿到是否有网络连接
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.intent.action.GTALK_CONNECTED".equals(action)) {
AppLog.i(TAG, "Avaliable, Gtalk connected");
isAvaliable = true;
App.isNetworkAvaliable = isAvaliable;
for (NetworkStatusListener listener : mListenerList) {
listener.onNetworkStatusChanged(isAvaliable, Connectivity.getConnectType(context));
}
} else {
boolean nextIsAvaliable = isNetworkAvaliable(context);
App.isNetworkAvaliable = nextIsAvaliable;
AppLog.i(TAG, "Old:" + isAvaliable + "<------->" + "New:" + nextIsAvaliable);
if (isAvaliable != nextIsAvaliable) {
isAvaliable = !isAvaliable;
for (NetworkStatusListener listener : mListenerList) {
listener.onNetworkStatusChanged(isAvaliable, Connectivity.getConnectType(context));
}
}
}
}
}