在Java中使用反射设置枚举字段

时间:2013-06-07 16:04:16

标签: java android reflection enums

我正在尝试使用反射在WifiConfiguration类中设置字段,更具体地说是ipAssignment字段。

以下是WifiConfiguration类关于ipAssignment字段的内容:

...
/**
 * @hide
 */
public enum IpAssignment {
    /* Use statically configured IP settings. Configuration can be accessed
     * with linkProperties */
    STATIC,
    /* Use dynamically configured IP settigns */
    DHCP,
    /* no IP details are assigned, this is used to indicate
     * that any existing IP settings should be retained */
    UNASSIGNED
}
/**
 * @hide
 */
public IpAssignment ipAssignment;
...

可以在此处找到完整的WifiConfiguration班级代码:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/net/wifi/WifiConfiguration.java#WifiConfiguration.0ipAssignment

默认情况下,似乎ipAssignment设置为UNASSIGNED,我想将其设置为DHCP,但我无法弄清楚如何执行此操作,因为我正在使用Reflection。 / p>

以下是我的尝试:

ipAssignment.set(ipAssignment.get(wifiConfig), Enum.valueOf((Class<Enum>) ipAssignment.getType().asSubclass(Enum.class), "DHCP")); 

但它不起作用,因为值不会改变,如下所示:

06-06 15:01:27.357: D/Enterprise Setting(5426): Setting TLS
06-06 15:01:27.357: D/Enterprise Setting(5426): Setting userName
06-06 15:01:27.357: D/Enterprise Setting(5426): Setting Password
06-06 15:01:27.367: E/WifiManager(5426): addNetwork() enter. config=* ID: -1 SSID: "MySSID" BSSID: null PRIO: 0
06-06 15:01:27.367: E/WifiManager(5426):  KeyMgmt: WPA_EAP IEEE8021X Protocols: WPA RSN
06-06 15:01:27.367: E/WifiManager(5426):  AuthAlgorithms:
06-06 15:01:27.367: E/WifiManager(5426):  PairwiseCiphers: TKIP CCMP
06-06 15:01:27.367: E/WifiManager(5426):  GroupCiphers: WEP40 WEP104 TKIP CCMP
06-06 15:01:27.367: E/WifiManager(5426):  PSK: 
06-06 15:01:27.367: E/WifiManager(5426):  eap: TLS
06-06 15:01:27.367: E/WifiManager(5426):  phase2: 
06-06 15:01:27.367: E/WifiManager(5426):  identity: userName
06-06 15:01:27.367: E/WifiManager(5426):  anonymous_identity: 
06-06 15:01:27.367: E/WifiManager(5426):  password: password
06-06 15:01:27.367: E/WifiManager(5426):  client_cert: 
06-06 15:01:27.367: E/WifiManager(5426):  private_key: 
06-06 15:01:27.367: E/WifiManager(5426):  ca_cert: 
06-06 15:01:27.367: E/WifiManager(5426): IP assignment: UNASSIGNED
06-06 15:01:27.367: E/WifiManager(5426): Proxy settings: UNASSIGNED
06-06 15:01:27.367: E/WifiManager(5426): LinkAddresses: [] Routes: [] DnsAddresses: [] 
06-06 15:01:27.367: E/WifiManager(5426): getNameForPid(5426)=com.AutoSSSIDConnection
06-06 15:01:27.407: E/WifiManager(5426): isWifiEnabled() enter.
06-06 15:01:27.407: E/WifiManager(5426): getNameForPid(5426)=com.AutoSSSIDConnection
06-06 15:01:27.407: E/WifiManager(5426): getWifiState() enter.
06-06 15:01:27.407: E/WifiManager(5426): getNameForPid(5426)=com.AutoSSSIDConnection
06-06 15:01:27.417: D/Wifi Connection(5426): Wifi Connected: true
06-06 15:01:27.417: I/System.out(5426): Wifi Connected: true
06-06 15:01:27.417: E/WifiManager(5426): getConnectionInfo() enter.
06-06 15:01:27.417: E/WifiManager(5426): getNameForPid(5426)=com.AutoSSSIDConnection
06-06 15:01:27.427: I/System.out(5426): Wifi Info: SSID: <none>, BSSID: <none>, MAC: 8c:e0:81:b1:f7:ed, Supplicant state: INACTIVE, RSSI: -200, Link speed: -1, Net ID: -1, Explicit connect: false

以下是我用来执行此操作的所有代码:

package com.AutoSSSIDConnection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.net.wifi.WifiConfiguration;
import android.util.Log;

public class WPAConfiguration {

    private static final String INT_PRIVATE_KEY = "private_key";
    private static final String INT_PHASE2 = "phase2";
    private static final String INT_PASSWORD = "password";
    private static final String INT_IDENTITY = "identity";
    private static final String INT_EAP = "eap";
    private static final String INT_CLIENT_CERT = "client_cert";
    private static final String INT_CA_CERT = "ca_cert";
    private static final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
    private static final String INT_ENTERPRISEFIELD_NAME = "android.net.wifi.WifiConfiguration$EnterpriseField";
    private static final String INT_IPASSIGNMENT = "android.net.wifi.WifiConfiguration$IpAssignment"; 
    private static final String INT_PROXYSETTINGS = "android.net.wifi.WifiConfiguration$ProxySettings";
    private static final String ENTERPRISE_EAP = "TLS";
    private static final String INT_IP_ASSIGNMENT = "ipAssignment";
    private static final String INT_PROXY_SETTINGS = "proxySettings";



    public static WifiConfiguration setWifiConfigurations(WifiConfiguration wifiConfig, String SSID, String userName, String userPass)
    {
        /*define basic configuration settings*/

        /*Access Point*/
        wifiConfig.SSID = SSID; 

        /*Priority*/
        wifiConfig.priority = 0; 

        /*Enable Hidden SSID's*/
        wifiConfig.hiddenSSID = false; 

        /*Key Management*/
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);

        /*Set Group Ciphers*/

        wifiConfig.allowedGroupCiphers.clear(); 
        wifiConfig.allowedGroupCiphers.clear();
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);


         /*Set Pairwise Ciphers*/

        wifiConfig.allowedPairwiseCiphers.clear();
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

        /*Set Protocols*/

        wifiConfig.allowedProtocols.clear();
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);


        /*Set Enterprise Settings Using Reflection*/
        try
        {
            Class<?> wifiEnterpriseField = null; 
            Class<?> wifiIpAssignmentField = null; 
            Class<?> wifiProxySettingsField = null; 

            boolean enterpriseFieldType = true; 
            boolean ipAssignmentFieldType = true; 
            boolean proxySettingsFieldType = true; 

            Field anonymousId = null, caCert = null, clientCert = null, eap = null, identity = null, password = null, phase2 = null, privateKey = null, ipAssignment = null, proxy = null; 

            Method setValue = null; 
            Method setIpName = null; 
            Method setProxy = null; 
            Class<?>[] wifiClasses = WifiConfiguration.class.getClasses(); 

            /*Get Enterprise/IP Assignment/Proxy Setting Field Class to Modify*/
            for(Class<?> wifiClass : wifiClasses)
            {
                if(wifiClass.getName().equals(INT_ENTERPRISEFIELD_NAME))
                {
                    wifiEnterpriseField = wifiClass; 
                }
                else if(wifiClass.getName().equals(INT_IPASSIGNMENT))
                {
                    wifiIpAssignmentField = wifiClass; 
                }
                else if(wifiClass.getName().equals(INT_PROXY_SETTINGS))
                {
                    wifiProxySettingsField = wifiClass; 
                }
            }

            /*Certain OS (Cupcake & Doughnut) access the enterprise field directly*/
            if(wifiEnterpriseField == null)
            {
                enterpriseFieldType = false; 
            }
            if(wifiIpAssignmentField == null)
            {
                ipAssignmentFieldType = false; 
            }
            if(wifiProxySettingsField == null)
            {
                proxySettingsFieldType = false; 
            }

            /*Get Fields*/
            Log.d("Enterprise Setting", "Getting Fields "); 
            Field[] wifiFields = WifiConfiguration.class.getFields();
            for(Field wifiField : wifiFields)
            {
                if(wifiField.getName().equals(INT_ANONYMOUS_IDENTITY))
                {
                    anonymousId = wifiField;
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField); 
                }
                else if(wifiField.getName().equals(INT_CA_CERT))
                {
                    caCert = wifiField;
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_CLIENT_CERT))
                {
                    clientCert = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_EAP))
                {
                    eap = wifiField;
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_IDENTITY))
                {
                    identity = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_PASSWORD))
                {
                    password = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_PHASE2))
                {
                    phase2 = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_PRIVATE_KEY))
                {
                    privateKey = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_IP_ASSIGNMENT))
                {
                    ipAssignment = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }
                else if(wifiField.getName().equals(INT_PROXY_SETTINGS))
                {
                    proxy = wifiField; 
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }

                else
                {
                    Log.d("Enterprise Setting", "Getting Field: " + wifiField);
                }

            }

            /*Get method to set value of enterprise fields*/
            if(enterpriseFieldType)
            {
                for(Method method : wifiEnterpriseField.getMethods())
                {
                    Log.d("Get Methods", "Enterprise Method: " + method);
                    if(method.getName().trim().equals("setValue"))
                    {
                        setValue = method; 
                        break;  
                    }
                }
            }

            /*Get method to set value of IP Assignment fields*/
            if(ipAssignmentFieldType)
            {
                for(Method method : wifiIpAssignmentField.getMethods())
                {
                    Log.d("Get Methods", "IP Method: " + method);
                    if(method.getName().trim().equals("setName"))
                    {
                        setIpName = method; 
                        break;  
                    }
                }
            }

            /*Get method to set value of IP Assignment fields*/
            if(proxySettingsFieldType)
            {
                for(Method method : wifiProxySettingsField.getMethods())
                {
                    Log.d("Get Methods", "Proxy Method: " + method);
                    if(method.getName().trim().equals("setName"))
                    {
                        setProxy = method; 
                        break;  
                    }
                }
            }
            /*Set EAP*/
            if(enterpriseFieldType)
            {
                setValue.invoke(eap.get(wifiConfig), ENTERPRISE_EAP);
                Log.d("Enterprise Setting", "Setting " + ENTERPRISE_EAP); 
            }
            else
            {
                eap.set(wifiConfig, ENTERPRISE_EAP); 
            }

            /*Set Identity*/
            if(enterpriseFieldType)
            {
                setValue.invoke(identity.get(wifiConfig), userName); 
                Log.d("Enterprise Setting", "Setting " + userName); 
            }
            else
            {
                identity.set(wifiConfig, userName); 
            }

            /*Set user password*/
            if(enterpriseFieldType)
            {
                setValue.invoke(password.get(wifiConfig), userPass); 
                Log.d("Enterprise Setting", "Setting " + userPass); 
            }
            else
            {
                password.set(wifiConfig, userPass); 
            }

            /*Set IP Protocol*/
            if(ipAssignmentFieldType)
            {
                ipAssignment.set(ipAssignment.get(wifiConfig), Enum.valueOf((Class<Enum>) ipAssignment.getType().asSubclass(Enum.class), "DHCP")); 
                //ipAssignment.set(wifiConfig, "DHCP");
                Log.d("Enterprise Setting", "Setting " + ipAssignment); 
            }
            else
            {
                ipAssignment.set(wifiConfig, "DHCP"); 
            }

            /*Set Proxy Protocol*/
            if(proxySettingsFieldType)
            {
                setProxy.invoke(proxy.get(wifiConfig), "NONE");
                Log.d("Enterprise Setting", "Setting " + proxy); 
            }
            else
            {
                proxy.set(wifiConfig, "NONE"); 
            }
        }
        catch(Exception e)
        {
            Log.e("ERROR!!!", "Error: " + e);
        }

        return wifiConfig;
    }
}

以下是用于调用上述类的Android代码:

package com.AutoSSSIDConnection;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {
    private final String userName = "userName"; 
    private final String userPassword = "Password"; 
    private final String SSID = "\"MySSID\""; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //check for current network connection to specific SSID 
        ConnectivityManager cm = (ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE);   
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if(activeNetwork == null)
        {
            this.connectToWifi(SSID, userName, userPassword); 
        }
        else
        {
            boolean isConnected = activeNetwork.isConnectedOrConnecting();
            if(!isConnected)
            {
                this.connectToWifi(SSID, userName, userPassword); 
            }
        }
    }

    public void connectToWifi(String SSID, String userName, String userPassword)
    {

        WifiConfiguration con = new WifiConfiguration(); 
        con = WPAConfiguration.setWifiConfigurations(con, SSID, userName, userPassword); 

        WifiManager wfm = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); 
        wfm.addNetwork(con); 
        boolean isWifiConnected = wfm.isWifiEnabled();
        Log.d("Wifi Connection", "Wifi Connected: " + isWifiConnected);
        System.out.println("Wifi Connected: " + isWifiConnected);
        System.out.println("Wifi Info: " + wfm.getConnectionInfo());

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

2 个答案:

答案 0 :(得分:2)

你检查了

ipAssignment.set(wifiConfig, Enum.valueOf((Class<Enum>) ipAssignment.getType().asSubclass(Enum.class), "DHCP")); 

而不是

ipAssignment.set(ipAssignment.get(wifiConfig), Enum.valueOf((Class<Enum>) ipAssignment.getType().asSubclass(Enum.class), "DHCP"));

答案 1 :(得分:1)

你使用反射的原因是什么? 作业很简单 -

ipAssignment = IpAssignment.DHCP;