如何以编程方式更改 Android 中保存的 wifi 网络的密码(API 级别 23,Android 6.0)
How to programmatically change password of a saved wifi network in Android (API level 23, Android 6.0)
前提:
我目前正在开发一个 Android 应用程序(API 级别 23,Android 6.0),它通过 Wi-Fi 连接设备并使用 UDP 数据包进行通信。我可以使用特定命令更改设备 Wi-Fi 密码。这很好用。
目标:
我想以编程方式做的是:
- 搜索从设备生成的 Wi-Fi
- 连接到设备
- 发送修改密码指令
- 使用新密码重新连接到设备
我可以使用如下代码首次连接(步骤 1、2、3):
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();
}
附加信息:
我在清单文件中声明了这些权限:
<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" />
问题:
如果我在更改密码后尝试使用相同的方法连接,我将无法连接,因为(我认为)Android 记住了以前的密码。
如果我尝试使用 updateNetwork(conf)
而不是 addNetwork(conf)
,我没有发现任何差异。
我尝试以某些方式删除或禁用已保存的网络,然后再次尝试连接,但未成功。
mWifiManager.removeNetwork(netId)
returns false(我不知道为什么会失败)
mWifiManager.disableNetwork(netId);
returns 是的,但似乎没有效果
如果我使用 Android 设置更改密码,一切正常...但我想以编程方式更改保存的密码。
非常感谢任何帮助
经过几次尝试,我目前按照下面报告的说明没有问题。
在连接到 Wi-Fi 网络之前,请务必检查之前保存的网络列表。如果没有具有相同 SSID 的网络,则可以创建新配置,否则需要修改现有配置。
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版本6之后不允许任何应用程序修改Wi-Fi网络,除非它是由应用程序自己创建的。此外,它不允许添加与之前已配置的其他名称相同的 Wi-Fi 网络。这很好奇,因为当您从设置中手动配置 Wi-Fi 网络时,它确实允许这样做。
在考虑了很长时间可能的解决方案之后,我想到也许可以为 Wifi 网络添加另一个名称,添加后,将其更改为所需的名称。我已经尝试过了并且有效。它将类似于以下内容:
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 应用程序(API 级别 23,Android 6.0),它通过 Wi-Fi 连接设备并使用 UDP 数据包进行通信。我可以使用特定命令更改设备 Wi-Fi 密码。这很好用。
目标:
我想以编程方式做的是:
- 搜索从设备生成的 Wi-Fi
- 连接到设备
- 发送修改密码指令
- 使用新密码重新连接到设备
我可以使用如下代码首次连接(步骤 1、2、3):
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();
}
附加信息:
我在清单文件中声明了这些权限:
<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" />
问题:
如果我在更改密码后尝试使用相同的方法连接,我将无法连接,因为(我认为)Android 记住了以前的密码。
如果我尝试使用 updateNetwork(conf)
而不是 addNetwork(conf)
,我没有发现任何差异。
我尝试以某些方式删除或禁用已保存的网络,然后再次尝试连接,但未成功。
mWifiManager.removeNetwork(netId)
returns false(我不知道为什么会失败)
mWifiManager.disableNetwork(netId);
returns 是的,但似乎没有效果
如果我使用 Android 设置更改密码,一切正常...但我想以编程方式更改保存的密码。
非常感谢任何帮助
经过几次尝试,我目前按照下面报告的说明没有问题。
在连接到 Wi-Fi 网络之前,请务必检查之前保存的网络列表。如果没有具有相同 SSID 的网络,则可以创建新配置,否则需要修改现有配置。
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版本6之后不允许任何应用程序修改Wi-Fi网络,除非它是由应用程序自己创建的。此外,它不允许添加与之前已配置的其他名称相同的 Wi-Fi 网络。这很好奇,因为当您从设置中手动配置 Wi-Fi 网络时,它确实允许这样做。 在考虑了很长时间可能的解决方案之后,我想到也许可以为 Wifi 网络添加另一个名称,添加后,将其更改为所需的名称。我已经尝试过了并且有效。它将类似于以下内容:
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();
}