314

我想设计一个显示可用 Wi-Fi 网络列表并连接到用户选择的任何网络的应用程序。

我已经实现了显示扫描结果的部分。现在我想连接到用户从扫描结果列表中选择的特定网络。

我该怎么做呢?

4

11 回答 11

463

您需要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 的情况下,如果您的密码是十六进制的,则不需要用引号括起来。

于 2012-01-11T11:30:27.350 回答
145

较早的答案有效,但解决方案实际上可以更简单。当您通过 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();
于 2013-12-10T20:43:58.807 回答
32

在连接 WIFI 网络之前,您需要检查 WIFI 网络的安全类型 ScanResult 类有一个功能。此字段为您提供网络类型

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

WIFI网络分为三种

首先,实例化一个 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
} 
于 2014-09-02T12:11:18.450 回答
20

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

注意unregisteronPauseonStop活下去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();
        }
    }
于 2016-06-23T12:26:12.187 回答
12

在 API 级别 29 中,WifiManager.enableNetwork()方法已弃用。根据 Android API 文档(在此处查看):

  1. 有关触发连接到 Wi-Fi 网络的新机制,请参阅 WifiNetworkSpecifier.Builder#build()。
  2. 请参阅 addNetworkSuggestions(java.util.List)、removeNetworkSuggestions(java.util.List) 了解用于添加 Wi-Fi 网络的新 API,以便在自动连接到 wifi 时考虑。兼容性说明:对于面向 Build.VERSION_CODES.Q 或更高版本的应用程序,此 API 将始终返回 false。

从 API 级别 29 开始,要连接到 WiFi 网络,您需要使用WifiNetworkSpecifier. 您可以在https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build()找到示例代码

于 2020-01-23T05:41:25.813 回答
6

如果您的设备知道 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;
于 2017-05-25T01:41:48.430 回答
6

我想明白为什么您对 WPA/WPA2 的回答不起作用……经过数小时的尝试,我发现您缺少什么:

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

是 WPA 网络所必需的!!!!

现在,它起作用了:)

于 2017-07-27T09:32:12.740 回答
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";
  }
}
于 2015-05-26T11:54:23.763 回答
4

我也尝试连接到网络。以上提出的解决方案均不适用于 hugerock t70。函数 wifiManager.disconnect(); 不会断开与当前网络的连接。Аnd 因此无法重新连接到指定的网络。我已经修改了上面的代码。对我来说,下面的代码完美地工作:

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);
于 2018-09-24T18:52:13.007 回答
2

获取 Wifi 列表,连接到 Wifi(Android <=9 和 Android >=10)

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Net;
using Android.Net.Wifi;
using Xamarin.Essentials;

[assembly: Xamarin.Forms.Dependency(typeof(Wifi))]
namespace configurator.Droid.Services
{
    public class Wifi : IWifi
    {
    private NetworkCallback _callback;
    private bool _requested;
    private Context _context = null;
    private WifiManager _wifiManager = null;
    private string _statusText;

    public Wifi()
    {
        this._context = Android.App.Application.Context;
    }

    [Obsolete]
    public void ConnectToWifi(string ssid, string password)
    {
        if (!_wifiManager.IsWifiEnabled)
            _wifiManager.SetWifiEnabled(true);
        
        Version version = Xamarin.Essentials.DeviceInfo.Version;
        if (version.Major <= 9 && version.Minor < 9)
        {
            var config = new WifiConfiguration();
            config.Ssid = "\"" + ssid + "\"";
            config.PreSharedKey = "\"" + password + "\"";
            var temp = _wifiManager.AddNetwork(config);
            _wifiManager.Disconnect();
            _wifiManager.EnableNetwork(temp, true);
            _wifiManager.Reconnect();
        }
        else
        {
           
            var specifier = new WifiNetworkSpecifier.Builder()
            .SetSsid(ssid)
            .SetWpa2Passphrase(password)
            .Build();

            var request = new NetworkRequest.Builder()
                .AddTransportType(TransportType.Wifi) // we want WiFi
                .RemoveCapability(NetCapability.Internet) // Internet not required
                .SetNetworkSpecifier(specifier) // we want _our_ network
                .Build();

            var connectivityManager = _context.GetSystemService(Context.ConnectivityService) as ConnectivityManager;

            if (_requested)
            {
                connectivityManager.UnregisterNetworkCallback(_callback);
            }

            _callback = new NetworkCallback
            {
                NetworkAvailable = network =>
                {
                    // we are connected!
                    _statusText = $"Request network available";
                },
                NetworkUnavailable = () =>
                {
                    _statusText = $"Request network unavailable";
                }
            };
            connectivityManager.RequestNetwork(request, _callback);
            _requested = true;
        }
        
    }

    [Obsolete]
    public async Task<IEnumerable<string>> GetAvailableNetworksAsync()
    {
        var location = await Geolocation.GetLastKnownLocationAsync();
        IEnumerable<string> availableNetworks = null;

        // Get a handle to the Wifi
        _wifiManager = 
    `(WifiManager)_context.GetSystemService(Context.WifiService);`
        if (!_wifiManager.IsWifiEnabled)
            _wifiManager.SetWifiEnabled(true);
        var wifiReceiver = new WifiReceiver(_wifiManager);

        await Task.Run(() =>
        {
            // Start a scan and register the Broadcast receiver to get 
        the list of Wifi Networks
            _context.RegisterReceiver(wifiReceiver, new 
    IntentFilter(WifiManager.ScanResultsAvailableAction));
            availableNetworks = wifiReceiver.Scan();
        });

        return availableNetworks;
    }
    private class NetworkCallback : ConnectivityManager.NetworkCallback
    {
        public Action<Network> NetworkAvailable { get; set; }
        public Action NetworkUnavailable { get; set; }

        public override void OnAvailable(Network network)
        {
            base.OnAvailable(network);
            NetworkAvailable?.Invoke(network);
        }

        public override void OnUnavailable()
        {
            base.OnUnavailable();
            NetworkUnavailable?.Invoke();
        }
    }

    [BroadcastReceiver(Enabled = true, Exported = false)]
    class WifiReceiver : BroadcastReceiver
    {
        private WifiManager _wifi;
        private List<string> _wifiNetworks;
        private AutoResetEvent _receiverARE;
        private Timer _tmr;
        private const int TIMEOUT_MILLIS = 20000; // 20 seconds timeout

        public WifiReceiver()
        {

        }
        public WifiReceiver(WifiManager wifi)
        {
            this._wifi = wifi;
            _wifiNetworks = new List<string>();
            _receiverARE = new AutoResetEvent(false);
        }

        [Obsolete]
        public IEnumerable<string> Scan()
        {
            _tmr = new Timer(Timeout, null, TIMEOUT_MILLIS, 
      System.Threading.Timeout.Infinite);
            _wifi.StartScan();
            _receiverARE.WaitOne();
            return _wifiNetworks;
        }

        public override void OnReceive(Context context, Intent intent)
        {
            IList<ScanResult> scanwifinetworks = _wifi.ScanResults;
            foreach (ScanResult wifinetwork in scanwifinetworks)
            {
                _wifiNetworks.Add(wifinetwork.Ssid);
            }

            _receiverARE.Set();
        }

        private void Timeout(object sender)
        {
            // NOTE release scan, which we are using now, or we throw an 
              error?
            _receiverARE.Set();
        }
       }
     }

   }
于 2021-09-14T20:00:03.393 回答
1

试试这个方法。这很容易:

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;
    }
}
于 2016-09-22T05:52:08.067 回答