Как программно подключиться к определенной сети Wi-Fi в Android?
Я хочу разработать приложение, которое показывает список доступных сетей Wi-Fi и подключается к любой сети, выбранной пользователем.
Я реализовал часть, показывающую результаты сканирования. Теперь я хочу подключиться к определенной сети, выбранной пользователем из списка результатов сканирования.
Как мне это сделать?
12 ответов
Вам нужно создать 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-менеджера Wi-Fi:
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, если ваш пароль в шестнадцатеричном виде, вам не нужно заключать его в кавычки.
Более ранний ответ работает, но решение на самом деле может быть проще. Циклический просмотр списка настроенных сетей не требуется, поскольку вы получаете идентификатор сети при добавлении сети через WifiManager.
Таким образом, полное упрощенное решение будет выглядеть примерно так:
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();
Перед подключением к сети WIFI необходимо проверить тип безопасности сети WIFI, который имеет класс ScanResult. В этом поле указан тип сети
См. https://developer.android.com/reference/android/net/wifi/ScanResult.html
Существует три типа сетей 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
}
Кредит @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
это на onPause
& onStop
живи этим 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();
}
}
На уровне API 29, WifiManager.enableNetwork()
метод устарел. Согласно документации Android API (проверьте здесь):
- См. WifiNetworkSpecifier.Builder#build() для получения информации о новом механизме подключения к сети Wi-Fi.
- См. AddNetworkSuggestions(java.util.List), removeNetworkSuggestions(java.util.List), чтобы узнать о новом API для добавления сетей Wi-Fi для рассмотрения при автоматическом подключении к Wi-Fi. Примечание о совместимости: для приложений, предназначенных для Build.VERSION_CODES.Q или выше, этот API всегда будет возвращать false.
Начиная с уровня API 29, для подключения к сети Wi-Fi вам необходимо использовать WifiNetworkSpecifier
. Вы можете найти пример кода на https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html
Я сломал голову, чтобы понять, почему ваши ответы на WPA/WPA2 не работают... после нескольких часов попыток я нашел то, что вам не хватает:
conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
ТРЕБУЕТСЯ для сетей WPA!!!!
Теперь это работает:)
Если ваше устройство знает настройки Wi-Fi (уже сохранены), мы можем обойти ракетостроение. Просто прокрутите конфиги и проверьте, совпадает ли 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;
Это действие, которое вы можете создать подклассом для принудительного подключения к определенному Wi-Fi: 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";
}
}
Я также пытался подключиться к сети. Ни одно из предложенных выше решений не работает для 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 +"\"";
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
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);
Получить список Wi-Fi, подключиться к Wi-Fi (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 c4configurator.Droid.Services;
using c4configurator.Interfaces;
using Xamarin.Essentials;
[assembly: Xamarin.Forms.Dependency(typeof(Wifi))]
namespace c4configurator.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();
}
}
}
}
Попробуйте этот метод. Это очень просто:
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;
}
}
/**
* @param context Context
* @return true if device is connected to Internet
*/
public static boolean isNetworkConnected(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}