欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-19 18:12:34
最近在做一个wifi和移动数据的监控功能,来来回回折腾了一阵子,这个模块的主要功能是监听整个app的wifi与数据流量的切换,让用户使用专用流量,而不是用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、在清单文件中注册广播

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

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

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