Android 网络改变状态监听

1. 网络状态改变使用静态注册还是动态注册

回答: 动态注册。因为当App关闭后,我们的应用将不再关心网络状态的改变了。

2. 添加必须的权限
    <uses-permission android:name="android.permission.INTERNET"/>
    <!--允许读取网络状态-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!--允许读取wifi网络状态-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
3. 静态注册
        <!--静态注册-->
        <receiver
            android:name=".NetReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
                <action android:name="android.net.wifi.STATE_CHANGE"/>
            </intent-filter>
        </receiver>
4. 动态注册
public class MainActivity extends AppCompatActivity {

    private NetReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mReceiver = new NetReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(mReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }
}
5. NetReceiver代码
/**
 * 网络状态监听广播
 * 监听网络的改变状态,只有在用户操作网络连接开关(wifi, mobile)的时候接收广播,
 * 然后再对应的界面进行相应的操作,并将状态保存在我们的app里面
 * @author mazaiting
 */
public class NetReceiver extends BroadcastReceiver {
    private static final String TAG = "NetReceiver";
    public NetReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        /**
         * 这个监听wifi的打开与关闭,与wifi的连接无关
         */
        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            // 获取Wifi状态
            int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
            Log.e(TAG, "onReceive: " + wifiState);

            switch (wifiState) {
                case WifiManager.WIFI_STATE_ENABLING:
                    // Wifi开启中
                    Log.e(TAG, "onReceive: Wifi开启中");
                    break;
                case WifiManager.WIFI_STATE_ENABLED:
                    // Wifi可用
                    Log.e(TAG, "onReceive: Wifi可用");
                    break;
                case WifiManager.WIFI_STATE_DISABLING:
                    // Wifi关闭中
                    Log.e(TAG, "onReceive: Wifi关闭中");
                    break;
                case WifiManager.WIFI_STATE_DISABLED:
                    // Wifi已关闭
                    Log.e(TAG, "onReceive: Wifi已关闭");
                    break;
                case WifiManager.WIFI_STATE_UNKNOWN:
                    // Wifi状态未知
                    Log.e(TAG, "onReceive: Wifi未知");
                    break;
                default:
                    break;
            }
        }

        /**
         * 监听Wifi的连接状态,即是否连上了一个有效无线路由,当上变广播的状态时WifiManager.WIFI_STATE_DISABLING,
         * 和WIFI_STATE_DISABLED的时候,根本不会解到这个广播在上边广播接到是WifiManager.WIFI_STATE_ENABLED状态
         * 的同时也会接到这个广播,当然刚打开wifi肯定还没有连接到有效的无线
         */
        if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            // 获取网络信息
            Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            if (null != parcelableExtra) {
                // 强转为NetworkInfo对象
                NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
                // 获取网络状态
                NetworkInfo.State state = networkInfo.getState();
                // 判断状态
                boolean isConnection = state == NetworkInfo.State.CONNECTED;
                Log.e(TAG, "onReceive: " + isConnection);
                Toast.makeText(context, "当前状态: " + isConnection , Toast.LENGTH_SHORT).show();
            }
        }

        /**
         * 这个监听网络连接的设置,包括Wifi和移动数据的打开和关闭
         * 最好还是用这个监听,Wifi如果打开,关闭以及链接上可用的连接都会接到监听
         * 这个广播的最大的弊端势必上边两个广播的反应都要慢
         */
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
            // 获取连接管理者
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            // 获取网络状态信息
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            // 判断网络信息是否为空并且已连接
            if (null != networkInfo && networkInfo.isConnected()) {
                if (ConnectivityManager.TYPE_WIFI == networkInfo.getType()) {
                    // 判断是否为Wifi
                    Log.e(TAG, "onReceive: 当前Wifi可用");
                    Toast.makeText(context, "当前Wifi可用", Toast.LENGTH_SHORT).show();
                } else if (ConnectivityManager.TYPE_MOBILE == networkInfo.getType()) {
                    // 判断是否为移动网络
                    Log.e(TAG, "onReceive: 当前移动网络可用");
                    Toast.makeText(context, "当前移动网络可用", Toast.LENGTH_SHORT).show();
                }

                Log.e(TAG, "onReceive: info.getTypeName--" + networkInfo.getTypeName());
                Log.e(TAG, "onReceive: getSubtypeName--" + networkInfo.getSubtypeName());
                Log.e(TAG, "onReceive: getState--" + networkInfo.getState());
                Log.e(TAG, "onReceive: getDetailedState().name--" + networkInfo.getDetailedState().name());
                Log.e(TAG, "onReceive: getExtraInfo--" + networkInfo.getExtraInfo());
                Log.e(TAG, "onReceive: getType--" + networkInfo.getType());

            } else {
                Log.e(TAG, "onReceive: 当前没有网络连接,请确保你已经打开网络!");
                Toast.makeText(context, "当前没有网络连接,请确保你已经打开网络!", Toast.LENGTH_SHORT).show();
            }
        }

    }
}
3110861-9a7038b81e3f64c6.png
执行效果.png
6. 网络工具类NetUtil

/**
 * 网络工具类
 * @author mazaiting
 * @date 2018/3/29
 */

public class NetUtil {
    /**
     * 判断当前网络是否是移动网络
     *
     * @param context 上下文
     * @return boolean 3G
     */
    public static boolean is3G(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetInfo != null
                && activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE;
    }

    /**
     * 判断当前网络是否是wifi网络
     *
     * @param context 上下文
     * @return true: wifi; false: 非wifi
     */
    public static boolean isWifi(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetInfo != null
                && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI;
    }

    /**
     * 判断当前网络是否是2G网络
     *
     * @param context 上下文
     * @return true: 2G; false: 不是2G
     */
    public static boolean is2G(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (null != activeNetInfo && (activeNetInfo.getSubtype() == TelephonyManager.NETWORK_TYPE_EDGE
                || activeNetInfo.getSubtype() == TelephonyManager.NETWORK_TYPE_GPRS || activeNetInfo
                .getSubtype() == TelephonyManager.NETWORK_TYPE_CDMA)) {
            return true;
        }
        return false;
    }

    /**
     * wifi是否打开
     * @param context 上下文
     * @return true: 打开; false: 未打开
     */
    public static boolean isWifiEnabled(Context context) {
        ConnectivityManager mgrConn = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        TelephonyManager mgrTel = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        return ((mgrConn.getActiveNetworkInfo() != null && mgrConn
                .getActiveNetworkInfo().getState() == NetworkInfo.State.CONNECTED) || mgrTel
                .getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS);
    }

    /**
     * 判断是否有网络连接
     *
     * @param context 上下文
     * @return 网络连接
     */
    public static boolean isNetworkConnected(Context context) {
        if (null != context) {
            // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context
                    .CONNECTIVITY_SERVICE);
            // 获取NetworkInfo对象
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            //判断NetworkInfo对象是否为空
            if (null != networkInfo) {
                return networkInfo.isAvailable();
            }
        }
        return false;
    }

    /**
     * 判断MOBILE网络是否可用
     *
     * @param context 上下文
     * @return true, 可用; false,不可用
     */
    public static boolean isMobileConnected(Context context) {
        if (context != null) {
            //获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context
                    .CONNECTIVITY_SERVICE);
            //获取NetworkInfo对象
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            //判断NetworkInfo对象是否为空 并且类型是否为MOBILE
            if (null != networkInfo && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                return networkInfo.isAvailable();
            }
        }
        return false;
    }

    /**
     * 获取当前网络连接的类型信息
     * 原生
     *
     * @param context 上下文
     * @return 网络类型
     */
    public static int getConnectedType(Context context) {
        if (null != context) {
            //获取手机所有连接管理对象
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context
                    .CONNECTIVITY_SERVICE);
            //获取NetworkInfo对象
            NetworkInfo networkInfo = manager.getActiveNetworkInfo();
            if (null != networkInfo && networkInfo.isAvailable()) {
                //返回NetworkInfo的类型
                return networkInfo.getType();
            }
        }
        return -1;
    }

    /**
     * 获取当前的网络状态 :没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2
     * 自定义
     *
     * @param context 上下文
     * @return 网络类型
     */
    public static int getApnType(Context context) {
        //结果返回值
        int netType = 0;
        //获取手机所有连接管理对象
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context
                .CONNECTIVITY_SERVICE);
        //获取NetworkInfo对象
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        //NetworkInfo对象为空 则代表没有网络
        if (networkInfo == null) {
            return netType;
        }
        //否则 NetworkInfo对象不为空 则获取该networkInfo的类型
        int nType = networkInfo.getType();
        if (nType == ConnectivityManager.TYPE_WIFI) {
            //WIFI
            netType = 1;
        } else if (nType == ConnectivityManager.TYPE_MOBILE) {
            // 获取子类型
            int nSubType = networkInfo.getSubtype();
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService
                    (Context.TELEPHONY_SERVICE);
            if (nSubType == TelephonyManager.NETWORK_TYPE_LTE
                    && !telephonyManager.isNetworkRoaming()) {
                // 4G
                netType = 4;
            } else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS
                    || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA
                    || nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0
                    && !telephonyManager.isNetworkRoaming()) {
                //3G   联通的3G为UMTS或HSDPA 电信的3G为EVDO
                netType = 3;
            } else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS
                    || nSubType == TelephonyManager.NETWORK_TYPE_EDGE
                    || nSubType == TelephonyManager.NETWORK_TYPE_CDMA
                    && !telephonyManager.isNetworkRoaming()) {
                //2G 移动和联通的2G为GPRS或EGDE,电信的2G为CDMA
                netType = 2;
            } else {
                netType = 2;
            }
        }
        return netType;
    }

    /**
     * 获得本机ip地址
     *
     * @return ip地址
     */
    public static String getHostIp() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface networkInterface = en.nextElement();
                for (Enumeration<InetAddress> ipAdd = networkInterface.getInetAddresses(); ipAdd
                        .hasMoreElements(); ) {
                    InetAddress inetAddress = ipAdd.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值