Android Connect to open WiFi - Fragmented between Nexus 5 and Nexus 5X - android

While using this to connect to an open WiFi network (that is not configured yet on the device):
public static void connectToWifiNetwork(Context context, final String ssid, String password) {
final WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiManager.disconnect();
// Delete already available network
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for (WifiConfiguration i : list) {
if(i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
Log.i(TAG, "Deleting configuration for " + ssid);
wifiManager.removeNetwork(i.networkId);
break;
}
}
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + ssid + "\"";
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
Log.d(TAG, "Added network " + ssid + " " + password);
final int addNetworkResult = wifiManager.addNetwork(conf);
new Thread(new Runnable() {
#Override
public void run() {
Log.d(TAG, "Attempting to connect to " + ssid + " with id " + addNetworkResult);
wifiManager.enableNetwork(addNetworkResult, true);
}
}).start();
}
On Nexus 5 with API 23 (6.0.1), the added network has result -1, does not connect.
On Nexus 5X with API 26 (8.0.0), the added network has result 2, connects fine.
I am building for target API 25.
I am not sure if it is about the API level or the device, but I'd like to have a solution to rule them all.
Any ideas?
Edit:
Also tried with ALL the configurations as in this SO question:
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);
Didn't work on Nexus 5 as well.
Note: I can connect to WEP/WPA/WPA2 programmatically using both devices by using this implementation.

For some reason, I had to manually delete the open network from Android's WiFi settings (even though connecting through it works fine). It now connects, but not every time.
It disconnects from current network, tries to connect to the open network, then connects to the previous network again.

Related

How to programmatically change password of a saved wifi network in Android (API level 23, Android 6.0)

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

Android Marshmallow - How to avoid Wi-Fi drop if No Internet access

I'm writing an app that connects to an hotspot with no internet connection.
It seems that on some Nexus devices with Android Marshmallow, when you connect to a network with no internet requests, the system "drops" the wifi connection and all request are not sent to the hotspot connection.
After a few seconds, a notification pops up asking if you want to stay connected to it. When the answer is "Yes", requests are sent to the hotspot successfully and you're able to get responses.
I've encountered the following thread:
https://android.stackexchange.com/questions/131132/force-marshmallow-to-keep-a-wi-fi-without-internet-access
However, I'm looking for a programmatically way (for not rooted devices) to tackle this problem.
I'm currently connecting to Wifi networks with the following code:
public void connectTo(String capabilities, String password, String ssid) {
WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + ssid + "\"";
if (capabilities.contains("WPA2")) {
conf.preSharedKey = "\"" + password + "\"";
} else if (capabilities.contains("WPA")) {
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);
}
mWifiManager.addNetwork(conf);
List<WifiConfiguration> list = mWifiManager.getConfiguredNetworks();
if (list == null) {
return;
}
for (WifiConfiguration i : list) {
if (i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
mWifiManager.disconnect();
mWifiManager.enableNetwork(i.networkId, true);
mWifiManager.reconnect();
break;
}
}
}

Network id is -1 for latest versions in android

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.

How to connect to wifi with a specific bssid android?

I am creating an Android app which allows to connect you to a WiFi with a specific BSSID. I have implemented the part which scan all the wifis and make the WiFi configuration in function of WiFi network security type. I have also implemented the connection to WiFi network with a specific BSSID.
But I have a problem: the connection to a specific BSSID works well for secure networks but doesn't work really for open network and I don't know why. Indeed this connection to an open network with a specific BSSID works on Samsung Galaxy S4 or more recent but doesn't work on Galaxy S2 and S3 ... It's really weird. On S2 and S3 the BSSID isn't take into account during connection.
This is the sample code that I use to create the configuration for a open network and try to connect on it with the specific BSSIDs:
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + wifiItem.getSSID() + "\"";
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiManager wifiManager = (WifiManager) parentActivity.getSystemService(Context.WIFI_SERVICE);
wifiManager.addNetwork(conf);
conf.BSSID = wifiItem.getBSSID();
wifiManager.updateNetwork(conf);
wifiManager.saveConfiguration();
for (WifiConfiguration wifiConfiguration : wifiManager.getConfiguredNetworks()) {
if (wifiConfiguration.SSID.equals("\"" + wifiItem.getSSID() + "\"")) {
wifiManager.disconnect();
wifiConfiguration.BSSID = wifiItem.getBSSID();
wifiManager.updateNetwork(wifiConfiguration);
wifiManager.enableNetwork(wifiConfiguration.networkId, true);
wifiManager.reconnect();
}
If someone could help me it would be so cool. I spent a lot of time on it and really don't understand this problem.
You can try looking this code over, this is what we use to connect to networks:
private void connectToNetwork(String password, ScanResult result, String capabilities) {
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"" + result.SSID + "\"";
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
if (capabilities.contains("WPA2")) {
wc.preSharedKey = "\"" + password + "\"";
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
}
if (capabilities.contains("WPA")) {
wc.preSharedKey = "\"" + password + "\"";
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
}
if (capabilities.contains("WEP")) {
wc.wepKeys[0] = password;
wc.wepTxKeyIndex = 0;
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
}
if (capabilities.contains("TKIP")) {
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
}
if (capabilities.contains("CCMP")) {
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.PairwiseCipher.CCMP);
}
if (!hasWifiSecurity(capabilities)) {
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.NONE);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
}
// wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
// // wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
// wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
int res = wifi.addNetwork(wc);
Log.d("WifiPreference", "add Network returned " + res);
boolean b = wifi.enableNetwork(res, true);
Log.d("WifiPreference", "enableNetwork returned " + b);
Log.d("", "Reassociate: " + wifi.reassociate());
Log.d("", "ReConnect: " + wifi.reconnect());
wifi.saveConfiguration();
WifiInfo connection = wifi.getConnectionInfo();
if (connection != null) {
if (connection.getSupplicantState().equals(SupplicantState.INACTIVE)) {
wifi.removeNetwork(res);
wifi.saveConfiguration();
scanForWiFiNetworks();
wifi.enableNetwork(wifi.getConnectionInfo().getNetworkId(), true);
}
}
// scanForWiFiNetworks();
// if (password.equalsIgnoreCase("")) {
// setScanningEnabled(true);
// }
// Toast.makeText(con, "Connecting to network: " + connectionInfo, Toast.LENGTH_SHORT).show(getMessageComments(dialog.getTextID()));
}
We need to connect to a 5G network with the same SSID as the 2.4G network, so the only way is to set the BSSID. i've just successfully connected to the several specified BSSID networks with the code below, have a try:
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
config.SSID = "\"" + SSID + "\"";
config.BSSID = BSSID; // <--BSSID should be set without ->"<- (-__-)b...
// remove this network from the configed(saved) network list
List<WifiConfiguration> existingConfigs = mWifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs)
{
if (null != existingConfig && existingConfig.SSID.toString().equals("\"" + SSID + "\""))
{
mWifiManager.removeNetwork(existingConfig.networkId);
}
}
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//...
//...
// get the networkid
int wcgID = mWifiManager.addNetwork(config);
// enabled this network
boolean b = mWifiManager.enableNetwork(wcgID, true);

Android 4.x static IP address for adhoc network (doesn't connect)

I'm working on an Android app that connects to custom hardware via networking.
If you set it up to use a wireless access point, it works fine.
If you set it up to use an access point on the device (aka tethering), it works fine.
If you set it up to use an ad-hoc network, it doesn't work. Android fails at the "obtaining IP address" step.
our work-around was to use a static IP address, and low and behold it worked! If you connect the tablet to our custom hardware and force a custom subnet mask and IP address, it connects instantly.
However, that's too confusing. DHCP or GTFO. Our solution uses a custom network manager, and if it's an ad-hoc network force a static IP address automatically. This should work.
I've followed the directions at this link (with some modifications) and it works perfectly-ish. You can select the network, assign it a static IP address, and that's it. The android tablet will never connect to the network. However, if you look at the network under the "real" wifi manager and select "modify settings", you can see where all of the static IP address information is saved. It just won't connect.
Adding to my misery, if you remove the network, and go to the android wifi manager and enter the information in manually, it works. but not if you do the same steps programatically.
Does anyone know why this is, or how to fix it? This is on a rooted nexus 7.
Thanks in advance.
public void connectToWiFiNetwork(String networkSSID, String networkPass, String type)
{
//Make sure a password is set
if(networkPass != null && networkPass.length() == 0)
return;
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\""; // Please note the quotes. String should contain ssid in quotes
conf.status = WifiConfiguration.Status.ENABLED;
int id = -1;
if(type.contains("WPA")) {
conf.preSharedKey = "\""+ networkPass +"\"";
//conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
System.out.println("Contains WPA");
} else if (type.contains("WEP")) {
conf.wepKeys[0] = "\"" + networkPass + "\"";
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
System.out.println("Contains WEP");
} else {
//open network?
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
System.out.println("Open WiFi");
}
if(type.contains("IBSS"))
{
//Adhoc network. Provide an IP address to prevent... stuff.
//For Android 2.x
//final ContentResolver cr = this.context.getContentResolver();
//Settings.System.putInt(cr, Settings.System.WIFI_USE_STATIC_IP, 1);
//Settings.System.putString(cr, Settings.System.WIFI_STATIC_IP, "169.254.1.1");
//Settings.System.putString(cr, Settings.System.WIFI_STATIC_NETMASK, "255.255.0.0");
try{
//Some code here isn't used...
WifiConfiguration wifiConf = null;
WifiManager wifiManager = (WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
WifiInfo connectionInfo = wifiManager.getConnectionInfo();
List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
for (WifiConfiguration conf2 : configuredNetworks){
if (conf2.networkId == connectionInfo.getNetworkId()){
wifiConf = conf2;
break;
}
}
wifiConf = conf;
setIpAssignment("STATIC", wifiConf); //or "DHCP" for dynamic setting
Log.d("CONNECTION", "Connecting now using a static IP address");
setIpAddress(InetAddress.getByName("169.254.1.1"), 24, wifiConf);
Log.d("CONNECTION", "Connecting now using a static IP address");
setGateway(InetAddress.getByName("255.255.0.0"), wifiConf);
Log.d("CONNECTION", "Connecting now using a static IP address");
setDNS(InetAddress.getByName("8.8.8.8"), wifiConf);
Log.d("CONNECTION", "Connecting now using a static IP address");
//wifiManager.updateNetwork(wifiConf); //apply the setting
Log.d("CONNECTION", "Connecting now using a static IP address");
}catch(Exception e){
e.printStackTrace();
}
}
id = wifi.addNetwork(conf);
wifi.saveConfiguration();
//Add the network
//And enable it
List<WifiConfiguration> list = wifi.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
if(i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
wifi.disconnect();
wifi.enableNetwork(i.networkId, true);
wifi.reconnect();
break;
}
}
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("auto_start_tethering", false);
editor.commit();
Log.d("CONNECTION", "Connecting using " + networkSSID + " and " + networkPass + ".");
}

Categories

Resources