热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

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

本文主要介绍了Android中wifi与数据流量的切换监听的方法步骤。具有一定的参考价值,下面跟着小编一起来看下吧

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

网络封装类ConnectivityManager:

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

一、注册广播

1、写一个类继承自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 
      NetManager netManager = new NetManager(context); 
      if (!netManager.getGRPS().isConnected()) { 
        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(); 
        } 
      } 
    } 
  } 

2、在清单文件中注册广播

 
       
         
       
 

添加权限:



以上代码很详细的描述了网络切换的实时检测,更加详细丰富的就不在这里写出来了。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


推荐阅读
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • 原理:dismiss再弹出,把dialog设为全局对象。if(dialog!null&&dialog.isShowing()&&!(Activity.)isFinishing()) ... [详细]
  • 本文详细介绍了在Centos7上部署安装zabbix5.0的步骤和注意事项,包括准备工作、获取所需的yum源、关闭防火墙和SELINUX等。提供了一步一步的操作指南,帮助读者顺利完成安装过程。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • 本文介绍了使用SSH免密登录的步骤,包括生成公私钥、传递公钥给被登录机、修改文件权限的操作。同时提醒用户注意私钥的传递方式,建议使用U盘等离线方式传递。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • GSIOpenSSH PAM_USER 安全绕过漏洞
    漏洞名称:GSI-OpenSSHPAM_USER安全绕过漏洞CNNVD编号:CNNVD-201304-097发布时间:2013-04-09 ... [详细]
  • 本文介绍了在RHEL 7中的系统日志管理和网络管理。系统日志管理包括rsyslog和systemd-journal两种日志服务,分别介绍了它们的特点、配置文件和日志查询方式。网络管理主要介绍了使用nmcli命令查看和配置网络接口的方法,包括查看网卡信息、添加、修改和删除配置文件等操作。 ... [详细]
  • Python脚本编写创建输出数据库并添加模型和场数据的方法
    本文介绍了使用Python脚本编写创建输出数据库并添加模型数据和场数据的方法。首先导入相应模块,然后创建输出数据库并添加材料属性、截面、部件实例、分析步和帧、节点和单元等对象。接着向输出数据库中添加场数据和历程数据,本例中只添加了节点位移。最后保存数据库文件并关闭文件。文章还提供了部分代码和Abaqus操作步骤。另外,作者还建立了关于Abaqus的学习交流群,欢迎加入并提问。 ... [详细]
  •     这里使用自己编译的hadoop-2.7.0版本部署在windows上,记得几年前,部署hadoop需要借助于cygwin,还需要开启ssh服务,最近发现,原来不需要借助cy ... [详细]
  • 大坑|左上角_pycharm连接服务器同步写代码(图文详细过程)
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了pycharm连接服务器同步写代码(图文详细过程)相关的知识,希望对你有一定的参考价值。pycharm连接服务 ... [详细]
  • Hadoop2.6.0 + 云centos +伪分布式只谈部署
    3.0.3玩不好,现将2.6.0tar.gz上传到usr,chmod-Rhadoop:hadophadoop-2.6.0,rm掉3.0.32.在etcp ... [详细]
author-avatar
书友60061807
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有