在 2 个 Wifi 网络之间切换,连接失败
Switching between 2 Wifi networks, connecting fails
我在 Raspberry Pi 3 运行 Android 事物上以编程方式在 2 个网络之间切换时遇到问题(但它应该与 运行 正常 Android).
第一个网络来自作为接入点的设备服务器。它运行一个 FTP 服务器,我需要通过它的网络访问它。它在我知道的 192.168.xxx.xxx 网络中有一个静态 IP 地址,并受 WPA2-PSK 保护。我有我知道正确的 SSID 和密码。该设备位于它自己创建的专用网络中,无法通过外部地址访问。连接到它的唯一方法是连接到它的网络并 FTP'ing 到它的静态地址。
第二个网络是开放网络,我也知道它的SSID。这是由另一个应用程序预先配置的,因此我的应用程序无法更新配置。
下面的代码是我目前的代码。 DownloadFilesTask 在我的开始屏幕的 onCreate 中被调用。
第一个网络的配置似乎失败了,因为将配置添加到 WifiManager returns -1 作为 networkId,正如我在断开连接和丢失所有日志记录之前的最后两行日志中看到的那样。这两行是:
04-11 11:10:51.258 1332-1349/rocks.androidthings.hellothings D/connecting: SSID1 passphase
04-11 11:10:51.259 411-740/system_process I/addOrUpdateNetwork: uid = 10026 SSID SSID1 nid=-1
在此之后我得到一个 java.net.socketException:参数无效或无法连接分配请求的地址。
过去几天我一直在为这个问题苦苦挣扎,所以我们将不胜感激。
public String connectToNetwork1() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"" + SSID1 + "\"")) {
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + SSID1 + "\"";
conf.preSharedKey = "\"" + passphrase + "\"";
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
Log.d("connecting", conf.SSID + " " + conf.preSharedKey);
int networkId = wifiManager.addNetwork(conf);
Log.d("after connecting", conf.SSID + " " + conf.preSharedKey);
wifiManager.disconnect();
Thread t = new Thread(() -> {
wifiManager.enableNetwork(networkId, true);
});
t.start();
t.join();
wifiManager.reconnect();
Log.d("re connecting", wifiManager.getConnectionInfo().getSSID());
return wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected to network1");
return "already connected to network1";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "nougabollen";
}
public String connectToNetwork2() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"" + SSID2 + "\"")) {
/*WifiConfiguration conf = new WifiConfiguration(); //
conf.SSID = "\"" + SSID2 + "\""; //
//
conf.status = WifiConfiguration.Status.ENABLED; //
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); // this block is useless since my application can't update this network
// since network 2 is configured elsewhere
Log.d("connecting", conf.SSID); //
//
int networkId = wifiManager.addNetwork(conf);*/ //
int networkId = -2;
List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
for(WifiConfiguration wc : configs){
if(wc.SSID.equals("\"" + SSID2 + "\"")){
networkId = wc.networkId;
}
}
int finalNetworkId = networkId;
wifiManager.disconnect();
Thread t = new Thread(() -> {
wifiManager.enableNetwork(finalNetworkId, true);
});
t.start();
t.join();
wifiManager.reconnect();
Log.d("re connecting", wifiManager.getConnectionInfo().getSSID());
return "tried networkId: " + networkId + " " + wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected to network2");
return "already connected to network2";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "smoutebollen";
}
private class DownloadFilesTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
String text = "";
text += " " + connectToNetwork1();
text += " " + retrieveFile();
text += " " + connectToNetwork2();
Log.d("text", text);
return text;
}
protected void onPostExecute(String text) {
test.setText(text);
}
}
我用来检索文件的代码是(使用apache.commons.net):
public static String getDummyFile(){
FTPClient client = new FTPClient();
Log.d("ftp","client created");
InetAddress ip = null;
try {
ip = InetAddress.getByName("192.168.242.129"); // this is the address of the device creating the first network
}
catch (Exception e){
Log.d("inetaddres",e.toString());
}
try {
Log.d("inet", ip.getHostAddress());
int reply = -1; //response
client.connect(ip);
Log.d("ftp","client connected");
reply = client.getReplyCode();
Log.d("ftp",""+reply);
client.enterLocalPassiveMode();
Log.d("ftp","passive mode");
//check if login is accepted
/*if (!client.login("anonymous", "")) {
Log.d("FTP", "error logging in");
}*/
//check if bad reponse code
/*if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
Log.d("FTP", "connection refused");
}*/
//set file type to binary and enter passive mode, active not supported on android
client.setFileType(FTP.BINARY_FILE_TYPE);
Log.d("ftp", "set type to binary");
client.changeWorkingDirectory("/files");
Log.d("ftp","changed dir");
String[] names = client.listNames();
Log.d("FTP", names[1].toString());
Log.d("FTP", client.printWorkingDirectory() + "/" + names[1].toString());
mapFiles(client,"/files","",0);
return client.printWorkingDirectory() + "/" + names[1].toString();
} catch (Exception e) {
Log.d("ftp",e.toString());
text = e.toString();
}
finally {
try {
client.disconnect();
}
catch (Exception e){
}
}
return text;
}
尝试连接时出现异常,因为我没有连接到网络。
所以我设法让它工作,以下是我的工作代码。主要区别在于将 WPA 设置为协议,并让我连接的线程在启用网络后休眠 3 秒。
public String connectToXs() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"ssid\"")) {
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"ssid\"";
wc.preSharedKey = "\"key\"";
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
int res = wifiManager.addNetwork(wc);
Log.d("WifiPreference", "add Network returned " + res );
final boolean[] b = new boolean[1];
Thread t = new Thread(() -> {
b[0] = wifiManager.enableNetwork(res, true);
wifiManager.setWifiEnabled(true);
try {
Thread.sleep(3000);
}
catch (Exception e){
Log.d("ERROR",e.toString());
}
});
t.start();
t.join();
Log.d("WifiPreference", "enableNetwork returned " + b[0]);
return wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected");
return "already connected";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "nougabollen";
}
public String connectToGuest() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"" + "ssid2" + "\"")) {
//int networkId = wifiManager.addNetwork(conf);
int networkId = -2;
List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
for(WifiConfiguration wc : configs){
if(wc.SSID.equals("\"SSID2\"")){
networkId = wc.networkId;
}
}
int finalNetworkId = networkId;
wifiManager.disconnect();
Thread t = new Thread(() -> {
wifiManager.enableNetwork(finalNetworkId, true);
try {
Thread.sleep(3000);
}
catch (Exception e){
Log.d("ERROR",e.toString());
}
});
t.start();
t.join();
wifiManager.reconnect();
Log.d("re connecting", wifiManager.getConnectionInfo().getSSID());
return "tried networkId: " + networkId + " " + wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected");
return "already connected";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "smoutebollen";
}
我在 Raspberry Pi 3 运行 Android 事物上以编程方式在 2 个网络之间切换时遇到问题(但它应该与 运行 正常 Android).
第一个网络来自作为接入点的设备服务器。它运行一个 FTP 服务器,我需要通过它的网络访问它。它在我知道的 192.168.xxx.xxx 网络中有一个静态 IP 地址,并受 WPA2-PSK 保护。我有我知道正确的 SSID 和密码。该设备位于它自己创建的专用网络中,无法通过外部地址访问。连接到它的唯一方法是连接到它的网络并 FTP'ing 到它的静态地址。
第二个网络是开放网络,我也知道它的SSID。这是由另一个应用程序预先配置的,因此我的应用程序无法更新配置。
下面的代码是我目前的代码。 DownloadFilesTask 在我的开始屏幕的 onCreate 中被调用。
第一个网络的配置似乎失败了,因为将配置添加到 WifiManager returns -1 作为 networkId,正如我在断开连接和丢失所有日志记录之前的最后两行日志中看到的那样。这两行是:
04-11 11:10:51.258 1332-1349/rocks.androidthings.hellothings D/connecting: SSID1 passphase
04-11 11:10:51.259 411-740/system_process I/addOrUpdateNetwork: uid = 10026 SSID SSID1 nid=-1
在此之后我得到一个 java.net.socketException:参数无效或无法连接分配请求的地址。
过去几天我一直在为这个问题苦苦挣扎,所以我们将不胜感激。
public String connectToNetwork1() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"" + SSID1 + "\"")) {
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + SSID1 + "\"";
conf.preSharedKey = "\"" + passphrase + "\"";
conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
Log.d("connecting", conf.SSID + " " + conf.preSharedKey);
int networkId = wifiManager.addNetwork(conf);
Log.d("after connecting", conf.SSID + " " + conf.preSharedKey);
wifiManager.disconnect();
Thread t = new Thread(() -> {
wifiManager.enableNetwork(networkId, true);
});
t.start();
t.join();
wifiManager.reconnect();
Log.d("re connecting", wifiManager.getConnectionInfo().getSSID());
return wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected to network1");
return "already connected to network1";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "nougabollen";
}
public String connectToNetwork2() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"" + SSID2 + "\"")) {
/*WifiConfiguration conf = new WifiConfiguration(); //
conf.SSID = "\"" + SSID2 + "\""; //
//
conf.status = WifiConfiguration.Status.ENABLED; //
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); // this block is useless since my application can't update this network
// since network 2 is configured elsewhere
Log.d("connecting", conf.SSID); //
//
int networkId = wifiManager.addNetwork(conf);*/ //
int networkId = -2;
List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
for(WifiConfiguration wc : configs){
if(wc.SSID.equals("\"" + SSID2 + "\"")){
networkId = wc.networkId;
}
}
int finalNetworkId = networkId;
wifiManager.disconnect();
Thread t = new Thread(() -> {
wifiManager.enableNetwork(finalNetworkId, true);
});
t.start();
t.join();
wifiManager.reconnect();
Log.d("re connecting", wifiManager.getConnectionInfo().getSSID());
return "tried networkId: " + networkId + " " + wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected to network2");
return "already connected to network2";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "smoutebollen";
}
private class DownloadFilesTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
String text = "";
text += " " + connectToNetwork1();
text += " " + retrieveFile();
text += " " + connectToNetwork2();
Log.d("text", text);
return text;
}
protected void onPostExecute(String text) {
test.setText(text);
}
}
我用来检索文件的代码是(使用apache.commons.net):
public static String getDummyFile(){
FTPClient client = new FTPClient();
Log.d("ftp","client created");
InetAddress ip = null;
try {
ip = InetAddress.getByName("192.168.242.129"); // this is the address of the device creating the first network
}
catch (Exception e){
Log.d("inetaddres",e.toString());
}
try {
Log.d("inet", ip.getHostAddress());
int reply = -1; //response
client.connect(ip);
Log.d("ftp","client connected");
reply = client.getReplyCode();
Log.d("ftp",""+reply);
client.enterLocalPassiveMode();
Log.d("ftp","passive mode");
//check if login is accepted
/*if (!client.login("anonymous", "")) {
Log.d("FTP", "error logging in");
}*/
//check if bad reponse code
/*if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect();
Log.d("FTP", "connection refused");
}*/
//set file type to binary and enter passive mode, active not supported on android
client.setFileType(FTP.BINARY_FILE_TYPE);
Log.d("ftp", "set type to binary");
client.changeWorkingDirectory("/files");
Log.d("ftp","changed dir");
String[] names = client.listNames();
Log.d("FTP", names[1].toString());
Log.d("FTP", client.printWorkingDirectory() + "/" + names[1].toString());
mapFiles(client,"/files","",0);
return client.printWorkingDirectory() + "/" + names[1].toString();
} catch (Exception e) {
Log.d("ftp",e.toString());
text = e.toString();
}
finally {
try {
client.disconnect();
}
catch (Exception e){
}
}
return text;
}
尝试连接时出现异常,因为我没有连接到网络。
所以我设法让它工作,以下是我的工作代码。主要区别在于将 WPA 设置为协议,并让我连接的线程在启用网络后休眠 3 秒。
public String connectToXs() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"ssid\"")) {
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"ssid\"";
wc.preSharedKey = "\"key\"";
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
int res = wifiManager.addNetwork(wc);
Log.d("WifiPreference", "add Network returned " + res );
final boolean[] b = new boolean[1];
Thread t = new Thread(() -> {
b[0] = wifiManager.enableNetwork(res, true);
wifiManager.setWifiEnabled(true);
try {
Thread.sleep(3000);
}
catch (Exception e){
Log.d("ERROR",e.toString());
}
});
t.start();
t.join();
Log.d("WifiPreference", "enableNetwork returned " + b[0]);
return wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected");
return "already connected";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "nougabollen";
}
public String connectToGuest() {
try {
WifiManager wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.getConnectionInfo().getSSID().equals("\"" + "ssid2" + "\"")) {
//int networkId = wifiManager.addNetwork(conf);
int networkId = -2;
List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
for(WifiConfiguration wc : configs){
if(wc.SSID.equals("\"SSID2\"")){
networkId = wc.networkId;
}
}
int finalNetworkId = networkId;
wifiManager.disconnect();
Thread t = new Thread(() -> {
wifiManager.enableNetwork(finalNetworkId, true);
try {
Thread.sleep(3000);
}
catch (Exception e){
Log.d("ERROR",e.toString());
}
});
t.start();
t.join();
wifiManager.reconnect();
Log.d("re connecting", wifiManager.getConnectionInfo().getSSID());
return "tried networkId: " + networkId + " " + wifiManager.getConnectionInfo().toString();
} else {
Log.d("WIFI", "already connected");
return "already connected";
}
} catch (Exception ex) {
Log.d("ERROR", ex.toString());
}
return "smoutebollen";
}