How to programmatically create and read WEP/EAP WiFi configurations in Android?

AndroidWifiAndroid Wifi

Android Problem Overview


How to programmatically create and read WEP/EAP WiFi configurations in Android?

I have seen a number of people struggling on this very question on various forums and all across the community. I know this is not that straight forward(especially EAP) to figure out because When I wanted to achieve the same I too struggled quite a lot.Well, all the hard work of code analysis and searching various implementations on the internet done with I was finally able to achieve the goal. All the credit goes to number of open source projects and their developers.

I would like to share this knowledge with all, Since SO encourages this: "It's also perfectly fine to ask and answer your own question, as long as you pretend you're on Jeopardy: phrase it in the form of a question."

Part 1: Creating a WEP WiFi configuration programmatically.

Part 2: Read a WEP WiFi configuration programmatically.

Part 3: Read a EAP WiFi Configuration programmatically.

Part 4: Save a EAP WiFi configuration programmatically.

Android Solutions


Solution 1 - Android

Part 1: Creating a WEP WiFi configuration programmatically

This is pretty much straightforward, WifiConfiguration exposes the interface to create the same. Here is the sample code:

void saveWepConfig()
{
    WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    WifiConfiguration wc = new WifiConfiguration(); 
    wc.SSID = "\"SSID_NAME\""; //IMP! This should be in Quotes!!
    wc.hiddenSSID = true;
    wc.status = WifiConfiguration.Status.DISABLED;     
    wc.priority = 40;
    wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
    wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN); 
    wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
    wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
    wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
    wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
           
    wc.wepKeys[0] = "\"aaabbb1234\""; //This is the WEP Password
    wc.wepTxKeyIndex = 0;
                         
    WifiManager  wifiManag = (WifiManager) this.getSystemService(WIFI_SERVICE);
    boolean res1 = wifiManag.setWifiEnabled(true);
    int res = wifi.addNetwork(wc);
    Log.d("WifiPreference", "add Network returned " + res );
    boolean es = wifi.saveConfiguration();
    Log.d("WifiPreference", "saveConfiguration returned " + es );
    boolean b = wifi.enableNetwork(res, true);   
    Log.d("WifiPreference", "enableNetwork returned " + b );  
        	
}

Following the permissions needed in AndroidManifest.xml

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE">
	</uses-permission>
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
	</uses-permission>
	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE">
	</uses-permission>

Part 2: Read a WEP WiFi configuration programmatically
Straighforward again. Here is the sample code:

    void readWepConfig()
    { 
        WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
        List<WifiConfiguration> item = wifi.getConfiguredNetworks();
        int i = item.size();
        Log.d("WifiPreference", "NO OF CONFIG " + i );
        Iterator<WifiConfiguration> iter =  item.iterator();
        WifiConfiguration config = item.get(0);
        Log.d("WifiPreference", "SSID" + config.SSID);
        Log.d("WifiPreference", "PASSWORD" + config.preSharedKey);
        Log.d("WifiPreference", "ALLOWED ALGORITHMS");
        Log.d("WifiPreference", "LEAP" + config.allowedAuthAlgorithms.get(AuthAlgorithm.LEAP));
        Log.d("WifiPreference", "OPEN" + config.allowedAuthAlgorithms.get(AuthAlgorithm.OPEN));
        Log.d("WifiPreference", "SHARED" + config.allowedAuthAlgorithms.get(AuthAlgorithm.SHARED));
        Log.d("WifiPreference", "GROUP CIPHERS");
        Log.d("WifiPreference", "CCMP" + config.allowedGroupCiphers.get(GroupCipher.CCMP));
        Log.d("WifiPreference", "TKIP" + config.allowedGroupCiphers.get(GroupCipher.TKIP));
        Log.d("WifiPreference", "WEP104" + config.allowedGroupCiphers.get(GroupCipher.WEP104));
        Log.d("WifiPreference", "WEP40" + config.allowedGroupCiphers.get(GroupCipher.WEP40));
        Log.d("WifiPreference", "KEYMGMT");
        Log.d("WifiPreference", "IEEE8021X" + config.allowedKeyManagement.get(KeyMgmt.IEEE8021X));
        Log.d("WifiPreference", "NONE" + config.allowedKeyManagement.get(KeyMgmt.NONE));
        Log.d("WifiPreference", "WPA_EAP" + config.allowedKeyManagement.get(KeyMgmt.WPA_EAP));
        Log.d("WifiPreference", "WPA_PSK" + config.allowedKeyManagement.get(KeyMgmt.WPA_PSK));
        Log.d("WifiPreference", "PairWiseCipher");
        Log.d("WifiPreference", "CCMP" + config.allowedPairwiseCiphers.get(PairwiseCipher.CCMP));
        Log.d("WifiPreference", "NONE" + config.allowedPairwiseCiphers.get(PairwiseCipher.NONE));
        Log.d("WifiPreference", "TKIP" + config.allowedPairwiseCiphers.get(PairwiseCipher.TKIP));
        Log.d("WifiPreference", "Protocols");
        Log.d("WifiPreference", "RSN" + config.allowedProtocols.get(Protocol.RSN));
        Log.d("WifiPreference", "WPA" + config.allowedProtocols.get(Protocol.WPA));
        Log.d("WifiPreference", "WEP Key Strings");
        String[] wepKeys = config.wepKeys;
        Log.d("WifiPreference", "WEP KEY 0" + wepKeys[0]);
        Log.d("WifiPreference", "WEP KEY 1" + wepKeys[1]);
        Log.d("WifiPreference", "WEP KEY 2" + wepKeys[2]);
        Log.d("WifiPreference", "WEP KEY 3" + wepKeys[3]);
    }

Part 3: Read a EAP WiFi Configuration programmatically
Now this is tricky. You can find the code which saves a EAP WiFi configuration through the vanilla Android UI in WifiDialog.java. Well easy enough We can use the same code in our Application, Well NO! If you happen to try this you will get errors saying cannot find the symbols eap, phase, client_cert and so on. A little detailed investigation tells us EnterpriseField is private inside WiFiConfiguration class and all the symbols we cannot find are of the type EnterpriseField. Well we've hit a roadblock, We need these fields for reading/saving a EAP config but we don't have programmatic access to them!

Java Reflection API to the rescue Well I am not a Java expert so I wont be getting in to details of Reflection API as such and you can google for tutorials or get more information here. To keep it Short and Sweet, Reflection API allows you to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection.And, Importantly Reflection can help you access private data members inside a class Well this is what we need don't we? :)

Let's check the code example now which shows how to read a EAP WiFi configuration using Reflection Api. As a bonus the snippet will log the config to a file and save it on the SD Card....pretty slick ..eh ;) A little bit of overview of Reflection Api and I am sure grasping the code below is easy.

    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";
    final String INT_ENTERPRISEFIELD_NAME = "android.net.wifi.WifiConfiguration$EnterpriseField";

This is the code to create a logfile on to SD card before calling the readEapConfig() function.

        BufferedWriter out = null;
        try 
        {
            File root = Environment.getExternalStorageDirectory();
            Toast toast = Toast.makeText(this, "SD CARD mounted and writable? " + root.canWrite(), 5000);
            toast.show();
            if (root.canWrite())
            {
                File gpxfile = new File(root, "ReadConfigLog.txt");
                FileWriter gpxwriter = new FileWriter(gpxfile);
                out = new BufferedWriter(gpxwriter);
                out.write("Hello world");
                //out.close();
            }
        } catch (IOException e) 
        {
        	Toast toast = Toast.makeText(this, "Problem reading SD CARD", 3000);
        	Toast toast2 = Toast.makeText(this, "Please take logs using Logcat", 5000);
            Log.e("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "Could not write file " + e.getMessage());
        }

Now the readEapConfig() function itself:

    void readEapConfig(BufferedWriter out)
    {
    	/*Get the WifiService */    	
    	WifiManager wifi = (WifiManager)getSystemService(WIFI_SERVICE);
    	/*Get All WIfi configurations*/
    	List<WifiConfiguration> configList = wifi.getConfiguredNetworks();
    	/*Now we need to search appropriate configuration i.e. with name SSID_Name*/
    	for(int i = 0;i<configList.size();i++)
    	{
    		if(configList.get(i).SSID.contentEquals("\"SSID_NAME\""))
    		{
    			/*We found the appropriate config now read all config details*/
    			Iterator<WifiConfiguration> iter =  configList.iterator();
    	        WifiConfiguration config = configList.get(i);
    	        
    	        /*I dont think these fields have anything to do with EAP config but still will
    	         * print these to be on safe side*/
    	        try {
    			Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[SSID]" + config.SSID);
    			out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[SSID]" + config.SSID);
    			Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[BSSID]" + config.BSSID);
    			out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" +"[BSSID]" + config.BSSID);
    			Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[HIDDEN SSID]" + config.hiddenSSID);
    			out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[HIDDEN SSID]" + config.hiddenSSID);
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[PASSWORD]" + config.preSharedKey);
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>"+ "[PASSWORD]" + config.preSharedKey);
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[ALLOWED ALGORITHMS]");
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>"+ "[ALLOWED ALGORITHMS]");
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[LEAP]" + config.allowedAuthAlgorithms.get(AuthAlgorithm.LEAP));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[LEAP]" + config.allowedAuthAlgorithms.get(AuthAlgorithm.LEAP));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[OPEN]" + config.allowedAuthAlgorithms.get(AuthAlgorithm.OPEN));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[OPEN]" + config.allowedAuthAlgorithms.get(AuthAlgorithm.OPEN));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[SHARED]" + config.allowedAuthAlgorithms.get(AuthAlgorithm.SHARED));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[SHARED]" + config.allowedAuthAlgorithms.get(AuthAlgorithm.SHARED));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[GROUP CIPHERS]");
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[GROUP CIPHERS]");
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[CCMP]" + config.allowedGroupCiphers.get(GroupCipher.CCMP));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[CCMP]" + config.allowedGroupCiphers.get(GroupCipher.CCMP));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" , "[TKIP]" + config.allowedGroupCiphers.get(GroupCipher.TKIP));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>"+ "[TKIP]" + config.allowedGroupCiphers.get(GroupCipher.TKIP));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP104]" + config.allowedGroupCiphers.get(GroupCipher.WEP104));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP104]" + config.allowedGroupCiphers.get(GroupCipher.WEP104));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP40]" + config.allowedGroupCiphers.get(GroupCipher.WEP40));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP40]" + config.allowedGroupCiphers.get(GroupCipher.WEP40));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[KEYMGMT]");
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[KEYMGMT]");
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[IEEE8021X]" + config.allowedKeyManagement.get(KeyMgmt.IEEE8021X));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>"+ "[IEEE8021X]" + config.allowedKeyManagement.get(KeyMgmt.IEEE8021X));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[NONE]" + config.allowedKeyManagement.get(KeyMgmt.NONE));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[NONE]" + config.allowedKeyManagement.get(KeyMgmt.NONE));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WPA_EAP]" + config.allowedKeyManagement.get(KeyMgmt.WPA_EAP));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WPA_EAP]" + config.allowedKeyManagement.get(KeyMgmt.WPA_EAP));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WPA_PSK]" + config.allowedKeyManagement.get(KeyMgmt.WPA_PSK));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WPA_PSK]" + config.allowedKeyManagement.get(KeyMgmt.WPA_PSK));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[PairWiseCipher]");
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[PairWiseCipher]");
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[CCMP]" + config.allowedPairwiseCiphers.get(PairwiseCipher.CCMP));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[CCMP]" + config.allowedPairwiseCiphers.get(PairwiseCipher.CCMP));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[NONE]" + config.allowedPairwiseCiphers.get(PairwiseCipher.NONE));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[NONE]" + config.allowedPairwiseCiphers.get(PairwiseCipher.NONE));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[TKIP]" + config.allowedPairwiseCiphers.get(PairwiseCipher.TKIP));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[TKIP]" + config.allowedPairwiseCiphers.get(PairwiseCipher.TKIP));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[Protocols]");
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[Protocols]");
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[RSN]" + config.allowedProtocols.get(Protocol.RSN));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[RSN]" + config.allowedProtocols.get(Protocol.RSN));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WPA]" + config.allowedProtocols.get(Protocol.WPA));
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WPA]" + config.allowedProtocols.get(Protocol.WPA));
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[PRE_SHARED_KEY]" + config.preSharedKey);
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[PRE_SHARED_KEY]" + config.preSharedKey);
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP Key Strings]");
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP Key Strings]");
    	        String[] wepKeys = config.wepKeys;
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP KEY 0]" + wepKeys[0]);
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP KEY 0]" + wepKeys[0]);
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP KEY 1]" + wepKeys[1]);
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP KEY 1]" + wepKeys[1]);
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP KEY 2]" + wepKeys[2]);
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP KEY 2]" + wepKeys[2]);
    	        Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[WEP KEY 3]" + wepKeys[3]);
    	        out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[WEP KEY 3]" + wepKeys[3]);
    	        
      	        }
    	        catch(IOException e) 
    	        {
    	        	Toast toast1 = Toast.makeText(this, "Failed to write Logs to ReadConfigLog.txt", 3000);
    	        	Toast toast2 = Toast.makeText(this, "Please take logs using Logcat", 5000);
    	            Log.e("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "Could not write to ReadConfigLog.txt" + e.getMessage());
    	        }
    	        /*reflection magic*/
    	        /*These are the fields we are really interested in*/
    	        try 
    	        {
    				// Let the magic start
    				Class[] wcClasses = WifiConfiguration.class.getClasses();
    				// null for overzealous java compiler
    				Class wcEnterpriseField = null;

    				for (Class wcClass : wcClasses)
    					if (wcClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) 
    					{
    						wcEnterpriseField = wcClass;
    						break;
    					}
    				boolean noEnterpriseFieldType = false; 
    				if(wcEnterpriseField == null)
    					noEnterpriseFieldType = true; // Cupcake/Donut access enterprise settings directly
    				
    				Field wcefAnonymousId = null, wcefCaCert = null, wcefClientCert = null, wcefEap = null, wcefIdentity = null, wcefPassword = null, wcefPhase2 = null, wcefPrivateKey = null;
    				Field[] wcefFields = WifiConfiguration.class.getFields();
    				// Dispatching Field vars
    				for (Field wcefField : wcefFields) 
    				{
    					if (wcefField.getName().trim().equals(INT_ANONYMOUS_IDENTITY))
    						wcefAnonymousId = wcefField;
    					else if (wcefField.getName().trim().equals(INT_CA_CERT))
    						wcefCaCert = wcefField;
    					else if (wcefField.getName().trim().equals(INT_CLIENT_CERT))
    						wcefClientCert = wcefField;
    					else if (wcefField.getName().trim().equals(INT_EAP))
    						wcefEap = wcefField;
    					else if (wcefField.getName().trim().equals(INT_IDENTITY))
    						wcefIdentity = wcefField;
    					else if (wcefField.getName().trim().equals(INT_PASSWORD))
    						wcefPassword = wcefField;
    					else if (wcefField.getName().trim().equals(INT_PHASE2))
    						wcefPhase2 = wcefField;
    					else if (wcefField.getName().trim().equals(INT_PRIVATE_KEY))
    						wcefPrivateKey = wcefField;
    				}
				Method wcefValue = null;
				if(!noEnterpriseFieldType)
				{
				for(Method m: wcEnterpriseField.getMethods())
				//System.out.println(m.getName());
				if(m.getName().trim().equals("value")){
					wcefValue = m;
					break;
				}
				}
				
				/*EAP Method*/
				String result = null;
				Object obj = null;
				if(!noEnterpriseFieldType)
				{
					obj = wcefValue.invoke(wcefEap.get(config), null);
					String retval = (String)obj;
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP METHOD]" + retval);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP METHOD]" + retval);
				}
				else
				{
					obj = wcefEap.get(config);
					String retval = (String)obj;    					
				}
				
				/*phase 2*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefPhase2.get(config), null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP PHASE 2 AUTHENTICATION]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP PHASE 2 AUTHENTICATION]" + result);
				}
				else
				{
					result = (String) wcefPhase2.get(config);
				}

				/*Anonymous Identity*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefAnonymousId.get(config),null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP ANONYMOUS IDENTITY]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP ANONYMOUS IDENTITY]" + result);
				}
				else
				{
					result = (String) wcefAnonymousId.get(config);
				}
				
				/*CA certificate*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefCaCert.get(config), null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP CA CERTIFICATE]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP CA CERTIFICATE]" + result);
				}
				else
				{
					result = (String)wcefCaCert.get(config);

				}
				
				/*private key*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefPrivateKey.get(config),null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP PRIVATE KEY]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP PRIVATE KEY]" + result);
				}
				else
				{
					result = (String)wcefPrivateKey.get(config);
				}

				/*Identity*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefIdentity.get(config), null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP IDENTITY]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP IDENTITY]" + result);
				}
				else
				{
					result = (String)wcefIdentity.get(config);
				}
				
				/*Password*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefPassword.get(config), null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP PASSWORD]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP PASSWORD]" + result);
				}
				else
				{
					result = (String)wcefPassword.get(config);
				}
					
				/*client certificate*/
				if(!noEnterpriseFieldType)
				{
					result = (String) wcefValue.invoke(wcefClientCert.get(config), null);
					Log.d("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "[EAP CLIENT CERT]" + result);
					out.write("<<<<<<<<<<WifiPreference>>>>>>>>>>>>" + "[EAP CLIENT CERT]" + result);
					Toast toast1 = Toast.makeText(this, "All config data logged to ReadConfigLog.txt", 3000);
    	        	Toast toast2 = Toast.makeText(this, "Extract ReadConfigLog.txt from SD CARD", 5000);
				}
				else
				{
					result = (String)wcefClientCert.get(config);
				}
				
				out.close();
					
    	        }
    	        catch(IOException e) 
    	        {
    	        	Toast toast1 = Toast.makeText(this, "Failed to write Logs to ReadConfigLog.txt", 3000);
    	        	Toast toast2 = Toast.makeText(this, "Please take logs using Logcat", 5000);
    	            Log.e("<<<<<<<<<<WifiPreference>>>>>>>>>>>>", "Could not write to ReadConfigLog.txt" + e.getMessage());
    	        }
    	        catch(Exception e)
    	        {
    	        	e.printStackTrace();
    	        }
    	        
    		}
    	}
    }

Solution 2 - Android

Ahh I ran out of edit space, Adding the remaining part here.

Part 4: Save a EAP WiFi configuration programmatically

If you already read the part 3, you already understand the Reflection magic that works here, If you are directly jumping to this section please read the introduction before the code snippet in part 3 and you will be up to speed to breeze through the code here!

void saveEapConfig(String passString, String userName)
    {
    /********************************Configuration Strings****************************************************/
    final String ENTERPRISE_EAP = "TLS";
    final String ENTERPRISE_CLIENT_CERT = "keystore://USRCERT_CertificateName";
    final String ENTERPRISE_PRIV_KEY = "USRPKEY_CertificateName";
    //CertificateName = Name given to the certificate while installing it

    /*Optional Params- My wireless Doesn't use these*/
    final String ENTERPRISE_PHASE2 = "";
    final String ENTERPRISE_ANON_IDENT = "ABC";
    final String ENTERPRISE_CA_CERT = ""; // If required: "keystore://CACERT_CaCertificateName"
    /********************************Configuration Strings****************************************************/

    /*Create a WifiConfig*/
    WifiConfiguration selectedConfig = new WifiConfiguration();

    /*AP Name*/
    selectedConfig.SSID = "\"SSID_Name\"";

    /*Priority*/
    selectedConfig.priority = 40;

    /*Enable Hidden SSID*/
    selectedConfig.hiddenSSID = true;

    /*Key Mgmnt*/
    selectedConfig.allowedKeyManagement.clear();
    selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
    selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);

    /*Group Ciphers*/
    selectedConfig.allowedGroupCiphers.clear();
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

    /*Pairwise ciphers*/
    selectedConfig.allowedPairwiseCiphers.clear();
    selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

    /*Protocols*/
    selectedConfig.allowedProtocols.clear();
    selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
    selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

    // Enterprise Settings
    // Reflection magic here too, need access to non-public APIs
    try {
        // Let the magic start
        Class[] wcClasses = WifiConfiguration.class.getClasses();
        // null for overzealous java compiler
        Class wcEnterpriseField = null;

        for (Class wcClass : wcClasses)
            if (wcClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) 
            {
                wcEnterpriseField = wcClass;
                break;
            }
        boolean noEnterpriseFieldType = false; 
        if(wcEnterpriseField == null)
            noEnterpriseFieldType = true; // Cupcake/Donut access enterprise settings directly

        Field wcefAnonymousId = null, wcefCaCert = null, wcefClientCert = null, wcefEap = null, wcefIdentity = null, wcefPassword = null, wcefPhase2 = null, wcefPrivateKey = null, wcefEngine = null, wcefEngineId = null;
        Field[] wcefFields = WifiConfiguration.class.getFields();
        // Dispatching Field vars
        for (Field wcefField : wcefFields) 
        {
            if (wcefField.getName().equals(INT_ANONYMOUS_IDENTITY))
                wcefAnonymousId = wcefField;
            else if (wcefField.getName().equals(INT_CA_CERT))
                wcefCaCert = wcefField;
            else if (wcefField.getName().equals(INT_CLIENT_CERT))
                wcefClientCert = wcefField;
            else if (wcefField.getName().equals(INT_EAP))
                wcefEap = wcefField;
            else if (wcefField.getName().equals(INT_IDENTITY))
                wcefIdentity = wcefField;
            else if (wcefField.getName().equals(INT_PASSWORD))
                wcefPassword = wcefField;
            else if (wcefField.getName().equals(INT_PHASE2))
                wcefPhase2 = wcefField;
            else if (wcefField.getName().equals(INT_PRIVATE_KEY))
                wcefPrivateKey = wcefField;
            else if (wcefField.getName().equals("engine"))
                wcefEngine = wcefField;
            else if (wcefField.getName().equals("engine_id"))
                wcefEngineId = wcefField;
        }


        Method wcefSetValue = null;
        if(!noEnterpriseFieldType){
        for(Method m: wcEnterpriseField.getMethods())
            //System.out.println(m.getName());
            if(m.getName().trim().equals("setValue"))
                wcefSetValue = m;
        }


        /*EAP Method*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefEap.get(selectedConfig), ENTERPRISE_EAP);
        }
        else
        {
                wcefEap.set(selectedConfig, ENTERPRISE_EAP);
        }
        /*EAP Phase 2 Authentication*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefPhase2.get(selectedConfig), ENTERPRISE_PHASE2);
        }
        else
        {
              wcefPhase2.set(selectedConfig, ENTERPRISE_PHASE2);
        }
        /*EAP Anonymous Identity*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefAnonymousId.get(selectedConfig), ENTERPRISE_ANON_IDENT);
        }
        else
        {
              wcefAnonymousId.set(selectedConfig, ENTERPRISE_ANON_IDENT);
        }
        /*EAP CA Certificate*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefCaCert.get(selectedConfig), ENTERPRISE_CA_CERT);
        }
        else
        {
              wcefCaCert.set(selectedConfig, ENTERPRISE_CA_CERT);
        }               
        /*EAP Private key*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefPrivateKey.get(selectedConfig), ENTERPRISE_PRIV_KEY);
        }
        else
        {
              wcefPrivateKey.set(selectedConfig, ENTERPRISE_PRIV_KEY);
        }               
        /*EAP Identity*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefIdentity.get(selectedConfig), userName);
        }
        else
        {
              wcefIdentity.set(selectedConfig, userName);
        }               
        /*EAP Password*/
        if(!noEnterpriseFieldType)
        {
                wcefSetValue.invoke(wcefPassword.get(selectedConfig), passString);
        }
        else
        {
              wcefPassword.set(selectedConfig, passString);
        }               
        /*EAp Client certificate*/
        if(!noEnterpriseFieldType)
        {
            wcefSetValue.invoke(wcefClientCert.get(selectedConfig), ENTERPRISE_CLIENT_CERT);
        }
        else
        {
              wcefClientCert.set(selectedConfig, ENTERPRISE_CLIENT_CERT);
        }
        /*Engine fields*/
        if(!noEnterpriseFieldType)
        {
           wcefSetValue.invoke(wcefEngine.get(wifiConf), "1");
           wcefSetValue.invoke(wcefEngineId.get(wifiConf), "keystore");
        }

        // Adhoc for CM6
        // if non-CM6 fails gracefully thanks to nested try-catch

        try{
        Field wcAdhoc = WifiConfiguration.class.getField("adhocSSID");
        Field wcAdhocFreq = WifiConfiguration.class.getField("frequency");
        //wcAdhoc.setBoolean(selectedConfig, prefs.getBoolean(PREF_ADHOC,
        //      false));
        wcAdhoc.setBoolean(selectedConfig, false);
        int freq = 2462;    // default to channel 11
        //int freq = Integer.parseInt(prefs.getString(PREF_ADHOC_FREQUENCY,
        //"2462"));     // default to channel 11
        //System.err.println(freq);
        wcAdhocFreq.setInt(selectedConfig, freq); 
        } catch (Exception e)
        {
            e.printStackTrace();
        }

    } catch (Exception e)
    {
        // TODO Auto-generated catch block
        // FIXME As above, what should I do here?
        e.printStackTrace();
    }

    WifiManager wifiManag = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    boolean res1 = wifiManag.setWifiEnabled(true);
    int res = wifiManag.addNetwork(selectedConfig);
    Log.d("WifiPreference", "add Network returned " + res );
    boolean b = wifiManag.enableNetwork(selectedConfig.networkId, false);
    Log.d("WifiPreference", "enableNetwork returned " + b );
    boolean c = wifiManag.saveConfiguration();
    Log.d("WifiPreference", "Save configuration returned " + c );
    boolean d = wifiManag.enableNetwork(res, true);   
    Log.d("WifiPreference", "enableNetwork returned " + d );  
}

Well thats it! And I hope this helps some lost developer, somewhere, sometime :)

Solution 3 - Android

Android has added an API to JellyBean 4.3. You must use this option if you want to configure WIFI on API 18:

http://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.html

Solution 4 - Android

Part 4 started me off on the right path! However i wanted to create a TTLS rather than TLS config here is how i did it!

	/********************************Configuration Strings****************************************************/
    final String ENTERPRISE_EAP = "TTLS";

    /*Optional Params- My wireless Doesn't use these*/
    final String ENTERPRISE_PHASE2 = "PAP";
    final String ENTERPRISE_ANON_IDENT = "ABC";
    final String ENTERPRISE_CA_CERT = "";
    /********************************Configuration Strings****************************************************/

    /*Create a WifiConfig*/
    WifiConfiguration selectedConfig = new WifiConfiguration();

    /*AP Name*/
    selectedConfig.SSID = "\"EAP_SSID_TEST_CONFIG\"";

    /*Priority*/
    selectedConfig.priority = 40;

    /*Enable Hidden SSID*/
    selectedConfig.hiddenSSID = false;

    /*Key Mgmnt*/
    selectedConfig.allowedKeyManagement.clear();
    selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
    selectedConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);

    /*Group Ciphers*/
    selectedConfig.allowedGroupCiphers.clear();
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
    selectedConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

    /*Pairwise ciphers*/
    selectedConfig.allowedPairwiseCiphers.clear();
    selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    selectedConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

    /*Protocols*/
    selectedConfig.allowedProtocols.clear();
    selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
    selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

    // Enterprise Settings
    // Reflection magic here too, need access to non-public APIs
    try {
        // Let the magic start
        Class[] wcClasses = WifiConfiguration.class.getClasses();
        // null for overzealous java compiler
        Class wcEnterpriseField = null;

        for (Class wcClass : wcClasses)
            if (wcClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) 
            {
                wcEnterpriseField = wcClass;
                break;
            }
        boolean noEnterpriseFieldType = false; 
        if(wcEnterpriseField == null)
            noEnterpriseFieldType = true; // Cupcake/Donut access enterprise settings directly

        Field wcefAnonymousId = null, wcefCaCert = null, wcefClientCert = null, wcefEap = null, wcefIdentity = null, wcefPassword = null, wcefPhase2 = null, wcefPrivateKey = null;
        Field[] wcefFields = WifiConfiguration.class.getFields();
        // Dispatching Field vars
        for (Field wcefField : wcefFields) 
        {
            if (wcefField.getName().equals(INT_ANONYMOUS_IDENTITY))
                wcefAnonymousId = wcefField;
            else if (wcefField.getName().equals(INT_CA_CERT))
                wcefCaCert = wcefField;
            else if (wcefField.getName().equals(INT_CLIENT_CERT))
                wcefClientCert = wcefField;
            else if (wcefField.getName().equals(INT_EAP))
                wcefEap = wcefField;
            else if (wcefField.getName().equals(INT_IDENTITY))
                wcefIdentity = wcefField;
            else if (wcefField.getName().equals(INT_PASSWORD))
                wcefPassword = wcefField;
            else if (wcefField.getName().equals(INT_PHASE2))
                wcefPhase2 = wcefField;
            else if (wcefField.getName().equals(INT_PRIVATE_KEY))
                wcefPrivateKey = wcefField;
        }


        Method wcefSetValue = null;
        if(!noEnterpriseFieldType){
        for(Method m: wcEnterpriseField.getMethods())
            //System.out.println(m.getName());
            if(m.getName().trim().equals("setValue"))
                wcefSetValue = m;
        }


        /*EAP Method*/
        if(!noEnterpriseFieldType){
            wcefSetValue.invoke(wcefEap.get(selectedConfig), ENTERPRISE_EAP);
        }
        /*EAP Phase 2 Authentication*/
        if(!noEnterpriseFieldType){
            wcefSetValue.invoke(wcefPhase2.get(selectedConfig), ENTERPRISE_PHASE2);
        }
        /*EAP Anonymous Identity*/
        if(!noEnterpriseFieldType){
            wcefSetValue.invoke(wcefAnonymousId.get(selectedConfig), ENTERPRISE_ANON_IDENT);
        }
        /*EAP CA Certificate*/
        if(!noEnterpriseFieldType){
            wcefSetValue.invoke(wcefCaCert.get(selectedConfig), ENTERPRISE_CA_CERT);
        }


        /*EAP Identity*/
        if(!noEnterpriseFieldType){
            wcefSetValue.invoke(wcefIdentity.get(selectedConfig), "test user name");
        }
        /*EAP Password*/
        if(!noEnterpriseFieldType){
            wcefSetValue.invoke(wcefPassword.get(selectedConfig), "test password");
        }


        try{

        } catch (Exception e)
        {
            e.printStackTrace();
        }

    } catch (Exception e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    WifiManager wifiManag = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    boolean res1 = wifiManag.setWifiEnabled(true);
    int res = wifiManag.addNetwork(selectedConfig);
    Log.d("WifiPreference", "add Network returned " + res );
//        boolean b = wifiManag.enableNetwork(selectedConfig.networkId, false);
//        Log.d("WifiPreference", "enableNetwork returned " + b );
//        boolean c = wifiManag.saveConfiguration();
//        Log.d("WifiPreference", "Save configuration returned " + c );
//        boolean d = wifiManag.enableNetwork(res, true);   
//        Log.d("WifiPreference", "enableNetwork returned " + d ); 


}

Hope this helps some one. @Android learner I removed the bit about adHocFrequency and SSID as they were causing crashes but my results were still good without them.

Solution 5 - Android

The WEP keys are masked, so it is not possible to read them with the mentioned code

    Log.d("WifiPreference", "WEP KEY 0" + wepKeys[0]);
    Log.d("WifiPreference", "WEP KEY 1" + wepKeys[1]);
    Log.d("WifiPreference", "WEP KEY 2" + wepKeys[2]);
    Log.d("WifiPreference", "WEP KEY 3" + wepKeys[3]);

Is there any way to solve this in same way as the EAP solution? With reflection?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlok SaveView Question on Stackoverflow
Solution 1 - AndroidAlok SaveView Answer on Stackoverflow
Solution 2 - AndroidAlok SaveView Answer on Stackoverflow
Solution 3 - AndroidBlackHatSamuraiView Answer on Stackoverflow
Solution 4 - AndroidAiden FryView Answer on Stackoverflow
Solution 5 - Androiduser1419056View Answer on Stackoverflow