Android中wifi与数据流量的切换监听详解
发布时间 - 2026-01-10 22:25:24 点击率:次最近在做一个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、在清单文件中注册广播
<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"/>
以上代码很详细的描述了网络切换的实时检测,更加详细丰富的就不在这里写出来了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# android
# 监听wifi切换
# 监听流量
# Android实现WIFI和GPRS网络的切换
# 做一个
# 对话框
# 上时
# 是一个
# 来了
# 在这里
# 好了
# 就不
# 设为
# 会在
# 我们可以
# 很高
# 弹出
# 还有一个
# 四种
# 装了
# 这里面
# 主要功能
# 比较容易
# 很适合
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
郑州企业网站制作公司,郑州招聘网站有哪些?
如何快速搭建自助建站会员专属系统?
Java类加载基本过程详细介绍
python中快速进行多个字符替换的方法小结
Laravel如何使用查询构建器?(Query Builder高级用法)
网站页面设计需要考虑到这些问题
如何在万网利用已有域名快速建站?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
如何在IIS服务器上快速部署高效网站?
Android利用动画实现背景逐渐变暗
C#如何调用原生C++ COM对象详解
Android滚轮选择时间控件使用详解
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
如何解决hover在ie6中的兼容性问题
北京网站制作公司哪家好一点,北京租房网站有哪些?
Laravel如何处理异常和错误?(Handler示例)
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
Bootstrap整体框架之JavaScript插件架构
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
linux top下的 minerd 木马清除方法
如何在万网开始建站?分步指南解析
HTML 中动态设置元素 name 属性的正确语法详解
如何在IIS7中新建站点?详细步骤解析
如何快速查询网站的真实建站时间?
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Laravel如何实现本地化和多语言支持?(i18n教程)
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
Laravel Session怎么存储_Laravel Session驱动配置详解
如何登录建站主机?访问步骤全解析
JavaScript如何实现错误处理_try...catch如何捕获异常?
Laravel怎么使用artisan命令缓存配置和视图
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
zabbix利用python脚本发送报警邮件的方法
使用Dockerfile构建java web环境
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
如何在局域网内绑定自建网站域名?
Laravel如何记录自定义日志?(Log频道配置)
Android仿QQ列表左滑删除操作
如何将凡科建站内容保存为本地文件?
Laravel如何创建自定义Artisan命令?(代码示例)
如何在 Pandas 中基于一列条件计算另一列的分组均值
怎么用AI帮你设计一套个性化的手机App图标?
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
如何在阿里云服务器自主搭建网站?
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法

