`
一夕剑
  • 浏览: 55253 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

[Android]正确地访问网络资源----Proxy的使用

阅读更多

天朝有很多独特的东西,今天要涉及到的是CMWAP与CMNET。

现在仍有许多Android手机用的是CMWAP连接网络的,如果只是简单滴使用URL.openConnection()开启一个HttpURLConnection,则会发现有一个UnknownHostException被抛出。唉...身为悲剧的程序员,就要开始解决这种bug了。

Sodino还发现一个现象,为什么自己的程序会崩掉,而Google浏览器就不会呢?与国产软件不同,国产软件身处天朝的软硬件环境下成长,可能会将代理IP(10.0.0.172)写进程序中,Sodino也确实反编译了几个程序后发现他们也是这样做来保持CMWAP下的正常联接。但是,Google浏览器可不是国人写的,那帮老外可不考虑天朝还有个CMWAP。那他们是如何保证网络的正常联接呢?一番鼓捣下,有了以下代码,可以在WIFI/CMWAP/CMNET/CTNET下正常访问网络,附带如何使用ping使用。

先上效果图:

 

view plaincopy to clipboardprint?
package lab.sodino.network;  
import java.io.IOException;  
import java.io.InputStream;  
import java.net.HttpURLConnection;  
import java.net.InetSocketAddress;  
import java.net.MalformedURLException;  
import java.net.URL;  
import java.net.UnknownHostException;  
import android.app.Activity;  
import android.content.Context;  
import android.net.ConnectivityManager;  
import android.net.NetworkInfo;  
import android.os.Bundle;  
import android.os.Handler;  
import android.os.Message;  
import android.util.Log;  
import android.view.View;  
import android.widget.Button;  
import android.widget.TextView;  
public class NetworkAct extends Activity {  
    public static final int CLEAR_TEXT = 0;  
    public static final int APPEND_TEXT = 1;  
    private TextView txtInfo;  
    private Button btnPing;  
    private Button btnConnect;  
    private Button btnClear;  
    private BtnListener btnListener;  
    private Handler handler = new Handler() {  
        public void handleMessage(Message msg) {  
            switch (msg.what) {  
            case APPEND_TEXT:  
                String content = msg.obj.toString();  
                txtInfo.setText("\n" + content);  
                break;  
            case CLEAR_TEXT:  
                txtInfo.setText("");  
                break;  
            }  
        }  
    };  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        btnListener = new BtnListener();  
        txtInfo = (TextView) findViewById(R.id.txtInfo);  
        btnPing = (Button) findViewById(R.id.btnPing);  
        btnPing.setOnClickListener(btnListener);  
        btnConnect = (Button) findViewById(R.id.btnConnect);  
        btnConnect.setOnClickListener(btnListener);  
        btnClear = (Button) findViewById(R.id.btnClear);  
        btnClear.setOnClickListener(btnListener);  
    }  
    /** 
     * @param param 
     *            指定的域名如(www.google.com)或IP地址。 
     */ 
    private void doPing(final String param) {  
        new Thread() {  
            public void run() {  
                String line = "";  
                InputStream is = null;  
                try {  
                    line = "\nping -c 1 " + param;  
                    // -c 1:表示ping的次数为1次。  
                    Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com");  
                    // 等待该命令执行完毕。  
                    int status = p.waitFor();  
                    if (status == 0) {  
                        // 正常退出  
                        line += "Pass";  
                    } else {  
                        // 异常退出  
                        line += "Fail: Host unreachable";  
                    }  
                    is = p.getInputStream();  
                    byte[] data = new byte[is.available()];  
                    is.read(data);  
                    line += "\n" + new String(data);  
                } catch (UnknownHostException e) {  
                    line += "Fail: Unknown Host";  
                } catch (IOException e) {  
                    line += "Fail: IOException";  
                } catch (InterruptedException e) {  
                    line += "Fail: InterruptedException";  
                }  
                Message msg = new Message();  
                msg.what = APPEND_TEXT;  
                msg.obj = line;  
                handler.sendMessage(msg);  
            }  
        }.start();  
    }  
    private void go2Network() {  
        new Thread() {  
            public void run() {  
                String line = "";  
                URL url = null;  
                HttpURLConnection httpConn = null;  
                InputStream is = null;  
                try {  
                    url = new URL("http://www.sodino.com/index.html");  
                    // Log.d("ANDROID_LAB", "Protocol=" + new  
                    // URL("https://www.sodino.com").getProtocol());  
                    // 需要android.permission.ACCESS_NETWORK_STATE  
                    NetworkInfo networkInfo = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE))  
                            .getActiveNetworkInfo();  
                    // 如果是使用的运营商网络  
                    if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {  
                        // 获取默认代理主机ip  
                        String host = android.net.Proxy.getDefaultHost();  
                        // 获取端口  
                        int port = android.net.Proxy.getDefaultPort();  
                        if (host != null && port != -1) {  
                            line += "\nhost[" + host + "] port[" + port + "]";  
                            // 封装代理連接主机IP与端口号。  
                            InetSocketAddress inetAddress = new InetSocketAddress(host, port);  
                            // 根据URL链接获取代理类型,本链接适用于TYPE.HTTP  
                            java.net.Proxy.Type proxyType = java.net.Proxy.Type.valueOf(url  
                                    .getProtocol().toUpperCase());  
                            java.net.Proxy javaProxy = new java.net.Proxy(proxyType, inetAddress);  
                            httpConn = (HttpURLConnection) url.openConnection(javaProxy);  
                        } else {  
                            httpConn = (HttpURLConnection) url.openConnection();  
                        }  
                    } else {  
                        httpConn = (HttpURLConnection) url.openConnection();  
                    }  
                    httpConn.connect();  
                    int length = httpConn.getContentLength();  
                    byte[] data = new byte[length];  
                    String encoding = httpConn.getContentEncoding();  
                    line += "\nlength=" + length + " encoding=" + encoding;  
                    is = httpConn.getInputStream();  
                    is.read(data);  
                    String content = null;  
                    if (encoding != null) {  
                        content = new String(data, encoding);  
                    } else {  
                        content = new String(data);  
                    }  
                    line += "\nContent[\n" + content + "\n]";  
                    Message msg = new Message();  
                    msg.what = APPEND_TEXT;  
                    msg.obj = line;  
                    handler.sendMessage(msg);  
                } catch (IOException ie) {  
                    ie.printStackTrace();  
                } finally {  
                    try {  
                        if (is != null) {  
                            is.close();  
                        }  
                        if (httpConn != null) {  
                            httpConn.disconnect();  
                        }  
                    } catch (IOException ie) {  
                        ie.printStackTrace();  
                    }  
                }  
            }  
        }.start();  
    }  
    class BtnListener implements Button.OnClickListener {  
        public void onClick(View view) {  
            if (view == btnPing) {  
                // doPing("www.google.com");  
                doPing("10.0.0.172");  
            } else if (view == btnConnect) {  
                go2Network();  
            } else if (view == btnClear) {  
                Message msg = new Message();  
                msg.what = CLEAR_TEXT;  
                handler.sendMessage(msg);  
            }  
        }  
    }  

package lab.sodino.network;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class NetworkAct extends Activity {
 public static final int CLEAR_TEXT = 0;
 public static final int APPEND_TEXT = 1;
 private TextView txtInfo;
 private Button btnPing;
 private Button btnConnect;
 private Button btnClear;
 private BtnListener btnListener;
 private Handler handler = new Handler() {
  public void handleMessage(Message msg) {
   switch (msg.what) {
   case APPEND_TEXT:
    String content = msg.obj.toString();
    txtInfo.setText("\n" + content);
    break;
   case CLEAR_TEXT:
    txtInfo.setText("");
    break;
   }
  }
 };
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  btnListener = new BtnListener();
  txtInfo = (TextView) findViewById(R.id.txtInfo);
  btnPing = (Button) findViewById(R.id.btnPing);
  btnPing.setOnClickListener(btnListener);
  btnConnect = (Button) findViewById(R.id.btnConnect);
  btnConnect.setOnClickListener(btnListener);
  btnClear = (Button) findViewById(R.id.btnClear);
  btnClear.setOnClickListener(btnListener);
 }
 /**
  * @param param
  *            指定的域名如(www.google.com)或IP地址。
  */
 private void doPing(final String param) {
  new Thread() {
   public void run() {
    String line = "";
    InputStream is = null;
    try {
     line = "\nping -c 1 " + param;
     // -c 1:表示ping的次数为1次。
     Process p = Runtime.getRuntime().exec("ping -c 1 www.google.com");
     // 等待该命令执行完毕。
     int status = p.waitFor();
     if (status == 0) {
      // 正常退出
      line += "Pass";
     } else {
      // 异常退出
      line += "Fail: Host unreachable";
     }
     is = p.getInputStream();
     byte[] data = new byte[is.available()];
     is.read(data);
     line += "\n" + new String(data);
    } catch (UnknownHostException e) {
     line += "Fail: Unknown Host";
    } catch (IOException e) {
     line += "Fail: IOException";
    } catch (InterruptedException e) {
     line += "Fail: InterruptedException";
    }
    Message msg = new Message();
    msg.what = APPEND_TEXT;
    msg.obj = line;
    handler.sendMessage(msg);
   }
  }.start();
 }
 private void go2Network() {
  new Thread() {
   public void run() {
    String line = "";
    URL url = null;
    HttpURLConnection httpConn = null;
    InputStream is = null;
    try {
     url = new URL("http://www.sodino.com/index.html");
     // Log.d("ANDROID_LAB", "Protocol=" + new
     // URL("https://www.sodino.com").getProtocol());
     // 需要android.permission.ACCESS_NETWORK_STATE
     NetworkInfo networkInfo = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE))
       .getActiveNetworkInfo();
     // 如果是使用的运营商网络
     if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
      // 获取默认代理主机ip
      String host = android.net.Proxy.getDefaultHost();
      // 获取端口
      int port = android.net.Proxy.getDefaultPort();
      if (host != null && port != -1) {
       line += "\nhost[" + host + "] port[" + port + "]";
       // 封装代理連接主机IP与端口号。
       InetSocketAddress inetAddress = new InetSocketAddress(host, port);
       // 根据URL链接获取代理类型,本链接适用于TYPE.HTTP
       java.net.Proxy.Type proxyType = java.net.Proxy.Type.valueOf(url
         .getProtocol().toUpperCase());
       java.net.Proxy javaProxy = new java.net.Proxy(proxyType, inetAddress);
       httpConn = (HttpURLConnection) url.openConnection(javaProxy);
      } else {
       httpConn = (HttpURLConnection) url.openConnection();
      }
     } else {
      httpConn = (HttpURLConnection) url.openConnection();
     }
     httpConn.connect();
     int length = httpConn.getContentLength();
     byte[] data = new byte[length];
     String encoding = httpConn.getContentEncoding();
     line += "\nlength=" + length + " encoding=" + encoding;
     is = httpConn.getInputStream();
     is.read(data);
     String content = null;
     if (encoding != null) {
      content = new String(data, encoding);
     } else {
      content = new String(data);
     }
     line += "\nContent[\n" + content + "\n]";
     Message msg = new Message();
     msg.what = APPEND_TEXT;
     msg.obj = line;
     handler.sendMessage(msg);
    } catch (IOException ie) {
     ie.printStackTrace();
    } finally {
     try {
      if (is != null) {
       is.close();
      }
      if (httpConn != null) {
       httpConn.disconnect();
      }
     } catch (IOException ie) {
      ie.printStackTrace();
     }
    }
   }
  }.start();
 }
 class BtnListener implements Button.OnClickListener {
  public void onClick(View view) {
   if (view == btnPing) {
    // doPing("www.google.com");
    doPing("10.0.0.172");
   } else if (view == btnConnect) {
    go2Network();
   } else if (view == btnClear) {
    Message msg = new Message();
    msg.what = CLEAR_TEXT;
    handler.sendMessage(msg);
   }
  }
 }
}

如此,悲剧的程序员解决了不同网络状态下如何保证正常链接的问题。

最后补充下:Android手机在CMWAP上要能够正常上网,除了设置一大堆代理数据外,还需进入拨号器下按"*#*#4636#*#*"→Phone Information下拉到最后后有个“Toggle DNS Check”,将其设置为allow

转载自:http://blog.csdn.net/sodino/archive/2011/04/05/6302313.aspx

分享到:
评论

相关推荐

    dnsproxy2 --Android系统DNS修改工具优化版

    DNS(Domain Name System)是互联网上的一个关键组件,它负责将人类可读的域名转换为IP地址,以便设备能够访问相应的网络资源。 在Android系统中,DNS设置通常是固定的,可能由网络运营商或系统默认设定。DNSproxy2...

    webview通过代理访问网络

    因此,当用户更改系统代理设置后,Webview的网络访问也会相应地改变。 总结一下,实现Webview通过代理访问网络的步骤主要包括: 1. 添加必要的网络权限。 2. 在Webview的生命周期方法中控制对系统代理设置的响应。...

    charles-proxy3.9.2-for-mac含注册码

    **Charles Proxy 3.9.2 for Mac:网络请求抓包神器** Charles Proxy是一款强大的网络代理和抓包工具,尤其适用于Mac用户。它允许开发者监控、记录和分析应用程序的网络流量,这对于调试、优化和理解应用程序如何与...

    charles-proxy-4.5.6.dmg.zip

    《Charles Proxy 4.5.6:网络调试利器解析》 Charles Proxy,简称为Charles,是一款强大的网络代理和抓包工具,尤其在软件开发、测试和网络调试领域中备受推崇。本文将详细介绍Charles 4.5.6版本的主要功能、使用...

    android studio 在线升级pac代理

    PAC代理是一种自动配置代理服务器的方式,它可以智能地选择最快速的网络路径来访问互联网资源。 首先,我们需要理解PAC文件的作用。PAC文件(通常扩展名为.js)包含了一段JavaScript代码,该代码定义了一个函数`...

    Android-SDK更新.

    它包含了开发者创建、调试和发布Android应用所需的库文件、文档以及示例代码等资源。Android SDK是构建高质量Android应用的基础。 #### 二、SDK Manager介绍 SDK Manager是一个集成在Android Studio中的工具,用于...

    Part-04-Android的IPC & Service.rar

    Proxy模式是一种设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在Android中,Proxy模式常用于跨进程调用,特别是在IPC中,由于进程间的隔离,我们需要一个代理类来封装服务端的接口,使得客户端可以像...

    Android源码下载出现的问题

    在Android开发领域,获取源码是深入理解系统工作原理、定制化开发或进行故障排查的重要步骤。本篇文章将聚焦于“Android...通过不断尝试和学习,你将能够成功地获取并构建Android源码,从而开启你的Android开发之旅。

    ec20模块qmi_wwan拨号工具

    对于EC20模块,需要安装相应的驱动程序才能使系统正确地与模块通信。在提供的压缩包"quectel-CM"中,很可能包含了用于Linux系统的EC20模块驱动以及相关的配置和管理工具。 驱动程序的安装通常包括以下几个步骤: 1....

    14年android SDK更新方法

    当前,开发者通常会使用Android Studio内置的SDK Manager进行更新,该工具提供了一个图形化的用户界面,更方便地管理SDK组件。同时,Google也提供了命令行工具`sdkmanager`,允许开发者通过终端或脚本自动化SDK的...

    Gradle failed

    这条错误信息表明构建过程中尝试通过代理服务器访问网络资源时失败,并且代理服务器返回了“400 Bad Request”的HTTP状态码。这意味着代理服务器拒绝了请求,可能是由于配置不正确或其他原因导致的。 #### 解决方案...

    B4A初级教程

    - **Running the Emulator through a proxy via the Command prompt(通过命令提示符使用代理运行模拟器)**: 提供解决方案来解决模拟器网络连接问题。 - **日历数据同步** - **Send data to Android calendar...

    introduction-to-alljoyn

    8. 对象模型和远程方法调用:AllJoyn通过对象模型和远程方法调用(Remote Method Invocation, RMI)提供了一个直观的方式来访问网络中的资源和服务。 9. 软件组件:AllJoyn提供了一系列软件组件,帮助开发者以模块...

    xamarin signalr 客户端下载

    1. 访问Xamarin官网或相关资源页面,找到适用于Xamarin Android的SignalR客户端dll文件,本案例中为"signalr.client"。 2. 将下载的dll文件添加到Xamarin Android项目的引用目录下。 ### 四、引入SignalR客户端库 ...

    初试vue-cli使用HBuilderx打包app的坑

    5. iPhoneX适配问题:在iPhoneX上由于底部安全区的存在,可能会导致导航栏不能正确地显示在最底部。为解决这一问题,在index.html的标签中添加viewport-fit=cover,以适应安全区。 6. 打开第三方链接时遇到的问题:...

    windows版Charles抓包工具

    总结来说,Windows版Charles是一款功能强大的网络抓包工具,无论是在Android应用开发还是其他网络相关工作,都能提供宝贵的辅助作用。通过深入理解和熟练运用,开发者可以更有效地调试和优化其产品。

    Java资源包01

    开发它是用于在UTF-8 Oracle实例中使用ASCII编码的Oracle 数据库中来正确的传输非ASCII字符。 Java模板语言 Beetl Beetl,是Bee Template Language的缩写,它绝不是简单的另外一种模板引擎,而是新一代的模板引擎,...

    电信多媒体彩信相关资料

    - 使用Java、Swift或其他编程语言集成MMS库,实现发送和接收彩信的功能,并处理可能出现的网络、格式转换等问题。 6. **彩信服务管理** - 对于电信运营商,管理彩信服务包括监控服务质量、容量规划、故障排查等。...

Global site tag (gtag.js) - Google Analytics