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();
            }
        }

    }
}
执行效果.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;
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,363评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • 每次一到超市打酱油 看到货架上琳琅满目的酱油 小编的选择困难症就开始犯了 左右手各拿着一瓶,再看看货架上的 完全不...
    文博_4f10阅读 190评论 0 0
  • 也不知道你想出去的想法是否成行,也不知道你啥时候毕业,毕业以后过一段自己想要的生活是好事,就当毕业旅行吧!...
    船长阅读 178评论 0 0
  • 我认为,战略思考的好处是: 1.清晰不做什么,和做什么。甚至懂得不做什么比做什么更重要!因为只有聚焦,才会容易出成...
    韩燕_6989阅读 710评论 0 0