1. 程式人生 > >Android 設定網路代理

Android 設定網路代理

0x00 前言

做過Android開發的同學,一定都有和服務端聯調介面的經歷,昨天才剛剛把介面調通,服務端同學“一不小心”又把介面的返回欄位格式改了,一連串的崩潰就來了,跟程式碼跟了半天,原來是服務端下發的有個欄位格式不對。這種排錯的方式,效率異常的低。如果我們能夠一開始就去check服務端下發的資料是否正確,就可以更加快速的定位問題。所以,抓包在客戶端開發中,顯得尤為重要。

0x01 抓包工具

在筆者的應用中,主要是抓HTTP/HTTPS的包,當然也有時候會抓TCP包。

常用的抓包工具有如下幾種:

  • Fiddler 可以抓HTTP/HTTPS的包(可以自己寫外掛處理網路請求與Response結果)
  • Charless 可以抓HTTP/HTTPS的包
  • WireShark 用來抓TCP的包,分析TCP報文灰常強大

上面,是筆者使用比較多的抓包工具。

PS:

  1. Charles是收費軟體,有錢的同學們建議購買正版。
  2. HTTPS的抓包與HTTP類似,只需要給手機裝上Charles的證書就行(程式碼裡面沒有對證書進行校驗才可喔。)

0x02 代理手動配置

要能夠抓到包,前提是你的手機與你的電腦要在同一個區域網上。然後將你手機的網路代理設定到你的電腦的ip上。

Fiddler 使用教程傳送門

Charles 使用教程傳送門

0x03 使用命令配置

使用命令修改Android手機系統的配置,如下程式碼:

// 設定代理
adb shell settings put global http_proxy ip_address:port

// 移除代理
adb shell settings delete global http_proxy
adb shell settings delete global global_http_proxy_host
adb shell settings delete global global_http_proxy_port

移除代理需要重啟手機方可生效,設定可直接多次覆蓋,不需要移除

使用adb來修改 settings中的值,修改的是系統的環境配置,你可以在專案中使用Java程式碼獲取到修改的值:

// 列印所有的屬性
Properties properties = System.getProperties();
for (Map.Entry<Object, Object> property : properties.entrySet()) {
    Log.d("TAG", property.getKey() + "=" + property.getValue());
}

// 僅讀取代理host和post
System.getProperty("http.proxyHost"); // https.proxyHost
System.getProperty("http.proxyPort"); // https.proxyPort

那網路請求是怎麼連線上代理設定的呢?

OKHTTP為例:

// OkHttpClient.Builder 
public Builder() {
	// 初始化
    proxySelector = ProxySelector.getDefault();
    if (proxySelector == null) {
        proxySelector = new NullProxySelector();
    }
    // 其它初始化操作省略
}

可以看到, 預設使用的是 ProxySelector.getDefault()

/**
 * Supports proxy settings using system properties This proxy selector
 * provides backward compatibility with the old http protocol handler
 * as far as how proxy is set
 *
 * Most of the implementation copied from the old http protocol handler
 *
 * Supports http/https/ftp.proxyHost, http/https/ftp.proxyPort,
 * proxyHost, proxyPort, and http/https/ftp.nonProxyHost, and socks.
 * NOTE: need to do gopher as well
 */
public abstract class ProxySelector {
    private static ProxySelector theProxySelector;
    static {
        try {
            Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector");
            if (c != null && ProxySelector.class.isAssignableFrom(c)) {
                theProxySelector = (ProxySelector) c.newInstance();
            }
        } catch (Exception e) {
            theProxySelector = null;
        }
    }
    public static ProxySelector getDefault() {
        return theProxySelector;
    }
}

可以看到,這個地方預設使用的是 DefaultProxySelector

0x04 命令修改最佳實踐

因為筆者公司的網路IP地址是動態的,每一次在手機系統裡面的網路上修改代理,這是一個讓人崩潰的事情,所以結合 0x03 中介紹的方式結合,自己寫了一個指令碼來獲取ip地址,並重設代理:

#!/bin/bash
# 可以指定網絡卡,預設使用 en0
EN0=$1
if [ ! $EN0 ]; then
	EN0="en0"
fi
echo "current network card:$EN0"
# 獲取當前網絡卡的ip地址
ipAddress=`ifconfig $EN0 | grep 'inet ' | grep -v 127.0.0.1 | cut -d\  -f2`
echo "current ip address: $ipAddress"
echo "setting android devices global http_proxy:$ipAddress:8888"
echo "  current shell:"
echo "  adb shell settings put global http_proxy $ipAddress:8888"
# 使用settings設定的命令來設定代理
adb shell settings put global http_proxy "$ipAddress:8888"%

0x05 使用Android App來修改(未完待續)