Как программно создавать и читать конфигурации WEP/EAP WiFi в Android?
как программно создавать и читать WEP/EAP WiFi configurations в Android?
Я видел много людей, борющихся по этому самому вопросу на различных форумах и по всему сообществу. Я знаю, что это не так прямо вперед(особенно EAP), чтобы выяснить, потому что, когда я хотел достичь того же, я тоже боролся довольно много.Ну, вся тяжелая работа по анализу кода и поиску различных реализаций в интернете, выполненная с помощью I, наконец, смогла достичь цель. Весь кредит идет на количество проектов с открытым исходным кодом и их разработчиков.
Я хотел бы поделиться этим знанием со всеми, так как так рекомендует это: "также совершенно нормально задавать и отвечать на свой собственный вопрос, пока вы притворяетесь, что находитесь под угрозой: сформулируйте его в форме вопроса."
Часть 1.создание конфигурации WEP WiFi программно.
Часть 2: прочитайте конфигурацию WEP WiFi программно.
Часть 3.прочитайте конфигурацию WiFi EAP программно.
Часть 4.сохраните конфигурацию EAP WiFi программно.
5 ответов:
Часть 1: Создание конфигурации WEP WiFi программно
это довольно просто,WifiConfiguration предоставляет интерфейс для создания того же самого. Вот пример кода:
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 ); }после разрешений, необходимых в 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>Часть 2: прочитайте конфигурацию WEP WiFi программно
Straighforward снова. Вот пример кода: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]); }Часть 3: прочитайте конфигурацию WiFi EAP программно
Теперь это сложно. Вы можете найти код, который сохраняет конфигурацию EAP WiFi через интерфейс vanilla Android в WifiDialog.java. Достаточно легко мы можем использовать тот же код в нашем приложении, ну нет! Если вы попробуете это, вы получите ошибки, говорящие, что не можете найти символыeap,phase,client_certи так далее. Один небольшое детальное расследование говорит нам EnterpriseFieldis privateвнутриWiFiConfigurationкласс и все символы мы не можем найти типаEnterpriseField. Ну, мы попали в блокпост, нам нужны эти поля для чтения / сохранения конфигурации EAP, но у нас нет программного доступа к ним!
Java Reflection APIспасения Ну, я не эксперт Java, поэтому я не буду вдаваться в детали API отражения как такового, и вы можете google для учебников или получить дополнительную информацию здесь. Чтобы сохранить его коротким и сладким, Reflection API позволяет вам проверять классы, интерфейсы, поля и методы во время выполнения, не зная имен классов, методов и т. д. во время компиляции. Также можно создавать экземпляры новых объектов, вызывать методы и получать/устанавливать значения полей с помощью отражения.И, Главное отражение может помочь вам получить доступ к частным членам данных внутри класса Ну вот что нам нужно, не так ли? :)давайте теперь проверим пример кода, который показывает, как читать конфигурацию EAP WiFi с помощью API отражения. В качестве бонуса фрагмент будет регистрировать конфигурацию в файл и сохранять его на SD-карте....довольно ловко ..eh ;) немного обзора API отражения, и я уверен, что понять приведенный ниже код легко.
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";это код для создания файла журнала на SD-карте перед вызовом
Ahh у меня закончилось пространство для редактирования, добавив оставшуюся часть здесь.
Часть 4: сохраните конфигурацию EAP WiFi программно
Если вы уже читали часть 3, вы уже понимаете магию отражения, которая работает здесь, Если вы непосредственно переходите к этому разделу, пожалуйста, прочитайте введение перед фрагментом кода в части 3, и вы будете в курсе, чтобы ветер через код здесь!
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 ); }Ну вот и все! И Я надеюсь, что это поможет какой-то потерянный разработчик, где-то, когда-нибудь :)
Android добавил API в JellyBean 4.3. Вы должны использовать эту опцию, если вы хотите настроить WIFI на API 18:
http://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.html
часть 4 начала меня на правильном пути! Однако я хотел создать TTLS, а не TLS config вот как я это сделал!
/********************************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 ); }надеюсь, что это поможет кому-то. @Android learner я удалил бит о adHocFrequency и SSID, поскольку они вызывали сбои, но мои результаты были все еще хороши без них.
ключи WEP замаскированы, поэтому их невозможно прочитать с указанным кодом
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]);есть ли способ решить это таким же образом, как и решение EAP? С отражением?
Comments