修改Android AP的SSID和SharedKey

WifiManager中含有可以修改AP模式下SSID和SharedKey的方法,在源码中可以看到这部分方法被@hide了,也就是被隐藏了,不过只要利用反射即可调用这些方法。

咱在设置SSID和SharedKey时,发现几个需要注意的点:

  1. 写入系统设置的权限,可以通过Intent的方式提示用户给予权限
  2. <uses -permission android:name="android.permission.ACCESS_WIFI_STATE"></uses>
    <uses -permission android:name="android.permission.CHANGE_WIFI_STATE"></uses>
    <uses -permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses>
    <uses -permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses>
    <uses -permission android:name="android.permission.WRITE_SETTINGS"></uses>
  3. 设置AP模式的参数,会同时自动打开AP(无法在关闭AP的情况下,写入设置,这一点,可以从下面的代码看到,当setWifiApEnable的第三个参数为false时,随便填个null,因为设置是不会更新的,所以为了设置AP的各种参数,必须先关闭AP,然后填充WifiConfiguration结构,最后把setWifiApEnable设置为true,设置完成并打开AP。),并且需要提前关闭WIFI,两者不能共存
  4. 有些手机只支持WPA2_PSK加密方式,看了下源码,貌似这种加密方式在WifiConfiguration结构里面并没有看到,然后看到有些人的说法是被隐藏了,具体情况,咱不太清楚,反正源码确实没有看到对应的字段,所以自己一直卡在这里,没法更新AP的密码,后面看到网上有的设置为4,之后便可以使用WPA2_PSK加密方式了。。。。

下面是部分代码片段

 
    private void initAP_Service(){
        mWiFiManager=(WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
        mWiFiManager.setWifiEnabled(false); //先确定WIFI已经关闭
    }
 
    private boolean setAP_Config(String ssid,String sharedKey,boolean  enabled){
        Method method;
        if(getWifiAPState()!=11){//判断AP是否已经打开
            try {
                 method = mWiFiManager.getClass().getMethod("setWifiApEnabled",
                        WifiConfiguration.class, boolean.class);
                 method.invoke(mWiFiManager, null, false);//先关掉,false时,不会更新AP设置,关闭AP。true的情况下,才会更新AP设置,自动打开AP
                 Thread.sleep(2000);//AP关闭,需要一定时间,随便填的,可以自行调整
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            WifiConfiguration apConfig = new WifiConfiguration();
 
            apConfig.SSID=ssid;
            apConfig.preSharedKey=sharedKey;
 
            apConfig.hiddenSSID=false;//是否隐藏SSID
            apConfig.allowedKeyManagement.set(4);//设置WPA2_PSK加密方式
            apConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            apConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            apConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
 
            method = this.mWiFiManager.getClass().getMethod(
                    "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
            return (Boolean) method.invoke(mWiFiManager, apConfig, enabled);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                return false;
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                return false;
            }
             catch (NoSuchMethodException e) {
                e.printStackTrace();
                 return false;
        }
    }
 
    private int getWifiAPState() {
        int state = -1;
        try {
            Method method = mWiFiManager.getClass().getMethod("getWifiApState");
            state=(Integer)method.invoke(mWiFiManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return state;
    }

需求还涉及修改AP模式下的Ethernet IP,但是这个在DHCP服务的源码中被固定为192.168.43.1了,即使使用ifconfig(需要提权,所以没有多大意义,只是用来测试高权限模式下修改IP的情况)修改了,只要每次DHCP服务重启,IP就会重置回去,所以如果需要修改这部分,需要修改framework层。

还有APN配置,因为配置没法在一般权限下进行,所以要不就是提权至System,要不就是在内核态下提供接口让上层应用进行修改。

Leave a Reply

Your email address will not be published. Required fields are marked *