[Android]WiFi接続まわりで苦戦したのでメモ

Mar 8, 2013   #Android 

AndroidのWiFi設定や変更において、色々と苦戦したのでその時の記録をメモ。

(*2013年3月現在 : APILevel8~16にて動作確認)

こちらの記事内容で動作確認は出来ましたが、動作保証はしかねますので、使用の際には再度ドキュメントを確認した方が良いかと思います。

また、端末によって微妙に挙動が異なったり、WiFi切替まで時間もかかったりと、色々と下記以外にも調整しないといけない事が多かったです。

Androidリファレンス:WifiManager
Androidリファレンス:WifiConfiguration

使用するために

まずAndroidManifest.xmlに下記のパーミッション追加をする必要があります。

<uses-permission android:name="android.permission.CHANGE\_WIFI\_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS\_WIFI\_STATE"></uses-permission>

WiFi機能をONにする

SSID登録の際は、WiFi機能が有効でないと出来ないので、もしプログラム内で有効にするには下記の方法で行う

WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled() == false) {
    wifiManager.setWifiEnabled(true);
}

上記のコードをActivityのonCreate等で実行しておくと良いかと思います。

端末によっては、切り替わるまで少々時間もかかるようなんで注意も必要ですね。

SSIDを端末に設定する

こちらもWiFi機能が無効の場合、正しく設定することができないので、先に有効にする処理を入れる必要があります。

また、設定については認証方式毎に異なります。

セキュリティなしのSSIDを設定する

WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String ssid = "SSID_NAME";
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"" + ssid + "\"";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedAuthAlgorithms.clear();
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
int networkId = wifiManager.addNetwork(config); // 失敗した場合は-1となります
wifiManager.saveConfiguration();
wifiManager.updateNetwork(config);

認証方式 : WEPのSSID設定

WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String ssid = "SSID_NAME";
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"" + ssid + "\"";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.wepKeys[0] = "\"password\"";
config.wepTxKeyIndex = 0;
int networkId = wifiManager.addNetwork(config); // 失敗した場合は-1となります
wifiManager.saveConfiguration();
wifiManager.updateNetwork(config);

認証方式 : WPA/WPA2-PSKのSSID設定

WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String ssid = "SSID_NAME";
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"" + ssid + "\"";
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.preSharedKey = "\"password\"";
int networkId = wifiManager.addNetwork(config); // 失敗した場合は-1となります
wifiManager.saveConfiguration();
wifiManager.updateNetwork(config);

上記で作成したSSIDに接続する

networkIdが正しくとれていれば実際に接続を試してみます。

WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
int networkId = 0; // 上記設定で取得できたものを使用
String targetSSID = "hoge-ssid";
// WiFi機能が無効の状態で呼び出されるとSSID検索の所でnullとなるので念のため例外処理を行なう
try {
    // ssidの検索を開始
    wifiManager.startScan();
    for (ScanResult result : wifiManager.getScanResults()) {
        // Android4.2以降よりダブルクォーテーションが付いてくるので除去
        String resultSSID = result.SSID.replace("\"", "");
        if (resultSSID.equals(targetSSID)) {
            // 接続を行う
            if (networkId > 0) {
                // 先に既存接続先を無効にしてから接続します
                for (WifiConfiguration c0 : wifiManager.getConfiguredNetworks()) {
                    wifiManager.enableNetwork(c0.networkId, false);
                }
                wifiManager.enableNetwork(networkId, true);
            }
            break;
        }
    }
} catch (NullPointerException e) {
   // 適切な例外処理をしてください。
}

これでひと通りSSID設定と、接続まで出来るようになりました。

接続タイミングやWiFi切替等、微妙に調整の必要があるため結構大変でした。

また、認証方式毎の設定についても理解しきれていない所もあるんで、もっと勉強しないとなと思いました。

詳しい方いましたら、ぜひアドバイスや間違いをご指摘頂けると嬉しいです。