プログラムでAndroidの特定のWi-Fiネットワークに接続するにはどうすればよいですか?


294

利用可能なWi-Fiネットワークのリストを表示し、ユーザーが選択したネットワークに接続するアプリを設計したいと思います。

スキャン結果を表示する部分を実装しました。次に、スキャン結果のリストからユーザーが選択した特定のネットワークに接続したいと思います。

どうすればよいですか?



:これは私のためWPA2およびWEP働いstackoverflow.com/a/29575563/7337517
Kundan

回答:


441

次のWifiConfigurationようなインスタンスを作成する必要があります。

String networkSSID = "test";
String networkPass = "pass";

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";   // Please note the quotes. String should contain ssid in quotes

次に、WEPネットワークの場合、これを行う必要があります。

conf.wepKeys[0] = "\"" + networkPass + "\""; 
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 

WPAネットワークの場合、次のようなパスフレーズを追加する必要があります。

conf.preSharedKey = "\""+ networkPass +"\"";

オープンネットワークの場合、これを行う必要があります。

conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

次に、それをAndroid wifiマネージャーの設定に追加する必要があります。

WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
wifiManager.addNetwork(conf);

そして最後に、それを有効にする必要があるかもしれませんので、Androidはそれに接続します:

List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
    if(i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
         wifiManager.disconnect();
         wifiManager.enableNetwork(i.networkId, true);
         wifiManager.reconnect();               

         break;
    }           
 }

UPD:WEPの場合、パスワードが16進数の場合、引用符で囲む必要はありません。


5
それはうまくいきます!ありがとうございます:)しかし、もう一つお願いしたいことがあります。allowedPairwiseCipher、allowedAuthALgorithms、およびallowedProtocolsを設定する必要はありませんか?また、設定する特定の属性を決定する方法。WEPネットワークのGroupCipherにWEP40を設定したようですか?
Vikram Gupta

8
一つ忘れてしまいました。WEPの場合、パスワードが16進数の場合、引用符で囲む必要はありません。
ケノタ2012年

8
素晴らしい解決策をありがとう、接続が成功したかどうかを確認する方法について詳しく説明していただけますか。たとえば、ユーザーが間違ったパスワードを入力した場合、そのことを通知する必要があります。
Pascal Klein

3
必要なWifiホットスポットがパスワードをまったく使用しない場合はどうでしょうか。....preSharedKey = nullを使用する必要があります。または.preSharedKey = ""を設定する必要があります。どちらが正しいか?@kenota
gumuruh 2014

6
それは私にとっては機能しません:新しいものに接続するのではなく、以前に記憶されたwifiに直接再接続します。
Virthuss、2016年

138

以前の答えは動作しますが、解決策は実際には簡単になることができます。WifiManagerを介してネットワークを追加するときにネットワークIDを取得するため、構成済みネットワークリストをループする必要はありません。

したがって、完全で単純化されたソリューションは次のようになります。

WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"", ssid);
wifiConfig.preSharedKey = String.format("\"%s\"", key);

WifiManager wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
//remember id
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();

1
パスワードを使用しない場合。.preSharedKey = null; または、空の文字列@seanloyolaを置く必要がありますか?
gumuruh 2014

2
@MuhammedRefaatは、すでに別のネットワークに接続している場合に切断します。
sean loyola 2014年

1
@gumuruh必要なキーがない場合は、事前共有キーオブジェクトを含める必要はありません。
sean loyola 2014年

7
あなたは真のブールdisableOthersを使用する場合enableNetworkのjavadocツールによると、その後、あなたが切断したり、接続するために持っていけない、それはあなたのための両方を行います
NikkyD

12
おそらくCHANGE_WIFI_STATE許可が必要であることを言及する必要があります。
ThomasW

27

WIFIネットワークに接続する前に、WIFIネットワークのセキュリティタイプを確認する必要があります。ScanResultクラスには機能があります。このフィールドには、ネットワークのタイプが表示されます

参照:https : //developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities

WIFIネットワークには3つのタイプがあります。

最初に、WifiConfigurationオブジェクトをインスタンス化し、ネットワークのSSIDを入力し(二重引用符で囲む必要があることに注意)、初期状態を無効に設定し、ネットワークの優先順位を指定します(約40の数値が適切に機能するようです)。

WifiConfiguration wfc = new WifiConfiguration();

wfc.SSID = "\"".concat(ssid).concat("\"");
wfc.status = WifiConfiguration.Status.DISABLED;
wfc.priority = 40;

次に、より複雑な部分について説明します。ネットワークのセキュリティモードを指定するには、WifiConfigurationのいくつかのメンバーを埋める必要があります。オープンネットワーク用。

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedAuthAlgorithms.clear();
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

WEPを使用するネットワークの場合。WEPキーも二重引用符で囲まれていることに注意してください。

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

if (isHexString(password)) wfc.wepKeys[0] = password;
else wfc.wepKeys[0] = "\"".concat(password).concat("\"");
wfc.wepTxKeyIndex = 0;

WPAとWPA2を使用するネットワークでは、どちらにも同じ値を設定できます。

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

wfc.preSharedKey = "\"".concat(password).concat("\"");

最後に、ネットワークをWifiManagerの既知のリストに追加できます。

WifiManager wfMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
int networkId = wfMgr.addNetwork(wfc);
if (networkId != -1) {
 // success, can call wfMgr.enableNetwork(networkId, true) to connect
} 

優先度についてのメモ、私の電話番号では約4000が機能しました。その部分をもう少し動的にするために最も良いと思われます(既存の構成を繰り返すなど)
Sam


@shantanuで詳細を確認してください。stackoverflow.com/questions/6866153/...
Kalpesh Gohel

samsungデバイスでは、パスフレーズはハッシュされた文字列です。そして、コードは機能しません。確認しますか?
グエンミンビン2016年

simタイプのwifiのEAPを接続するためのサンプルを提供できますか?
Prashanth Debbadwar 16

19

@ raji-ramamoorthiと@kenotaへのクレジット

私のために働いた解決策は、このスレッドの上記の貢献者の組み合わせです。

ScanResultここに来るのはプロセスです。

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (wifi.isWifiEnabled() == false) {
            Toast.makeText(getApplicationContext(), "wifi is disabled..making it enabled", Toast.LENGTH_LONG).show();
            wifi.setWifiEnabled(true);
        }

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent intent) {
                 wifi.getScanResults();
            }
        };

通知unregisterのそれonPauseonStopこのライブunregisterReceiver(broadcastReceiver);

public void connectWiFi(ScanResult scanResult) {
        try {

            Log.v("rht", "Item clicked, SSID " + scanResult.SSID + " Security : " + scanResult.capabilities);

            String networkSSID = scanResult.SSID;
            String networkPass = "12345678";

            WifiConfiguration conf = new WifiConfiguration();
            conf.SSID = "\"" + networkSSID + "\"";   // Please note the quotes. String should contain ssid in quotes
            conf.status = WifiConfiguration.Status.ENABLED;
            conf.priority = 40;

            if (scanResult.capabilities.toUpperCase().contains("WEP")) {
                Log.v("rht", "Configuring WEP");    
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

                if (networkPass.matches("^[0-9a-fA-F]+$")) {
                    conf.wepKeys[0] = networkPass;
                } else {
                    conf.wepKeys[0] = "\"".concat(networkPass).concat("\"");
                }

                conf.wepTxKeyIndex = 0;

            } else if (scanResult.capabilities.toUpperCase().contains("WPA")) {
                Log.v("rht", "Configuring WPA");

                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

                conf.preSharedKey = "\"" + networkPass + "\"";

            } else {
                Log.v("rht", "Configuring OPEN network");
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedAuthAlgorithms.clear();
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            }

            WifiManager wifiManager = (WifiManager) WiFiApplicationCore.getAppContext().getSystemService(Context.WIFI_SERVICE);
            int networkId = wifiManager.addNetwork(conf);

            Log.v("rht", "Add result " + networkId);

            List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
            for (WifiConfiguration i : list) {
                if (i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
                    Log.v("rht", "WifiConfiguration SSID " + i.SSID);

                    boolean isDisconnected = wifiManager.disconnect();
                    Log.v("rht", "isDisconnected : " + isDisconnected);

                    boolean isEnabled = wifiManager.enableNetwork(i.networkId, true);
                    Log.v("rht", "isEnabled : " + isEnabled);

                    boolean isReconnected = wifiManager.reconnect();
                    Log.v("rht", "isReconnected : " + isReconnected);

                    break;
                }
            }

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

5

お使いのデバイスがWifi設定(すでに保存されている)を知っている場合は、ロケットサイエンスをバイパスできます。設定をループして、SSIDが一致するかどうかを確認します。その場合は、接続して戻ります。

権限を設定します。

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

接続:

    try {
    String ssid = null;
    if (wifi == Wifi.PCAN_WIRELESS_GATEWAY) {
        ssid = AesPrefs.get(AesConst.PCAN_WIRELESS_SSID,
                context.getString(R.string.pcan_wireless_ssid_default));
    } else if (wifi == Wifi.KJ_WIFI) {
        ssid = context.getString(R.string.remote_wifi_ssid_default);
    }

    WifiManager wifiManager = (WifiManager) context.getApplicationContext()
            .getSystemService(Context.WIFI_SERVICE);

    List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();

    for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
        if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
            wifiManager.enableNetwork(wifiConfiguration.networkId, true);
            Log.i(TAG, "connectToWifi: will enable " + wifiConfiguration.SSID);
            wifiManager.reconnect();
            return null; // return! (sometimes logcat showed me network-entries twice,
            // which may will end in bugs)
        }
    }
} catch (NullPointerException | IllegalStateException e) {
    Log.e(TAG, "connectToWifi: Missing network configuration.");
}
return null;

5

WPA / WPA2の回答が機能しない理由を理解するために頭を痛めました...何時間も試行した後、私はあなたが欠けているものを見つけました:

conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

WPAネットワークには必須です!!!!

今、それは動作します:)


4

これは、特定のwifiへの接続を強制するためにサブクラス化できるアクティビティです。https//github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/ WifiActivity.java

このアクティビティをサブクラス化し、そのメソッドを実装する必要があります。

public class SampleActivity extends WifiBaseActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  }

  @Override
  protected int getSecondsTimeout() {
      return 10;
  }

  @Override
  protected String getWifiSSID() {
      return "WifiNetwork";
  }

  @Override
  protected String getWifiPass() {
      return "123456";
  }
}

リンクダウンして新しいものを与えることができますか?
StartCoding 2018年

4

APIレベル29では、WifiManager.enableNetwork()メソッドは非推奨です。Android APIのドキュメントに従って(ここをチェックしてください):

  1. Wi-Fiネットワークへの接続をトリガーする新しいメカニズムについては、WifiNetworkSpecifier.Builder#build()を参照してください。
  2. Wi-Fiに自動接続する際の考慮事項としてWi-Fiネットワークを追加するための新しいAPIについては、addNetworkSuggestions(java.util.List)、removeNetworkSuggestions(java.util.List)を参照してください。互換性に関する注意:Build.VERSION_CODES.Q以上を対象とするアプリケーションの場合、このAPIは常にfalseを返します。

APIレベル29以降、WiFiネットワークに接続するには、を使用する必要がありますWifiNetworkSpecifier。サンプルコードはhttps://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build()にあります。


新しいWifiNetWorkSpecifier.Builderを使用してWEPネットワークに接続することはできますか?WEPパスフレーズをビルダーに追加する方法が見つかりません。
Dieter27

番号1は機能していないようですが、コールバックはありますか?
Faizan Mir

1

また、ネットワークに接続してみました。上記で提案されたソリューションは、hugerock t70では機能しません。関数wifiManager.disconnect(); 現在のネットワークから切断しません。したがって、指定されたネットワークに再接続できません。上記のコードを変更しました。私にとってコードbolowは完全に機能します:

String networkSSID = "test";
String networkPass = "pass";

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";   
conf.wepKeys[0] = "\"" + networkPass + "\""; 
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 
conf.preSharedKey = "\""+ networkPass +"\"";

WifiManager wifiManager =         
(WifiManager)context.getSystemService(Context.WIFI_SERVICE);    

int networkId = wifiManager.addNetwork(conf);
wifi_inf = wifiManager.getConnectionInfo();

/////important!!!
wifiManager.disableNetwork(wifi_inf.getNetworkId());
/////////////////

wifiManager.enableNetwork(networkId, true);

私はAndroidの10でエラーが出ます:UID nnnnn does not have permission to update configuration xxxx. MD_START_CONNECT but no requests and connected, but app does not have sufficient permissions, bailing.
ルイス・A. Florit

0

この方法を試してください。それは超簡単:

public static boolean setSsidAndPassword(Context context, String ssid, String ssidPassword) {
    try {
        WifiManager wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
        Method getConfigMethod = wifiManager.getClass().getMethod("getWifiApConfiguration");
        WifiConfiguration wifiConfig = (WifiConfiguration) getConfigMethod.invoke(wifiManager);

        wifiConfig.SSID = ssid;
        wifiConfig.preSharedKey = ssidPassword;

        Method setConfigMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
        setConfigMethod.invoke(wifiManager, wifiConfig);

        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.