MADEYE

修改 Android 系统的 Wifi 代理设置

介绍一个最近发现的 Android 私有 API

这个 API 只工作在 Android 4.0 以上的系统中,并且存在着一定的副作用。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package me.madeye;

import android.content.Context;
import android.net.ProxyProperties;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.util.Log;

import java.util.List;

public class WifiProxyManager {

  private static int networkID = -1;

  private static final String TAG = "WifiProxyManager";

  public static boolean setWifiProxy(String proxy, int port, Context context) {

    try {

      Handler handler = new Handler(context.getMainLooper());

      final WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

      if (!manager.isWifiEnabled()) return true;
      List<WifiConfiguration> configurationList = manager.getConfiguredNetworks();
      WifiConfiguration configuration = null;
      int cur = manager.getConnectionInfo().getNetworkId();
      for (WifiConfiguration wifiConfiguration : configurationList) {
        if (wifiConfiguration.networkId == cur)
          configuration = wifiConfiguration;
      }
      if (configuration == null) return true;

      WifiConfiguration config = new WifiConfiguration(configuration);
      config.ipAssignment = WifiConfiguration.IpAssignment.UNASSIGNED;
      config.proxySettings = WifiConfiguration.ProxySettings.STATIC;
      config.linkProperties.clear();

      config.linkProperties.setHttpProxy(new ProxyProperties("127.0.0.1", port, ""));
      manager.updateNetwork(config);

      manager.setWifiEnabled(false);
      handler.postDelayed(new Runnable() {
        @Override
        public void run() {
          manager.setWifiEnabled(true);
        }
      }, 1000);

      networkID = cur;
    } catch (Exception ignored) {
      // Ignore all private API exception
      Log.d(TAG, "Non support API", ignored);
      return false;
    }
    return true;
  }

  public static void clearWifiProxy(Context context) {
    if (networkID == -1) return;
    try {

      Handler handler = new Handler(context.getMainLooper());

      final WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
      List<WifiConfiguration> configurationList = manager.getConfiguredNetworks();
      WifiConfiguration configuration = null;
      for (WifiConfiguration wifiConfiguration : configurationList) {
        if (wifiConfiguration.networkId == networkID)
          configuration = wifiConfiguration;
      }
      if (configuration == null) return;

      WifiConfiguration config = new WifiConfiguration(configuration);
      config.ipAssignment = WifiConfiguration.IpAssignment.UNASSIGNED;
      config.proxySettings = WifiConfiguration.ProxySettings.NONE;
      config.linkProperties.clear();

      manager.updateNetwork(config);

      manager.setWifiEnabled(false);
      handler.postDelayed(new Runnable() {
        @Override
        public void run() {
          manager.setWifiEnabled(true);
        }
      }, 1000);

      networkID = -1;
    } catch (Exception ignored) {
      // Ignore all private API exception
      Log.d(TAG, "Non support API", ignored);
    }
  }
}

逻辑上比较简单,主要作用就是覆盖当前 Wifi 连接的代理设置,包括代理的地址和端口。代理设置后不会立即生效,需要等待用户重新连接或者由代码自动重启连接,后者可能会造成短暂的断网。

想要正常编译这个文件需要使用经过特殊处理的 SDK,假若你的项目恰好是使用 Maven 来管理的,那么你可以直接添加以下内容到你的 pom.xml 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<repositories>
    <repository>
        <id>madeye-maven-repository</id>
        <url>http://madeye-maven-repository.googlecode.com/git</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.google.android</groupId>
        <artifactId>android</artifactId>
        <version>15</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

其实这个 Private API 的潜在危险是很大的,恶意程序可以在用户完全没有察觉的情况下拦截整个系统的所有 HTTP 请求,并被用来钓鱼、中间人攻击等。

Comments