平时,3G和WIFI 都开着的时候,Android默认使用Wifi,但现实环境中不可能到处都有wifi,所以手机会经常自动切换网络。

有的时候,手机一开始使用wifi上网,当进入待机后10-30分钟,会自动从Wifi切换到3G网络。

如果编写网络程序,网络自动切换对程序的影响是非常明显的,IP地址肯定会变化。

感觉Android环境与我们日常用的windows环境还是有很大不同的,写Android程序,明显需要注意的细节有很多。

------------------------------------------------------------------------------------------------------------------------------------------------

下面附上相关的一些代码:
//listen 网络连接状态:  全部断开,当前正在使用Wifi网络,当前正在使用mobile网络,这个主要用于数据通讯时使用的线路判断

UpdateReceiver  receiver = new UpdateReceiver();

filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

registerReceiver(receiver, filter); //注册,开始接听广播

//接收来自Service的广播消息
 class UpdateReceiver extends BroadcastReceiver
 {
  private int previousNetType = -1;

@Override
  public void onReceive(Context context, Intent intent)
  {
   //System.out.println("接收到的广播信息:" + intent + "------" + intent.getExtras());

String action = intent.getAction();

if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION))
   {
    //listen:网络状态已变化 -> 断网 or 移动网络上线 or wifi网络上线 or 移动网络与wifi切换  
    //通过 intent.getExtras() 能提到详细的网络变化参数信息

//ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    //NetworkInfo mobileNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    //NetworkInfo wifiNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); //当前的
    NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); //另一个网络状态

boolean hasNoConnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); //检查是否网络全部断开  
    boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false); //是不是wifi 和 3g在切换 | 故障转移   
    //String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);  //原因,因什么而change

if (hasNoConnected)
    {
     previousNetType = -1;

isNetOnLine = false;

if (currentFriend != null)
     {
      addSystemTipToTalk("网络已断开,你已离线.", currentFriend.getNumber());
     }

//如果手机之前是通过wifi上网,同时关闭了3G数据网络,当进入锁屏后,可能是几分钟时间,android一般会自动关闭wifi连接,需要声音提示
     if (activityIsStoped || mKeyguardManager.inKeyguardRestrictedInputMode())
     {
      showNotify(A.ID_NOTIFY_GOING, getResources().getString(R.string.app_name), "网络已断开,你已离线.", "网络已断开,你已离线.", R.drawable.ic_stat_logo,
        Notification.FLAG_NO_CLEAR);
     }
     else
     {
      showSystemTip("网络已断开,你已离线.");
     }
    }
    else
    {
     isNetOnLine = true;

if (isFailover || otherNetworkInfo == null)
     {
      if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
      {
       if (previousNetType != ConnectivityManager.TYPE_WIFI && networkInfo.isConnected())
       {
        previousNetType = ConnectivityManager.TYPE_WIFI;

if (currentFriend != null)
        {
         addSystemTipToTalk("WIFI网络已启用.", currentFriend.getNumber());
        }

showSystemTip("WIFI网络已启用");

//由于刚刚切换网络,不能马上发送数据,等几秒后再发,比较可靠
        new Thread(new Runnable() {
         public void run()
         {
          try
          {
           Thread.sleep(2000);
          }
          catch (InterruptedException e)
          {
          }
          sendBroadcast(XinTiaoService.INTENT_XINTIAO); //通知服务器,我切换了网络
         }
        }).start();

}
      }
      else
      {
       if (previousNetType == ConnectivityManager.TYPE_WIFI || previousNetType == -1)
       {
        if (networkInfo.isConnected())
        {
         previousNetType = ConnectivityManager.TYPE_MOBILE;

if (currentFriend != null)
         {
          addSystemTipToTalk(networkInfo.getSubtypeName() + "网络已启用.", currentFriend.getNumber());
         }

showSystemTip(networkInfo.getSubtypeName() + "网络已启用");

//由于刚刚切换网络,不能马上发送数据,等几秒后再发,比较可靠
         new Thread(new Runnable() {
          public void run()
          {
           try
           {
            Thread.sleep(2000);
           }
           catch (InterruptedException e)
           {
           }
           sendBroadcast(XinTiaoService.INTENT_XINTIAO); //通知服务器,我切换了网络
          }
         }).start();
        }
       }
      }
     }

2011-11-27

Android: 网络随时需要在3G和Wifi切换,网络程序需要注意的更多相关文章

  1. android 获取网络类型名称2G 3G 4G wifi

    首先工程Manifest文件要引用: <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ...

  2. Android网络类型判断(2g、3g、wifi)

    判断网络类型是wifi,还是3G,还是2G网络,对不同 的网络进行不同的处理,现将判断方法整理给大家,以供参考   说明:下面用到的数据移动2G,联通2G,联通3G,wifi我都已经测试过,暂时手上 ...

  3. 转:Android 判断用户2G/3G/4G移动数据网络

    Android 判断用户2G/3G/4G移动数据网络 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以 ...

  4. Android 判断用户2G/3G/4G移动数据网络

    Android 判断用户2G/3G/4G移动数据网络 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以 ...

  5. 判断是否联网_检测网络的类型为3G、2G、wap、wifi

    判断是否联网_检测网络的类型为3G.2G.wap.wifi  判断是否联网: /*** * judge Internet is available * * @author wei-spring * @ ...

  6. Android判断用户的网络类型(2/3/4G、wifi)

    很多时候需要先判断当前用户的网络,才会继续之后的一些处理逻辑.但网络类型获取这一块,我用我自己的的手机调试时遇到一些问题,这里记录一下. 一加手机一代,移动4G 网络,得到的subtype类型值为17 ...

  7. 九、Android学习第八天——广播机制与WIFI网络操作(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 九.Android学习第八天——广播机制与WIFI网络操作 今天熟悉了An ...

  8. Swift - 判端网络连接状态,连接类型(3G还是Wifi)

    IJReachability是一个使用Swift写的第三方网络检测类.可以测试网络是否连接,并支持3G和Wifi的检测. 使用样例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  9. 蜂窝移动网络是什么,它和 Wi-Fi 有什么区别? 蓝牙和无线有什么区别?

    蜂窝移动网络是什么,它和 Wi-Fi 有什么区别? 转自知乎用户的一个回答: 原题问的是"数据流量是什么",不知道怎么又被改成"蜂窝移动网络是什么"了.说下个人 ...

随机推荐

  1. Jmeter(三十二)_搭建本地接口自动化环境

    我们在学习接口自动化的时候,最理想的状态是在公司有项目可以操作.大部分时候我们并没有可以练习的项目,因此练习接口无从谈起,只能找一些开放的api来练一练,但是这样并不能提高我们的技术.因此我们需要搭建 ...

  2. Nginx基于TCP/UDP端口的四层负载均衡(stream模块)配置梳理

    通过我们会用Nginx的upstream做基于http/https端口的7层负载均衡,由于Nginx老版本不支持tcp协议,所以基于tcp/udp端口的四层负载均衡一般用LVS或Haproxy来做.至 ...

  3. 关于Runtime error

    别人说的,但我感觉是因为你的操作是不符合语言规定的,让编译器无法识别,运行不出

  4. Scapy的使用

    0.前言 最近现场测试项目时,突如其来需要伪造IGMP报文,骗取交换机相关组播流量,慌忙之下学习了Scapy的使用,以及相关快速学习的方法,在这里分享下. 1.Scapy库安装 github地址:ht ...

  5. IP工具类

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletReques ...

  6. MySQLi面向对象实践--insert、update、delete

    执行insert <?php $mysqli = new Mysqli(); $mysqli->connect("localhost","root" ...

  7. shell脚本第一课

    shell脚本的文件名一般是以.sh结尾,也可以以其他格式如.txt,甚至不加后缀. 脚本的第一行的#!/bin/bash表示指定脚本执行时的解析器. #!/bin/bash #文件名:test.sh ...

  8. CI框架在辅助函数中使用配置文件中的变量

    问题: 现有一个自定义的辅助函数,想要获取配置文件中的配置项(配置文件路径为application/config/config.php) 分析: 辅助函数并不是定义在一个class中,而是很多个可供外 ...

  9. js面向对象高级编程

    面向对象的组成 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  10. ESXi虚拟机出现关机时卡住的问题处理

    1. ESXi在日常使用时经常会遇到机器卡住的情况 这种情况下GUI的方式无从下手, 需要从cli的方式处理 我记得之前写过一个 但是不知道放哪里去了. 再重新写一下. 直接按照图处理 2. 然后xs ...