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

ConnectivityManager类

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

一、注册广播

写一个类继承自BroadcastReceiver。

        @Overridepublic 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() {@Overridepublic 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);// 允许流量,阻止wifiwifiManager.setWifiEnabled(false);//false表示断开WiFiConnectivityManager 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();}}

在清单文件中注册广播

<receiverandroid: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"/>

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

Android中wifi与数据流量的切换监听相关推荐

  1. 解决:android 开发 WIFI 功能 密码输入正确时监听的问题

    问题描述: 在一个 android 项目中 需要 开发 类似于 系统 wifi 连接的功能,选择可用 wifi 后,输入正确的密码后,WifiManager.SUPPLICANT_STATE_CHAN ...

  2. android 发送彩信监听,在Android中发送短信和彩信,监听短信并显示

    发送短信: String body="this is sms demo"; Intent mmsintent = new Intent(Intent.ACTION_SENDTO, ...

  3. android onscrolllistener判断到底部,android中RecycleView添加下滑到底部的监听示例

    我们的日常开发中经常用到下拉刷新,而网上评价最好的开源下拉刷新组件当然还是android-Ultra-Pull-To-Refresh此组件可以给任何的控件添加下拉刷新功能.当然也包括recyclevi ...

  4. Android手机同时使用Wi-Fi和数据流量

    Android手机同时使用Wi-Fi和数据流量 大家都知道,当手机成功连接到Wi-Fi热点以后,手机所产生的上网流量都是通过Wi-Fi来传输的,而手机的移动流量会被禁用.但是,我们现在有特殊的业务需求 ...

  5. android 手机同时使用wifi 和数据流量(3G/4G...)

    Android手机同时使用Wi-Fi和数据流量 大家都知道,当手机成功连接到Wi-Fi热点以后,手机所产生的上网流量都是通过Wi-Fi来传输的,而手机的移动流量会被禁用.但是,我们现在有特殊的业务需求 ...

  6. 苹果7无线网怎么连接电脑连接服务器,iPhone7怎么连接Wifi无线网络?苹果iPhone7 wifi和网络流量自动切换吗?...

    iPhone7与7 Plus运行的都是iOS 10系统,体验非常出色,那么iPhone7怎么连Wifi?iPhone7无线网络怎么连接?iPhone7 wifi和网络流量自动切换吗?下面脚本之家的小编 ...

  7. Android中使用的数据单位

    Android中使用的数据单位 px(Pixels,像素):对应屏幕上的实际像素点. in(Inches,英寸):屏幕物理长度单位. mm(Millimeters,毫米):屏幕物理长度单位. pt(P ...

  8. Android中wifi认证的实现

    WiFi需要登录的情况(WiFi重定向) 检测wifi是否需要portal验证 公共场所wifi验证 关于wifi portal认证–为浏览器添加wifi认证功能 Android中wifi的扫描机制 ...

  9. Android中清除应用数据的方法

    Android 中应用的数据分为内置储存的和外置储存,默认是保存在内置储存的,所以一般清除内置储存的就行了.使用这个工具类: import java.io.File;public class Data ...

最新文章

  1. 精选180+Python开源项目,随你选!做项目何愁没代码
  2. 厉害了!写代码、搜问题,全部都在「终端」完成!如此编程神器,是时候入手了...
  3. OpenCV环境下Laplace(拉普拉斯)和Roberts基本边缘检测算子的实现代码
  4. Qt QWidget实现消息提示控件TipsWidget
  5. jpa的查询api_为JPA的本机查询API键入安全查询
  6. 判断该网页是在什么设备打开。
  7. Secondary Namenode的Check point机制以及Namenode、Datanode工作机制说明
  8. printf的缓存问题
  9. svn里 is already locked
  10. 应届生面试技巧心得及选择工作走向的分析
  11. 数据库系统SQL编程-02
  12. java计算机毕业设计会议管理系统MyBatis+系统+LW文档+源码+调试部署
  13. EMLOG模板山河网站主题分享
  14. 蚂蚁海图tms切片工具
  15. python:画python,即绘制蟒蛇图像
  16. Java封装的四个关键字
  17. Xilinx Ultrascale+ 使用PRC向ICAP E3核输入码流重构时无反应
  18. 回忆数学老前辈孙元远先生
  19. 数据库设计中的命名规范
  20. android修改默认遥控器键值,android 中遥控器键值的添加和修改

热门文章

  1. 李力游辞去紫光集团联席总裁一职
  2. 电子秤称重传感器常见故障及解决办法
  3. 三坐标测量时为什么要进行测头校验
  4. FIRST集和FOLLOW集
  5. 你知道seo到底是什么吗?该怎么优化?
  6. HTML超文本标记语言
  7. 评论:Java 7并发食谱
  8. 完美日记、钟薛高等新消费品牌的崛起,给传统零售企业带来哪些启发?
  9. 2018年江苏省监理工程师考试软件练习题库模拟测试免费下载注册机码监理工程师教材2018江苏省监理人员业务培训教程习题集模拟考自测
  10. 每个人都应该了解的金融小知识 -- 利率计算 (含一道码农面试题)