I've been working on a react-native application recently, and I'd like to connect the devices to a wifi network through the app. I used the react-native-wifi npm lib to achieve this but it seems i have some problems connection with my android 9 phone. Although the lib is working with an other phone which is running android 7.1 (Nougat).
The ACCESS_FINE_LOCATION permission is granted in runtime by the user, also ACCESS_WIFI_STATE and CHANGE_WIFI_STATE are granted in the manifest.
So the native module that is used is:
public Boolean connectTo(ScanResult result, String password, String ssid, Promise promise) {
//Make new configuration
WifiConfiguration conf = new WifiConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
conf.SSID = ssid;
} else {
conf.SSID = "\"" + ssid + "\"";
}
String capabilities = result.capabilities;
if (capabilities.contains("WPA") ||
capabilities.contains("WPA2") ||
capabilities.contains("WPA/WPA2 PSK")) {
// appropriate ciper is need to set according to security type used,
// ifcase of not added it will not be able to connect
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
conf.status = WifiConfiguration.Status.ENABLED;
conf.preSharedKey = "\"" + password + "\"";
} else if (capabilities.contains("WEP")) {
conf.wepKeys[0] = "\"" + password + "\"";
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
} else {
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
//Remove the existing configuration for this netwrok
List<WifiConfiguration> mWifiConfigList = wifi.getConfiguredNetworks();
int updateNetwork = -1;
for (WifiConfiguration wifiConfig : mWifiConfigList) {
if (wifiConfig.SSID.equals(conf.SSID)) {
conf.networkId = wifiConfig.networkId;
updateNetwork = wifi.updateNetwork(conf);
}
}
// If network not already in configured networks add new network
if (updateNetwork == -1) {
updateNetwork = wifi.addNetwork(conf);
wifi.saveConfiguration();
}
if (updateNetwork == -1) {
return false;
}
boolean disconnect = wifi.disconnect();
if (!disconnect) {
return false;
}
boolean enableNetwork = wifi.enableNetwork(updateNetwork, true);
if (!enableNetwork) {
return false;
}
return true;
}
(returning false means the connection didnt succeed)
I was debugging it and it seems that wifi.updateNetwork(conf) and wifi.addNetwork(conf) always return -1 no matter what (so far). By the android docs these methods should still work with the API level 28.
I'm trying to connect to a WPA2 network. Also i tried to remove the network from the wifi.getConfiguredNetworks() list but didn't change anything.
I don't know what i'm missing, but i'd be really happy if somebody could help me out with this one.
Thanks!
After all i managed to find the solution which is really simple, just had to quote the ssid and it works. Tested on API level 27 and 28.
Related
"Addnetwork" is used below Android 9.0. This method returns correctly, but it fails when Android 10.0 is used. It always returns - 1. What is the reason?
This is my core code:
public WifiConfiguration createWifiInfo(String SSID, String Password,
int Type) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
WifiConfiguration tempConfig = this.isExsits(SSID);
if (tempConfig != null) {
mWifiManager.removeNetwork(tempConfig.networkId);
}
if (Type == 1) // WIFICIPHER_NOPASS
{
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
}
return config;
}
Partial code:
WifiConfiguration wifiInfo = createWifiInfo("", "", 1);
networkId = mWifiManager.addNetwork(wifiInfo);//result: networkId:-1
WifiManager.addNetwork(WifiConfiguration config) has been deprecated in API level 29.
Instead, developers are expected to use the WifiNetworkSpecifier or "Wi-Fi suggestion API" as stated in the link above. Both APIs show a different system dialog which asks the user to connect to a specified network.
You can find an example for the WifiSuggestions API in this StackOverflow thread: Creating a custom wifi setup
Premise:
I'm currently work on an Android App (API level 23, Android 6.0) that connect with a device via Wi-Fi and uses UDP packets to communicate. I'm able to change the device Wi-Fi password using a particular command. This works fine.
Target:
What I'm tring to programmatically do is:
search Wi-Fi generated from the device
connect to the device
send the command to change the password
reconnect to the device using the new password
I'm able to connect the first time (steps 1,2,3) using code like this:
private void connect(String ssid, String password) {
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = String.format("\"%s\"", ssid);
conf.preSharedKey = String.format("\"%s\"", password);
netId = mWifiManager.addNetwork(conf);
mWifiManager.saveConfiguration();
mWifiManager.disconnect();
mWifiManager.enableNetwork(netId, true);
mWifiManager.reconnect();
}
Additional info:
In the Manifest file I declared these permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
The problem:
If I try to use the same method to connect after the change of the password, I'm not able to achive the connection because (I think) Android remembers the previous password.
If I try to use updateNetwork(conf) instead of addNetwork(conf), I don't notice any difference.
I've tried to remove or disable in some ways the saved network before try to connect again, but unsaccesfully.
mWifiManager.removeNetwork(netId)
returns false (I have no idea why it fails)
mWifiManager.disableNetwork(netId);
returns true but it appears to have no effects
If I use the Android settings to change password, all works fine... but I want to change the saved password programmatically.
Any help is very appreciated
After several attempts, I currently have no problems following the instructions I report below.
Before connecting to a Wi-Fi network it is important to check the list of previously saved networks. If there is no network with the same SSID it is possible to create a new configuration, otherwise it is necessary to modify the existing one.
public void connect(String ssid, String password) {
WifiConfiguration wifiConf = null;
WifiConfiguration savedConf = null;
//existing configured networks
List<WifiConfiguration> list = mWifiManager.getConfiguredNetworks();
if(list!=null) {
for( WifiConfiguration i : list ) {
if (i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
Log.d(TAG, "existing network found: " + i.networkId + " " + i.SSID);
savedConf = i;
break;
}
}
}
if(savedConf!=null) {
Log.d(TAG, "coping existing configuration");
wifiConf = savedConf;
} else {
Log.d(TAG, "creating new configuration");
wifiConf = new WifiConfiguration();
}
wifiConf.SSID = String.format("\"%s\"", ssid);
wifiConf.preSharedKey = String.format("\"%s\"", password);
int netId;
if(savedConf!=null) {
netId = mWifiManager.updateNetwork(wifiConf);
Log.d(TAG, "configuration updated " + netId);
} else {
netId = mWifiManager.addNetwork(wifiConf);
Log.d(TAG, "configuration created " + netId);
}
mWifiManager.saveConfiguration();
mWifiManager.disconnect();
mWifiManager.enableNetwork(netId, true);
mWifiManager.reconnect();
}
Android after version 6 does not allow any application to modify Wi-Fi networks unless it has been created by the application itself. In addition, it does not allow adding Wi-Fi networks with the same name as others already configured previously. This is very curious because when you configure Wi-Fi networks manually from the settings, it does allow it.
After thinking for a long time about a possible solution it occurred to me that perhaps the Wifi network could be added with another name and once added, change it to the desired name. I have tried it and it works. It would be something like the following:
int networkId = -1;
// Find my Wifi
List<WifiConfiguration> configuredWifis = wifiManager.getConfiguredNetworks();
for(WifiConfiguration wifi : configuredWifis)
{
if(wifi.SSID != null && wifi.SSID.equals("\"" + WIFI_SSID + "\"") && wifi.priority == WIFI_PRIORITY)
{
networkId = wifi.networkId;
}
else
{
wifiManager.disableNetwork(wifi.networkId);
wifiManager.removeNetwork(wifi.networkId); // After android 6 it really does not remove the Wifi network
wifiManager.saveConfiguration();
}
}
if(networkId == -1)
{
// If my Wifi is not yet configured then add it
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + WIFI_SSID + "\"";
conf.preSharedKey = "\""+ WIFI_PASSW +"\"";
conf.priority = WIFI_PRIORITY;
networkId = wifiManager.addNetwork(conf);
if(networkId == -1) // This ocurs when a wifi with the same name is yet configured. After Android 6 is not possible modify it.
{
Random random = new Random(System.currentTimeMillis());
int randomInteger = random.nextInt(10000);
conf.SSID = "\"" + WIFI_SSID + randomInteger + "\"";
networkId = wifiManager.addNetwork(conf); // Add my wifi with another name
conf.SSID = "\"" + WIFI_SSID + "\"";
conf.networkId = networkId;
networkId = wifiManager.updateNetwork(conf); // After my wifi is added with another name, I change it to the desired name
}
}
// Connect to my wifi
if(wifiManager.getConnectionInfo().getNetworkId() != networkId)
{
wifiManager.disconnect();
wifiManager.enableNetwork(networkId, true);
wifiManager.reconnect();
}
I have created an application to connect to selected Wifi from the list. This works fine in the android version of 4.1.2(network id = 10) but if I try to run the same application on version 4.4.2 and 4.4.4 it shows the network id value as -1.
My code to achieve this is :
private void connectToWifi2() {
// TODO Auto-generated method stub
// Main method. Write code here.
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = String.format("\"%s\"", selWifi.SSID);
conf.preSharedKey = String.format("\"%s\"", pwd.getText().toString());
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
conf.status = WifiConfiguration.Status.ENABLED;
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
conf.hiddenSSID = true;
// remember id
int netId = wifiManager.addNetwork(conf);
Log.d("RMGWiFiConfig", "netId returned" + netId);
if (netId >= 0) {
Log.i("RMGWiFiConfig", "Connecting with " + selWifi.SSID);
wifiManager.disconnect();
Boolean statusInBoolean = wifiManager.enableNetwork(netId, true);
Log.d("RMGWiFiConfig", "Enabled network returned "
+ statusInBoolean);
Log.d("RMGWiFiConfig", "Reassociate : " + wifiManager.reassociate());
Log.d("RMGWiFiConfig", "Reconnect " + wifiManager.reconnect());
} else {
Log.d("RMGWifiConfig", "Failed to add network configuration");
}
}
I tried to refer the below links but not able to resolve the problem. Or may be I am unable to fit in the solution in the right way provided in the below links.Please let me know the changes I need to do w.r.t my code.
Can not connect another android device with wifi with android lollipop
Android WifiConfiguration shows -1 for ID. How can I fix it for SSID to be recognized?
Android 6.0 Cannot add WifiConfiguration if there is already another WifiConfiguration for that SSID
android wifiManager.addNetwork returns -1
WifiConfiguration enable network in Lollipop
Android 5.0 Lollipop and 4.4 KitKat ignores my WiFi network, enableNetwork() is useless
Please Help!
Thanks
Shruti
I can't find an obvious critical reason, but I have similar code working on Android 6.x. The differences I can find are:
wc.StatusField = WifiStatus.Disabled; (enableNetwork() will update this later)
wc.PreSharedKey = "\"" + pw + "\"";
at the end: wm.SaveConfiguration();
If I had to guess, I'd say it was the first one that's causing the failure.
I am struggling through one issue that is- I am trying to connect with a SSID which is WPA2 PSK by below code:
WifiConfiguration conf = new WifiConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
conf.SSID =bed_ssid_name;
} else {
conf.SSID = "\"" + bed_ssid_name + "\"";
}
conf.preSharedKey = "\""+ networkPass +"\"";
wifi.addNetwork(conf);
List<WifiConfiguration> list = null;
list = wifi.getConfiguredNetworks();
//wifi.disconnect();
//wifi.disconnect();
for( WifiConfiguration i : list ) {
if(i.SSID != null && i.SSID.equals("\"" + bed_ssid_name + "\"")) {
System.out.println("!!!!!!!### several ssid "+i.SSID +" ssid "+"\""+bed_ssid_name+"\"");
wifi.enableNetwork(i.networkId, true);
break;
}
}
wifi.reconnect();
Above code is working fine upto KitKat. But i am facing some inconsistency issue in Lollipop. In Goggle nexus and Motorola 2nd gen some time its not connected and some its connected successfully but after some time spontaneous it get disconnect. Then after some Google i found some more permission we need to give then i have done this
public void addWifiConfig(String ssid,String password) {
// Log.d(TAG, "Inside addWifiConfig...");
if (ssid == null) {
throw new IllegalArgumentException(
"Required parameters can not be NULL #");
}
String wifiName = ssid;
WifiConfiguration conf = new WifiConfiguration();
// On devices with version Kitkat and below, We need to send SSID name
// with double quotes. On devices with version Lollipop, We need to send
// SSID name without double quotes
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
conf.SSID = wifiName;
} else {
conf.SSID = Constants.BACKSLASH + wifiName + Constants.BACKSLASH;
}
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
// conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
conf.status = WifiConfiguration.Status.ENABLED;
// conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
//conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
int newNetworkId = wifi.addNetwork(conf);
wifi.enableNetwork(newNetworkId, true);
wifi.saveConfiguration();
wifi.setWifiEnabled(true);
}
But still same issue, Please get me rid of this issue. What i am missing here.
I need to connect to hidden Wi-Fi network programmatically.
I know it's SSID, security type and password.
For some reason I can't connect it.
I can connect to the same network if it's not hidden.
Here's my code:
// configure the network
private void saveWPANetwork(WiFiNetwork network){
WifiConfiguration conf = new WifiConfiguration();
conf.SSID =network.getSSID();
conf.hiddenSSID = true;
conf.status = WifiConfiguration.Status.ENABLED;
conf.preSharedKey =network.getPassword();
conf.priority = 9999;
wifi.addNetwork(conf);
wifi.saveConfiguration();
}
// connect it
protected boolean connectToVaildNetwork() {
List<WifiConfiguration> list = wifi.getConfiguredNetworks();
if(list == null)
return false;
for( WifiConfiguration i : list ) {
for (WiFiNetwork network : config.wiFiNetworksDetails) {
if(network.getSSID().equalsIgnoreCase(i.SSID)){
wifi.enableNetwork(i.networkId, true);
return wifi.reconnect(); /// STRANGE BUT IT ALWAYS RETURNS TRUE, EVEN IF DEVICE IS NOT CONNECTED TO THE HIDDEN NETWORK!
}
}
}
return false;
}
This answer maybe late but I still post it in case of someone need.
Android 4.4.2 tested. Notes that hidden networks take longer time to connect (for my test it was around 10-15s)
wifi.reconnect() == true means that your command has been requested successfully, it does not mean that wifi is connected.
public void setWifiConfig(String ssid, String sharedKey) {
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + ssid + "\""; // Please note the quotes. String should contain ssid in quotes
conf.preSharedKey = "\"" + sharedKey + "\"";
conf.hiddenSSID = true;
conf.status = WifiConfiguration.Status.ENABLED;
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
wifiManager.addNetwork(conf);
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for (WifiConfiguration i : list) {
if (i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, true);
wifiManager.reconnect();
wifiManager.saveConfiguration();
break;
}
}
}