AndroidでプログラムでWEP / EAP WiFi設定を作成して読み取る方法は?


111

プログラムで作成WEP/EAP WiFi configurationsしてAndroid で読み取る方法は?

さまざまなフォーラムやコミュニティ全体でこの質問に苦労している多くの人々を見てきました。私はこれを理解するのがそれほど簡単ではないことを知っています(特にEAP)。同じことを達成したいと思ったとき、私も非常に苦労しました。最終的に目標を達成することができます。すべての功績は、オープンソースプロジェクトとその開発者の数にあります。

私はこの知識をすべての人と共有したいと思います。SO これを奨励しているため、「あなたがJeopardyにいるふりをしている限り、質問して質問に答えることも完全に問題ありません。質問の形式でそれを表現してください。」

パート1: プログラムによるWEP WiFi構成の作成。

パート2: プログラムでWEP WiFi構成を読み取ります。

パート3: プログラムでEAP WiFi設定を読み取ります。

パート4: プログラムでEAP WiFi構成を保存します。


質問としてフォーマットしてから、自分で回答することをお勧めします。うまくフォーマットすると、質の高い質問と回答が得られます。
Octavian A. Damiean 2010

@Octavian Damiean:頭を上げてくれてありがとう。正しいフォーマットを確保しようとしました。コメントは大歓迎です!
Alok Save

素晴らしく見える!共有してくれてありがとう!SO Androidチャットルームにアクセスしてください。
Octavian A. Damiean 2010

AndroidはAPI 18でEAP wifiをサポートするためにWifiEnterpriseConfigを追加します
ospider

これは非常に便利です。このトピックに関するドキュメントの場所を本当に知りたいですか?Androidのドキュメントは何も教えてくれません:(
Charlesjean

回答:


107

パート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:プログラムでEAP WiFi構成を読み取る
これはトリッキーです。WifiDialog.javaの通常の Android UIを介してEAP WiFi設定を保存するコードを見つけることができます。非常に簡単です。同じコードをアプリケーションで使用できます。あなたはこれを試すことが起こる場合は、シンボルを見つけることができないと言ってエラーが発生しますeapphaseclient_certとになります。少し詳細な調査により、クラス内の EnterpriseFieldがわかり、見つけられないシンボルはすべてタイプです。さて、ロードブロッキングが発生しました。EAP構成の読み取り/保存にはこれらのフィールドが必要ですが、プログラムによるアクセスはできません! is privateWiFiConfigurationEnterpriseField

Java Reflection API救助に まあ、私は私のようなリフレクションAPIの詳細にして取得さ文句を言わないと、あなたはチュートリアルのためにGoogleやより多くの情報を得ることができるようにするJavaの専門家ではないです、ここ。簡潔に保つために、Reflection APIでは、コンパイル時にクラス、メソッドなどの名前を知らなくても、実行時にクラス、インターフェース、フィールド、メソッドを検査できます。また、リフレクションを使用して、新しいオブジェクトをインスタンス化し、メソッドを呼び出し、フィールド値を取得/設定することもできます。そして、重要なことにリフレクションはクラス内のプライベートデータメンバーにアクセスするのに役立ちます。:)

ここで、Reflection Apiを使用してEAP WiFi構成を読み取る方法を示すコード例を確認してみましょう。おまけとして、スニペットは設定をファイルに記録し、SDカードに保存します。

    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";

これは、readEapConfig()関数を呼び出す前にSDカードにログファイルを作成するコードです。

        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());
        }

次に、readEapConfig()関数自体:

    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();
                }

            }
        }
    }

これを試してみましたが、何らかの理由で、ワイヤレスネットワークに新しいインターフェイスが作成されます(コメントが届かないというコメントが付いています)が、SSIDは元のネットワークとまったく同じです。これに関して何か助けはありますか?
nithinreddy 2012

@nithinreddy:私はもうAndroidに手を出さないように(かなり長い間)いないので、私が何かヘルプを提供できるかどうか疑問に思っています。AFAIR、同じSSID名を持つ2つの構成があるべきではありません。到達できない問題です。構成パラメーターを確認してください。私の推測では、どこかで不一致があるかもしれません..構成を手動で作成し、接続を確認してから、プログラムで構成パラメーターを読み取ります(上記の回答の「方法」の詳細を参照)&次に、これらのパラメーターを使用してプログラムで構成を作成します。コネクトはあなたがプログラム的に追加のものではない
Alok保存

1
@AlokSaveこれは、証明書についての手順を示すときに最適です。(EAP WIFIの場合)。これらの証明書を作成する方法と、プログラムでインストールする方法について質問があります。実際、私は過去2日間グーグルで検索していますが、プログラムで証明書をインストールする方法が見つかりませんでした。だからあなたの知識を共有してください。
Androidの学習者

1
プログラムで行う場合、AndroidのWEP(ここでは4.1)に問題があることを確認したいと思います。ただし、システムの設定でこれを手動で行うと、機能します。私は何日も試してからWPAに変更しましたが、どちらの場合も(手動でもプログラムでも)機能しました。したがって、WEPの場合:プログラムで正確に再現するために手動で(動作するように)作成されたときにWEP構造を読み取りましたが、方法はありません。永久に「OBTAINING_IPADDR」状態のままです。同じ問題で別の人を見つけたので注意してください。ここの情報は素晴らしいですが、何かが欠けています(少なくとも場合によっては)。
アレックス

1
WEPにAuthAlgorithm.OPENを使用するのはなぜですか?Androidのドキュメントには「オープンシステム認証(WPA / WPA2に必要)」
David

36

ああ、編集スペースが足りなくなりました。残りの部分をここに追加します。

パート4:プログラムでEAP WiFi構成を保存する

すでにパート3を読んでいる場合は、ここで機能するReflectionマジックをすでに理解しています。このセクションに直接ジャンプする場合は、パート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 );  
}

それでおしまい!そして、これが失われた開発者、どこか、いつかを助けることを願っています:)


7
@abresas:回答で述べたように、このソースは私がインターネットや昔からさまざまなソースから情報を取得することによって開発されましたが、その時点で新しいSDKがリリースされ、これらに関する情報はあまりありませんでした。私は現在Androidで作業していないため、現在のAndroidの状況です。また、私はこのコードの著作権を保持しておらず、それを使用している人には何の問題もありません。それが最初にここに投稿した理由ですが、わかりませんこのソースを書くときに私を助けたソースの考え/見通しについて。
Alok Save

1
Field wcAdhoc = WifiConfiguration.class.getField("adhocSSID"); Field wcAdhocFreq = WifiConfiguration.class.getField("frequency");。これらのメンバーはWifiConfiguration.javaにはありません。コードは私に例外を与えていますjava.lang.NoSuchFieldException: adhocSSID 。助けてください。
Android学習者

1
私はAndroid 4.1.2を使用しているので、このコードは最近のバージョンでは動作しない可能性があります。
ティアゴバボ2013

1
4.1または4.2では動作しないことに気づきました。ラインwcefPrivateKey.get(selectedConfig)はをスローしNullPointerExceptionます。他の誰かからの運は?
Dulax 2013

1
あなたは正しい@PrashanthDebbadwarです。API18以降では機能しません。このコードは、以前のバージョンでのみ機能します。
BurninatorDor 2017年

5

AndroidはAPIをJellyBean 4.3に追加しました。API 18でWIFIを構成する場合は、このオプションを使用する必要があります。

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


2
これは単なる「別のオプション」ではありません。android.net.wifi.WifiConfiguration $ EnterpriseFieldは存在しないため(おそらく、WifiEnterpriseConfigを追加したAPI 18以降)、Alokのソリューションは機能しなくなります。API 18+およびAPI 17-で実行するアプリには、両方のソリューションが必要になりました。
rmanna 2014年

1

パート4では、正しい道を歩み始めました。しかし、ここではTLS構成ではなくTTLSを作成したかったので、ここで作成しました。

    /********************************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学習者adHocFrequencyとSSIDについては、それらがクラッシュを引き起こしていたので少し削除しましたが、私の結果はそれらがなくても良好でした。


0

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ソリューションと同じ方法でこれを解決する方法はありますか?反射あり?


eapの場合、リフレクションは、必要な特定のフィールドでは機能しません。あなたはあなたの問題を解決しましたか?
Prashanth Debbadwar 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.