package com.google.zxing.client.android.wifi;
import java.util.List;
+import java.util.regex.Pattern;
import android.app.Activity;
import android.content.Intent;
/**
* A new activity showing the progress of Wifi connection
- *
- * TODO(viki): Tell the user when the network is not available here
- * TODO(viki): Incorrect password, could not connect, give an error
*
* @author Vikram Aggarwal
*/
-public class WifiActivity extends Activity {
+public final class WifiActivity extends Activity {
private static final String TAG = WifiActivity.class.getSimpleName();
+ private static final int MAX_ERROR_COUNT = 3;
+ private static final int FAILURE_NO_NETWORK_ID = -1;
+ private static final Pattern HEX_DIGITS_64 = Pattern.compile("[0-9A-Fa-f]{64}");
+
private WifiManager wifiManager;
private TextView statusView;
- private ConnectedReceiver connectedReceiver;
+ private WifiReceiver wifiReceiver;
+ private boolean receiverRegistered;
+ private int networkId;
+ private int errorCount;
+ private IntentFilter mWifiStateFilter;
+
+ void gotError() {
+ errorCount++;
+ Log.d(TAG, "Encountered another error. Errorcount = " + errorCount);
+ if (errorCount > MAX_ERROR_COUNT){
+ errorCount = 0;
+ doError(R.string.wifi_connect_failed);
+ }
+ }
public enum NetworkType {
NETWORK_WEP, NETWORK_WPA, NETWORK_NOPASS, NETWORK_INVALID,
private int doError(int resource_string) {
statusView.setText(resource_string);
+ // Give up on the connection
+ wifiManager.disconnect();
+ if (networkId > 0) {
+ wifiManager.removeNetwork(networkId);
+ networkId = -1;
+ }
+ if (receiverRegistered) {
+ unregisterReceiver(wifiReceiver);
+ receiverRegistered = false;
+ }
return -1;
}
// Adding a WEP network
private int changeNetworkWEP(NetworkSetting input) {
WifiConfiguration config = changeNetworkCommon(input);
- if (NetworkUtil.isHexWepKey(input.getPassword())) {
- config.wepKeys[0] = input.getPassword();
+ String pass = input.getPassword();
+ if (NetworkUtil.isHexWepKey(pass)) {
+ config.wepKeys[0] = pass;
} else {
- config.wepKeys[0] = NetworkUtil.convertToQuotedString(input.getPassword());
+ config.wepKeys[0] = NetworkUtil.convertToQuotedString(pass);
}
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
// Adding a WPA or WPA2 network
private int changeNetworkWPA(NetworkSetting input) {
WifiConfiguration config = changeNetworkCommon(input);
- final String pass = input.getPassword();
+ String pass = input.getPassword();
// Hex passwords that are 64 bits long are not to be quoted.
- if (pass.matches("[0-9A-Fa-f]{64}")){
+ if (HEX_DIGITS_64.matcher(pass).matches()){
Log.d(TAG, "A 64 bit hex password entered.");
config.preSharedKey = pass;
} else {
// Adding an open, unsecured network
private int changeNetworkUnEncrypted(NetworkSetting input){
- WifiConfiguration config = changeNetworkCommon(input);
Log.d(TAG, "Empty password prompting a simple account setting");
+ WifiConfiguration config = changeNetworkCommon(input);
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
* @param ssid
*/
private WifiConfiguration findNetworkInExistingConfig(String ssid){
- final List <WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
+ List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals(ssid)) {
return existingConfig;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final Intent intent = getIntent();
+ Intent intent = getIntent();
if (intent == null || (!intent.getAction().equals(Intents.WifiConnect.ACTION))) {
finish();
return;
}
- final String ssid = intent.getStringExtra(Intents.WifiConnect.SSID);
+ String ssid = intent.getStringExtra(Intents.WifiConnect.SSID);
String password = intent.getStringExtra(Intents.WifiConnect.PASSWORD);
- final String networkType = intent.getStringExtra(Intents.WifiConnect.TYPE);
+ String networkType = intent.getStringExtra(Intents.WifiConnect.TYPE);
setContentView(R.layout.network);
statusView = (TextView) findViewById(R.id.networkStatus);
- // TODO(vikrama): Error checking here, to ensure ssid exists.
NetworkType networkT;
if (networkType.equals("WPA")) {
networkT = NetworkType.NETWORK_WPA;
} else if (networkType.equals("nopass")) {
networkT = NetworkType.NETWORK_NOPASS;
} else {
- // Got an incorrect network type. Give an error
doError(R.string.wifi_type_incorrect);
return;
}
// This is not available before onCreate
wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE);
+ // Start WiFi, otherwise nothing will work
+ wifiManager.setWifiEnabled(true);
// So we know when the network changes
- connectedReceiver = new ConnectedReceiver(this, statusView);
- registerReceiver(connectedReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+ wifiReceiver = new WifiReceiver(wifiManager, this, statusView, ssid);
+
+ // The order matters!
+ mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ mWifiStateFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mWifiStateFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+ mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ registerReceiver(wifiReceiver, mWifiStateFilter);
+ receiverRegistered = true;
if (password == null) {
password = "";
changeNetwork(setting);
}
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (receiverRegistered) {
+ unregisterReceiver(wifiReceiver);
+ receiverRegistered = false;
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (wifiReceiver != null && mWifiStateFilter != null && !receiverRegistered) {
+ registerReceiver(wifiReceiver, mWifiStateFilter);
+ receiverRegistered = true;
+ }
+ }
+
@Override
protected void onDestroy() {
- if (connectedReceiver != null) {
- unregisterReceiver(connectedReceiver);
- connectedReceiver = null;
+ if (wifiReceiver != null) {
+ if (receiverRegistered) {
+ unregisterReceiver(wifiReceiver);
+ receiverRegistered = false;
+ }
+ wifiReceiver = null;
}
super.onDestroy();
}
* @param disableOthers true if other networks must be disabled
* @return network ID of the connected network.
*/
- private int updateNetwork(WifiConfiguration config, boolean disableOthers){
- int networkId;
- if (findNetworkInExistingConfig(config.SSID) == null){
+ private int updateNetwork(WifiConfiguration config, boolean disableOthers) {
+ WifiConfiguration found = findNetworkInExistingConfig(config.SSID);
+ wifiManager.disconnect();
+ if (found == null) {
statusView.setText(R.string.wifi_creating_network);
- networkId = wifiManager.addNetwork(config);
} else {
statusView.setText(R.string.wifi_modifying_network);
- networkId = wifiManager.updateNetwork(config);
+ Log.d(TAG, "Removing network " + found.networkId);
+ wifiManager.removeNetwork(found.networkId);
+ wifiManager.saveConfiguration();
}
- if (networkId == -1 || !wifiManager.enableNetwork(networkId, disableOthers)) {
- return -1;
+ networkId = wifiManager.addNetwork(config);
+ Log.d(TAG, "Inserted/Modified network " + networkId);
+ if (networkId < 0) {
+ return FAILURE_NO_NETWORK_ID;
}
- wifiManager.saveConfiguration();
+
+ // Try to disable the current network and start a new one.
+ if (!wifiManager.enableNetwork(networkId, disableOthers)) {
+ networkId = FAILURE_NO_NETWORK_ID;
+ return FAILURE_NO_NETWORK_ID;
+ }
+ errorCount = 0;
+ wifiManager.reassociate();
return networkId;
}
+
}
\ No newline at end of file