2012-05-22 7 views
5

Estoy tratando de crear programáticamente perfiles WiFi empresariales en Android (WPA-Enterprise, WPA2-Enterprise).Android: ¿Por qué el SDK no permite que el programador agregue perfiles WiFi (EAP) fácilmente?

He visto una solución bastante famosa, que es utilizar la reflexión para lograr esto. A mi entender, si tiene que hacerse de manera indirecta, lo que implica obtener acceso a partes de una API a las que se ha denegado el acceso, tiene que haber una buena razón para ello.

¿Esto significa que Google NO quiere que los desarrolladores puedan configurar de manera programática la configuración de WiFi? Si es así, ¿cuál podría ser el motivo de esto?

+0

Dónde está la solución bastante famosa 'que ha visto? – jacknad

+0

aquí http://stackoverflow.com/questions/4374862/how-to-programatically-create-and-read-wep-eap-wifi-configurations-in-android/4375874#4375874 –

Respuesta

0

Tal vez me falta algo en la pregunta o en los detalles, ya que no he tenido la necesidad de hacerlo yo mismo, pero ¿las clases WifiManager y WifiConfiguration no hacen lo que necesita? Por ejemplo:

WifiManager wMan = getSystemService(Context.WIFI_SERVICE); 
WifiConfiguration config = new WifiConfiguration(); 

config.SSID = "your ssid"; 
//continue setting up the configuration 

wMan.addNetwork(config); 

EDIT: La respuesta que señaló que sólo se utiliza la reflexión para las configuraciones de EAP (conexiones que utilizan seguridad WPA-Empresa o WPA2-Enterprise, por lo general). Para las conexiones típicas, no debería tener que usar el reflejo.

+0

Eso es correcto. Pero mi requisito es para Enterprise. ¿Hay alguna razón por la cual esto debería ser desautorizado para la empresa? –

+0

Está bien, con esa aclaración no estoy seguro entonces. No estoy particularmente familiarizado con las redes EAP, así que dejaré esa respuesta a otra persona. :) – kcoppock

+0

Gracias, por favor comparte esto con alguien que pueda saber la respuesta? –

1

He escrito una clase con un método estático que te permitirá hacer esto. Aquí está. Deberá pasar su SSID, nombre de usuario y contraseña al método. Hay otras opciones que puede establecer si necesita establecer el EAP en TLS o PEAP. Cabe señalar que este código se basa en el código aquí: How to programmatically create and read WEP/EAP WiFi configurations in Android?. La diferencia es que mi código te permite ajustar la configuración de IP y la configuración del proxy. Al usar este código, puede conectarse automáticamente a una red wifi con la configuración WPA_EAP.

Espero que esto ayude:

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_NAME = "android.net.wifi.WifiConfiguration$IpAssignment"; 
    private static final String INT_PROXYSETTINGS_NAME = "android.net.wifi.WifiConfiguration$ProxySettings"; 
    //change this to TLS,PEAP, or other options that are listed when you connect via a device 
    private static final String ENTERPRISE_EAP = "PEAP"; 
    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; 
     wifiConfig.networkId = 0; 

     /*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; 

      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_NAME)) 
       { 
        wifiIpAssignmentField = wifiClass; 
       } 
       else if(wifiClass.getName().equals(INT_PROXYSETTINGS_NAME)) 
       { 
        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); 
       } 

      } 

      /*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; 
        } 
       } 
      } 

      /*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) 
      { 
       /*Change the literal string in here to change the value of obtaining and IP address*/ 
       ipAssignment.set(wifiConfig, Enum.valueOf((Class<Enum>) ipAssignment.getType().asSubclass(Enum.class), "DHCP")); 
       Log.d("Enterprise Setting", "Setting " + ipAssignment); 
      } 
      else 
      { 
       ipAssignment.set(wifiConfig, "DHCP"); 
      } 

      /*Set Proxy Protocol*/ 
      if(proxySettingsFieldType) 
      { 
       /*Change the literal string in here to change the value of proxy settingss*/ 
       proxy.set(wifiConfig, Enum.valueOf((Class<Enum>) proxy.getType().asSubclass(Enum.class), "NONE")); 
       Log.d("Enterprise Setting", "Setting " + proxy); 
      } 
      else 
      { 
       proxy.set(wifiConfig, "NONE"); 
      } 

     } 
     catch(Exception e) 
     { 
      Log.e("ERROR!!!", "Error: " + e); 

     } 
     Log.d("WIFI", "Configuration Settings " + wifiConfig.toString()); 
     return wifiConfig; 
    } 
} 
+0

gracias por su respuesta. He visto esta solución antes. Este no es un método SDK directo, sino más bien un hack de reflexión. Estos agujeros pueden ser bloqueados por Google en cualquier momento dado. –

+0

No, no SDK, pero funcionó para mí :) – BlackHatSamurai

+0

@HeshanPerera usted es escribir desde lolipop en salas esa técnica en que no funciona. ¿Hay alguna otra manera? –

Cuestiones relacionadas