Android中wifi与数据流量的切换监听

 最近在做一个wifi和移动数据的监控功能,来来回回折腾了一阵子,这个模块的主要功能是监听整个APP的wifi与数据流量的切换,让用户使用专用流量,而不是用wifi,给一个弹窗,点击确认,自动切换数据流量,关闭wifi。我的思路是写一个静态广播,监听在广播里面进行监听,启用系统弹窗,点击确认,自动切换网络,这里面有一个坑就是弹窗会在广播中多次被调用,其实只调用了一次,但是实际上多次调用系统的弹窗会一个叠加一个,搞了好久,终于搞好了,原来是系统广播导致的叠加,详情看代码:


ConnectivityManager

 

 ConnectivityManager 是一个网络连接的管理类,里面封装了网络请求的详细信息,包括WiFi与移动数据流量的开关状态,正在开启与关闭的状态,连接状态等等,很适合做网络监听。还有一个类WifiManager ,这个类专门用来做WiFi的监听,他的监听效果比ConnectivityManager更加详细丰富,可以检测但是对流量没法生效。这里使用ConnectivityManager 就足够了。


一、注册广播


写一个类继承自BroadcastReceiver。

        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo gprs = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            NetworkInfo wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (intent.getAction().equals("Android.net.conn.CONNECTIVITY_CHANGE"))    {
                //移动数据连接上时
                if (gprs.isConnected()){
                }
                //wifi连接上时
                if (wifi.isConnected()) {
                    // 切换网络,关闭wifi,开启流量
                    if (isShow) {//做一个标记,避免多次弹窗的叠加bug,初始值为true,重要
                        switchNetwork(context);
                    }
                }
                //断网时
                if (!netManager.getGRPS().isConnected() || !netManager.getGRPS().isConnected()) {
                }
            }


二、弹窗


 弹窗一般用四种常用的方式:

1、使用popupwindow

2、使用dialog

3、WindowManager

4、系统弹窗

 一般的弹窗需要依附于activity,在activity中弹窗,但是在服务中,不能简单的使用这种方式,一般是采用系统的弹窗,他的优先级很高,覆盖于应用界面的最高层,并且要设置setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT),要不然会崩溃的。

    private void switchNetwork(final Context context) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AlertDialog);
        builder.setTitle("提示");
        builder.setMessage("请关闭wifi,打开移动网络");
        builder.setCancelable(false);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 控制网络的开关
                controlNetWork(context);
                isShow = true;
            }
        });
        AlertDialog dialog = builder.create();
        // 需要把对话框的类型设为TYPE_SYSTEM_ALERT,否则对话框无法在广播接收器里弹出
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        dialog.show();
        isShow = false;
    }


三、网络切换


 wifi的网络切换比较容易,直接设置setWifiEnabled就可以完成切换,而数据流量的切换比较麻烦,他的方法是私有的,无法调用,我们可以通过反射,找到他的方法进行调用:具体看代码


    private void controlNetWork(Context context) {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        // 允许流量,阻止wifi
        wifiManager.setWifiEnabled(false);//false表示断开WiFi
        ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean connected = conn.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected();
        if (!connected) {
            ConnectivityManager gprsCM = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            Class conmanClass;
            try {
                conmanClass = Class.forName(gprsCM.getClass().getName());
                final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
                iConnectivityManagerField.setAccessible(true);
                final Object iConnectivityManager = iConnectivityManagerField.get(gprsCM);
                final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
                final Method setMobileDataEnabledMethod = iConnectivityManagerClass
                        .getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
                setMobileDataEnabledMethod.setAccessible(true);//true表示连接网络
                setMobileDataEnabledMethod.invoke(iConnectivityManager, true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

在清单文件中注册广播

<receiver
            android:name=".NetChangeReceiver"
            android:label="NetChangeReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
</receiver>

添加权限:

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

以上代码很详细的描述了网络切换的实时检测,更加详细丰富的就不在这里写出来了。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Android ,可以通过 `ConnectivityManager` 来监听网络连接状态的变化,包括 WiFi移动数据切换。 具体实现步骤如下: 1. 在 `AndroidManifest.xml` 添加以下权限: ```xml <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> ``` 2. 在需要进行监听的 `Activity` 或 `Service` ,创建一个 `ConnectivityManager.NetworkCallback` 的回调类: ```java private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { // 网络连接可用 super.onAvailable(network); Log.d(TAG, "onAvailable: " + network); } @Override public void onLost(Network network) { // 网络连接丢失 super.onLost(network); Log.d(TAG, "onLost: " + network); } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { // 网络连接属性变化 super.onCapabilitiesChanged(network, networkCapabilities); Log.d(TAG, "onCapabilitiesChanged: " + networkCapabilities); } }; ``` 3. 在 `onCreate()` 方法获取 `ConnectivityManager` 对象,并注册监听回调: ```java ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); connectivityManager.registerNetworkCallback(new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) // 监听移动数据连接 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // 监听 WiFi 连接 .build(), networkCallback); ``` 4. 在 `onDestroy()` 方法取消监听回调: ```java connectivityManager.unregisterNetworkCallback(networkCallback); ``` 这样,就可以监听网络连接状态的变化,包括 WiFi移动数据切换了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值