天天看點

使用ConnectivityManager來擷取、監聽目前的網絡狀态

擷取網絡連接配接狀态

ConnectivityManager可以擷取Android系統的網絡連接配接相關資訊,它是系統服務中的一員:

ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
           

得到管理器對象後,調用getActiveNetworkInfo()即可獲得目前活動的網絡連接配接資訊了,若無網絡通路,傳回NULL

NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
           

根據getType()傳回的值來判斷是哪一種網絡連接配接類型,一般來說,我們隻要判斷有無、是否是WIFI就行了

int state = NETWORK_NULL;
        if(mNetworkInfo != null){
            switch (mNetworkInfo.getType()){
                case -1:
                    state = NETWORK_NULL;
                    break;
                case ConnectivityManager.TYPE_MOBILE:
                    state = NETWORK_MOBILE;
                    break;
                case ConnectivityManager.TYPE_WIFI:
                    state = NETWORK_WIFI;
                    break;
                default:
                    state = NETWORK_OTHER;
                    break;
            }
        }
           

監聽網絡連接配接變更

網絡連接配接變更時,系統會發送一條廣播,自定義一個廣播接收者來監聽這個廣播,我們就可以随時監聽網絡變更事件

該廣播為:"android.net.conn.CONNECTIVITY_CHANGE"

它是ConnectivityManager的常量:ConnectivityManager.CONNECTIVITY_ACTION

代碼如下:

/**
 * 監聽網絡狀态的接收者
 * <p>
 * 需要權限:
 * <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 * <p>
 * 需要注冊過濾器:
 * <p>
 * <intent-filter>
 * <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
 * </intent-filter>
 */
public class NetworkStateBroadcastReceiver
        extends BroadcastReceiver {
    
    public enum State {
        /** 沒有網絡 */
        NULL,
        /** 手機3G、GPRS網絡 */
        MOBILE,
        /** WIFI網絡 */
        WIFI,
        /** 其它網絡連接配接(如藍牙) */
        OTHER
    }
    
    /** 目前的網絡狀态 */
    private static State sState;
    
    /** 監聽網絡狀态的對象集合,使用了弱引用持有對象,當回調時,才會清除已釋放的弱引用對象 */
    private static final LinkedList<NetworkStateListener> mListeners = new LinkedList<>();
    
    static {
        //擷取網絡連接配接管理器
        ConnectivityManager mConnectivityManager =
                (ConnectivityManager) ApplicationHolder.instance().getSystemService(Context.CONNECTIVITY_SERVICE);
        //目前的網絡連接配接資訊
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        //判斷目前的網絡狀态
        State s = State.NULL;
        if (mNetworkInfo != null) {
            switch (mNetworkInfo.getType()) {
                case -1:
                    s = State.NULL;
                    break;
                case ConnectivityManager.TYPE_MOBILE:
                    s = State.MOBILE;
                    break;
                case ConnectivityManager.TYPE_WIFI:
                    s = State.WIFI;
                    break;
                default:
                    s = State.OTHER;
                    break;
            }
        }
        sState = s;
    }
    
    @Override
    public void onReceive(Context context, Intent intent) {
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
            //擷取目前網絡狀态
            int networkType = intent.getIntExtra("networkType", -1);
            State s;
            switch (networkType) {
                case -1:
                    s = State.NULL;
                    break;
                case ConnectivityManager.TYPE_MOBILE:
                    s = State.MOBILE;
                    break;
                case ConnectivityManager.TYPE_WIFI:
                    s = State.WIFI;
                    break;
                default:
                    s = State.OTHER;
                    break;
            }
            if (s != sState) {
                //将結果回調給監聽者
                sState = s;
                doCallBack(sState);
            }
        }
    }
    
    /** 網絡狀态變化時,回調接口 */
    private static synchronized void doCallBack(State state) {
        for (NetworkStateListener listener : mListeners) {
            listener.onNetworkStateChanged(state);
        }
    }
    
    /** 添加網絡狀态變化的監聽者 */
    public static synchronized void addListener(@NonNull NetworkStateListener listener) {
        mListeners.add(listener);
    }
    
    /** 添加網絡狀态變化的監聽者,并進行一次初始化的回調 */
    public static synchronized void addListenerWithInitCall(@NonNull NetworkStateListener listener) {
        mListeners.add(listener);
        listener.onNetworkStateChanged(sState);
    }
    
    /** 移除網絡狀态變化的監聽者 */
    public static synchronized boolean removeListener(@NonNull NetworkStateListener listener) {
        return mListeners.remove(listener);
    }
    
    /** 監聽網絡狀态變化的接口 */
    public interface NetworkStateListener {
        
        void onNetworkStateChanged(State state);
    }
    
    /** 擷取目前狀态 */
    public static State getState() {
        return sState;
    }
    
    /** 是否有網絡 */
    public static boolean hasNetwork() {
        return sState != State.NULL;
    }
    
    /** 是否有WIFI連接配接 */
    public static boolean hasWifi() {
        return sState == State.WIFI;
    }
    
}
           

對外開放了幾個靜态方法來擷取目前的網絡狀态及監聽網絡狀态變化。

addListener添加監聽者時,為避免記憶體洩漏,應在Activity的onDestory階段調用removeListener移除監聽者。

繼續閱讀