Search code examples
androidwifiwifimanager

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:

  1. search Wi-Fi generated from the device
  2. connect to the device
  3. send the command to change the password
  4. 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


Solution

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