Android网络是否可用

转自:http://chen592969029.iteye.com/blog/2108412

Android访问网络有很多种方式,比如WiFi,移动网络(3G等)...

他们是有一个优先级的。

  • 当WiFi连接,打开3G网络,3G网络将被自动屏蔽;
  • 当3G连接,连接WiFi,3G网络将被屏蔽,启用WiFi;
  • 当WiFi连接,然后关闭,如果3G网络可用,将自动切换到3G网络。

这是系统默认的,可以通过API来改变这种优先级。比如:当3G连接,连接WiFi,我们希望仍然使用3G网络,那么

Java代码   收藏代码
  1. ConnectivityManager connMgr = (ConnectivityManager)  
  2.                 getSystemService(Context.CONNECTIVITY_SERVICE);          
  3. connMgr.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);  

当这样设置之后,会自动断开WiFi连接。

那通过代码,怎么知道WiFi是否连接或者移动网络是否连接呢?

Java代码   收藏代码
  1. //判断是否有网络连接  
  2.     public boolean isOnline() {  
  3.         ConnectivityManager connMgr = (ConnectivityManager)  
  4.                 getSystemService(Context.CONNECTIVITY_SERVICE);  
  5.         NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();  
  6.         //connMgr.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);  
  7.         return (networkInfo != null && networkInfo.isAvailable());  
  8.     }  
  9.     //判断WiFi是否连接  
  10.     public boolean isWifiConnected() {  
  11.         ConnectivityManager connMgr = (ConnectivityManager)  
  12.                 getSystemService(Context.CONNECTIVITY_SERVICE);  
  13.         NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);  
  14.         return (networkInfo != null && networkInfo.isConnected());  
  15.     }  
  16.     //判断移动网络是否连接  
  17.     public boolean isMobileConnected() {  
  18.         ConnectivityManager connMgr = (ConnectivityManager)  
  19.                 getSystemService(Context.CONNECTIVITY_SERVICE);  
  20.         NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);  
  21.         return (networkInfo != null && networkInfo.isConnected());  
  22.     }  

 判断WiFi是否连接,还可以通过WifiManager

Java代码   收藏代码
  1. //判断WiFi是否连接  
  2.     public boolean isWifiConnected() {  
  3.         WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);  
  4.         if (wifiManager.isWifiEnabled()) {  
  5.             WifiInfo wifiInfo = wifiManager.getConnectionInfo();  
  6.   
  7.             return wifiInfo != null && SupplicantState.COMPLETED == wifiInfo.getSupplicantState();  
  8.         }  
  9.   
  10.         return false;  
  11.     }  

它还提供了很多操控WiFi的方法,比如连接或断开WiFi连接,打开或关掉WiFi等。

有WiFi连接并不等于连接到Internet。比如:手机连接到无线路由器,而无线路由器没有连接Internet,这种情况可以用代码容易地判断

Java代码   收藏代码
  1. //判断WiFi连接时是否能够访问Internet  
  2. public boolean hasWifiInternetAccess() {  
  3.     WifiManager mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);  
  4.     if(mWifiManager.isWifiEnabled()) {  
  5.         return mWifiManager.pingSupplicant();  
  6.     }  
  7.     return false;  
  8. }  

上面的方法其实并不能准确的判断当WiFi连接是是否可以访问Internet。例如,当连接到机场的WiFi,它需要打开浏览器,在弹出的页面上输入用户名密码,此时pingSupplicant返回的是TRUE,当这种情况时,只能通过代码访问某个网址,检查返回值来检测是否能够上网。

通常,为了更好的用户体验,比较大的网络请求只在有WiFi的情况下才发出,比如下载地图数据,下载高质量的音乐。因为网络请求是一个比较耗时的操作,所以不能放在主线程(UI线程)进行,了解更多请点击这里。可以使用Android中的AsyncTask发送网络请求。

Java代码   收藏代码
  1. TextView textView;  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_network_test);  
  7.   
  8.         textView = (TextView) findViewById(R.id.textView);  
  9.   
  10.         NetworkTask networkTask = new NetworkTask();  
  11.         networkTask.execute();  
  12.     }  
  13.   
  14.     private class NetworkTask extends AsyncTask<Void, Void, Void> {  
  15.         String statusCode = "";  
  16.   
  17.         @Override  
  18.         protected Void doInBackground(Void... voids) {  
  19.             //耗时操作。在这里是发送网络请求,系统会将本方法里面的代码在新的工作线程里面执行  
  20.             DefaultHttpClient client = new DefaultHttpClient();  
  21.             HttpParams params = client.getParams();  
  22.             int timeoutInMillisecond = 10000;  
  23.             HttpConnectionParams.setConnectionTimeout(params, timeoutInMillisecond);  
  24.             HttpConnectionParams.setSoTimeout(params, timeoutInMillisecond);  
  25.   
  26.             int retryTimes = 1;  
  27.             if (retryTimes > 0) {  
  28.                 client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(retryTimes, true));  
  29.             }  
  30.   
  31.             HttpGet get = new HttpGet("http://www.cchen.com");  
  32.             HttpResponse response = null;  
  33.             try {  
  34.                 response = client.execute(get);  
  35.                 statusCode = String.valueOf(response.getStatusLine().getStatusCode());  
  36.             } catch (IOException e) {  
  37.                 statusCode = "-1";  
  38.             }  
  39.             return null;  
  40.         }  
  41.   
  42.         @Override  
  43.         protected void onPostExecute(Void aVoid) {  
  44.             //更新UI。上面方法执行完毕后,系统会在主线程(UI线程)执行本方法中的代码  
  45.             textView.append(statusCode + "\n");  
  46.         }  
  47.     }  

注意,上面的HttpConnectionParams设置了两个Timeout:

  • ConnectionTimeOut,建立连接的timeout
  • SoTimeout,socket timeout,等待返回数据的timeout

上面代码设置两个timeout都是10秒。那假如手机不能上网,是不是10秒之后才会抛出异常呢?答案是否定的。

  • 如果手机不能上网,这里会立即报错。注意,这里指的是上网,不是连接WiFi或者移动网络,因为连接上了WiFi或者移动网络并不等于连接上Internet。
  • 如果手机能上网,访问某个网址,连接时间超过10秒,则会报错。例如,上面我给的网址,http://www.cchen.com,这是一个不存在的网址,因此,程序在10秒之后,屏幕显示错误码-1.

还有当我们听着音乐回到家中,手机自动连接到WiFi,这个时候程序就应该播放高质量的音乐了,那我们怎么知道手机的网络连接类型发生了变化呢?Android系统在手机网络类型发生变化的时候,会发送一个广播

Java代码   收藏代码
  1. ConnectivityManager.CONNECTIVITY_ACTION  

所以,我们只需要监听这个广播,再利用上面的代码,就能轻易得知当前网络类型,然后进行相关操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值