Android 网络改变状态监听-阿里云开发者社区

开发者社区> 凌浩雨> 正文

Android 网络改变状态监听

简介: 1. 网络状态改变使用静态注册还是动态注册 回答: 动态注册。因为当App关闭后,我们的应用将不再关心网络状态的改变了。 2. 添加必须的权限 3.
+关注继续查看

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

    }
}
img_e76e9d02360ddc9f93ea5c7c2a2dc6f3.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;
    }
}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Android开发14——监听内容提供者ContentProvider的数据变化
  一、提出需求 有A,B,C三个应用,B中的数据需要被共享,所以B中定义了内容提供者ContentProvider;A应用修改了B应用的数据,插入了一条数据。有这样一个需求,此时C应用需要得到数据被修改的通知并处理相应操作。     二、示例代码 A应用 /** * 对内容提供者进行操作 * * @author XY * */ public cla
889 0
Android手写状态切换布局
实现状态切换布局 image 效果图 image 原理 继承RelativeLayout,然后向其中添加各种状态的View,通过对各种View的显示隐藏的切换来实现各种状态的切换。
897 0
用广播监听安卓设备电量状态
  发送通知     这次邮件我们将会讨论怎么获取电量状态在安卓设备上,为了完成这个目标,我们将会使用到广播。   What is BroadcastReceiver?A broadcast receiver is an Android component...
862 0
Android状态管理优化
目录介绍 01.界面状态有哪些 02.采用include方式管理 03.在Base类中处理逻辑 04.如何降低偶性和入侵性 05.封装低入侵性状态库 5.1 自定义帧布局 5.2 自定义状态管理器 5.
2581 0
android(cm11)状态栏源码分析(一)
版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/50216563 (一):写在前面 最近由于工作需要,需要了解CM11中的有关于StatusBar相关的内容。
932 0
《UNIX网络编程 卷2:进程间通信(第2版)》——1.7 Unix标准
Posix是“可移植操作系统接口”(Portable Operating System Interface)的首字母缩写。它并不是一个单一标准,而是一个由电气与电子工程师学会即IEEE开发的一系列标准。
1403 0
Android屏幕适配之状态栏导航栏半透明、全透明(5.0以上去阴影),方法多样
1.1 StatusBar半透明用StatusBarView实现(4.4以上有效) 1.2 StatusBar半透明用setStatusBarColor实现(5.0以上有效) 2.1 StatusBar全透明用fitSystemWindows实现(4.
3879 0
设置windows网络连接别名和linux网络连接别名
windows网络连接别名 C:\Windows\System32\drivers\etc目录下的hosts文件中添加 127.0.0.1 localhost 192.168.1.100 proxy.
663 0
+关注
凌浩雨
毕业于贵州大学大数据与信息工程学院,目前是一名移动端工程师,就职于北京乾元大通信息技术有限责任公司。
327
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载