X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=android%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid%2Fwifi%2FWifiActivity.java;h=f39b7321944585b54cb003a462401c71f6375afe;hb=01bfbf2e7e85ce75a659913b2f90b155078d4d91;hp=ae8dc6426afdc37ae2cbbcec958eb524b94e9320;hpb=4cbbf3bf20e39925ade3611213d757f5b3ff65f5;p=zxing.git diff --git a/android/src/com/google/zxing/client/android/wifi/WifiActivity.java b/android/src/com/google/zxing/client/android/wifi/WifiActivity.java index ae8dc642..f39b7321 100644 --- a/android/src/com/google/zxing/client/android/wifi/WifiActivity.java +++ b/android/src/com/google/zxing/client/android/wifi/WifiActivity.java @@ -19,89 +19,94 @@ package com.google.zxing.client.android.wifi; import java.util.List; import android.app.Activity; -import android.content.BroadcastReceiver; -import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.util.Log; -import android.widget.ImageView; import android.widget.TextView; import com.google.zxing.client.android.Intents; import com.google.zxing.client.android.R; -import com.google.zxing.client.android.wifi.Killer; -import com.google.zxing.client.android.wifi.NetworkUtil; -import com.google.zxing.client.android.wifi.NetworkSetting; /** * A new activity showing the progress of Wifi connection + * * @author Vikram Aggarwal - * */ public class WifiActivity extends Activity { - public static enum NetworkType { - NETWORK_WEP, NETWORK_WPA, - } - /** - * Get a broadcast when the network is connected, and kill the activity. - */ - class ConnectedReceiver extends BroadcastReceiver { - Activity parent = null; - public ConnectedReceiver(WifiActivity wifiActivity) { - parent = wifiActivity; - } + private static final String TAG = WifiActivity.class.getSimpleName(); + private WifiManager wifiManager; + private TextView statusView; + private WifiReceiver wifiReceiver; + private boolean receiverRegistered; + private int networkId; + private static int errorCount; + private IntentFilter mWifiStateFilter; - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)){ - ConnectivityManager con = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo[] s = con.getAllNetworkInfo(); - for (NetworkInfo i : s){ - if (i.getTypeName().contentEquals("WIFI")){ - NetworkInfo.State state = i.getState(); - if (state == NetworkInfo.State.CONNECTED){ - statusT.setText("Connected!"); - Killer delay_kill = new Killer(parent); - delay_kill.run(); - } - } - } - } + static { + errorCount = 0; + } + + public void gotError(){ + final int maxErrorCount = 3; + errorCount++; + Log.d(TAG, "Encountered another error. Errorcount = " + errorCount); + if (errorCount > maxErrorCount){ + errorCount = 0; + doError(R.string.wifi_connect_failed); } } - private static final String tag = "NetworkActivity"; - WifiManager mWifiManager = null; - TextView statusT = null; - ImageView statusI = null; - ConnectedReceiver rec = null; - boolean debug = true; + public enum NetworkType { + NETWORK_WEP, NETWORK_WPA, NETWORK_NOPASS, NETWORK_INVALID, + } private int changeNetwork(NetworkSetting setting) { + // If the SSID is empty, throw an error and return + if (setting.getSsid() == null || setting.getSsid().length() == 0) { + return doError(R.string.wifi_ssid_missing); + } + // If the network type is invalid + if (setting.getNetworkType() == NetworkType.NETWORK_INVALID){ + return doError(R.string.wifi_type_incorrect); + } + // If the password is empty, this is an unencrypted network - if (setting.getPassword() == null || setting.getPassword() == "") { + if (setting.getPassword() == null || setting.getPassword().length() == 0 || + setting.getNetworkType() == null || + setting.getNetworkType() == NetworkType.NETWORK_NOPASS) { return changeNetworkUnEncrypted(setting); } if (setting.getNetworkType() == NetworkType.NETWORK_WPA) { - return changeNetworkWPA(setting); + return changeNetworkWPA(setting); } else { return changeNetworkWEP(setting); } } - private WifiConfiguration changeNetworkCommon(NetworkSetting input){ - statusT.setText("Creating settings..."); - if (debug) { - Log.d(tag, "adding new configuration: \nSSID: " + input.getSsid() + "\nPassword: \"" - + input.getPassword() + "\"\nType: " + input.getNetworkType()); + 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; } - WifiConfiguration config = new WifiConfiguration(); + return -1; + } + + private WifiConfiguration changeNetworkCommon(NetworkSetting input){ + statusView.setText(R.string.wifi_creating_network); + Log.d(TAG, "Adding new configuration: \nSSID: " + input.getSsid() + "\nType: " + input.getNetworkType()); + final WifiConfiguration config = new WifiConfiguration(); config.allowedAuthAlgorithms.clear(); config.allowedGroupCiphers.clear(); @@ -110,24 +115,24 @@ public class WifiActivity extends Activity { config.allowedProtocols.clear(); // Android API insists that an ascii SSID must be quoted to be correctly handled. - config.SSID = NetworkUtil.convertToQuotedString(input.getSsid()); + config.SSID = NetworkUtil.convertToQuotedString(input.getSsid()); config.hiddenSSID = true; return config; } - private int requestNetworkChange(WifiConfiguration config){ - boolean disableOthers = false; - statusT.setText("Changing Network..."); - return updateNetwork(config, disableOthers); + private int requestNetworkChange(WifiConfiguration config){ + statusView.setText(R.string.wifi_changing_network); + return updateNetwork(config, false); } // Adding a WEP network private int changeNetworkWEP(NetworkSetting input) { - WifiConfiguration config = changeNetworkCommon(input); - if (NetworkUtil.isHexWepKey(input.getPassword())) { - config.wepKeys[0] = input.getPassword(); + final WifiConfiguration config = changeNetworkCommon(input); + final 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); @@ -141,23 +146,31 @@ public class WifiActivity extends Activity { // Adding a WPA or WPA2 network private int changeNetworkWPA(NetworkSetting input) { - WifiConfiguration config = changeNetworkCommon(input); - config.preSharedKey = NetworkUtil.convertToQuotedString(input.getPassword()); + final WifiConfiguration config = changeNetworkCommon(input); + final String pass = input.getPassword(); + // Hex passwords that are 64 bits long are not to be quoted. + if (pass.matches("[0-9A-Fa-f]{64}")){ + Log.d(TAG, "A 64 bit hex password entered."); + config.preSharedKey = pass; + } else { + Log.d(TAG, "A normal password entered: I am quoting it."); + config.preSharedKey = NetworkUtil.convertToQuotedString(pass); + } config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); // For WPA config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA2 + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); + config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); return requestNetworkChange(config); } // Adding an open, unsecured network private int changeNetworkUnEncrypted(NetworkSetting input){ + Log.d(TAG, "Empty password prompting a simple account setting"); WifiConfiguration config = changeNetworkCommon(input); - if (debug){ - Log.d(tag, "Empty password prompting a simple account setting"); - } config.wepKeys[0] = ""; config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); config.wepTxKeyIndex = 0; @@ -169,10 +182,10 @@ public class WifiActivity extends Activity { * @param ssid */ private WifiConfiguration findNetworkInExistingConfig(String ssid){ - List existingConfigs = mWifiManager.getConfiguredNetworks(); - for (int i = 0; i < existingConfigs.size(); i++){ - if (existingConfigs.get(i).SSID.compareTo(ssid) == 0){ - return existingConfigs.get(i); + final List existingConfigs = wifiManager.getConfiguredNetworks(); + for (final WifiConfiguration existingConfig : existingConfigs) { + if (existingConfig.SSID.equals(ssid)) { + return existingConfig; } } return null; @@ -182,79 +195,110 @@ public class WifiActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Intent intent = getIntent(); + final Intent intent = getIntent(); if (intent == null || (!intent.getAction().equals(Intents.WifiConnect.ACTION))) { finish(); return; } - String ssid = intent.getStringExtra(Intents.WifiConnect.SSID); + final String ssid = intent.getStringExtra(Intents.WifiConnect.SSID); String password = intent.getStringExtra(Intents.WifiConnect.PASSWORD); - String networkType = intent.getStringExtra(Intents.WifiConnect.TYPE); + final 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 = null; - if (networkType.contains("WPA")) { + NetworkType networkT; + if (networkType.equals("WPA")) { networkT = NetworkType.NETWORK_WPA; - } - else if (networkType.contains("WEP")) { + } else if (networkType.equals("WEP")) { networkT = NetworkType.NETWORK_WEP; - } - else { - // Got an incorrect network type - finish(); + } else if (networkType.equals("nopass")) { + networkT = NetworkType.NETWORK_NOPASS; + } else { + doError(R.string.wifi_type_incorrect); return; } - setContentView(R.layout.network); - statusT = (TextView) findViewById(R.id.networkStatus); // This is not available before onCreate - mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); + wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE); + // Start WiFi, otherwise nothing will work + wifiManager.setWifiEnabled(true); // So we know when the network changes - rec = new ConnectedReceiver(this); - registerReceiver(rec, 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) + if (password == null) { password = ""; - if (debug) { - Log.d(tag, "adding new configuration: \nSSID: " + ssid + "\nPassword: \"" + password + "\"\nType: " + networkT); } + Log.d(TAG, "Adding new configuration: \nSSID: " + ssid + "Type: " + networkT); NetworkSetting setting = new NetworkSetting(ssid, password, networkT); changeNetwork(setting); } + public void pause() { + if (receiverRegistered) { + unregisterReceiver(wifiReceiver); + receiverRegistered = false; + } + } + + public void resume() { + if (wifiReceiver != null && mWifiStateFilter != null && !receiverRegistered) { + registerReceiver(wifiReceiver, mWifiStateFilter); + receiverRegistered = true; + } + } + @Override protected void onDestroy() { + if (wifiReceiver != null) { + if (receiverRegistered) { + unregisterReceiver(wifiReceiver); + receiverRegistered = false; + } + wifiReceiver = null; + } super.onDestroy(); - if (rec != null) - unregisterReceiver(rec); - rec = null; } /** * Update the network: either create a new network or modify an existing network - * @param config: the new network configuration - * @param disableOthers: true if other networks must be disabled + * @param config the new network configuration + * @param disableOthers true if other networks must be disabled * @return network ID of the connected network. */ private int updateNetwork(WifiConfiguration config, boolean disableOthers){ - WifiConfiguration existing = findNetworkInExistingConfig(config.SSID); - int networkId; - if (existing == null){ - statusT.setText("Creating network..."); - networkId = mWifiManager.addNetwork(config); + final int FAILURE = -1; + WifiConfiguration found = findNetworkInExistingConfig(config.SSID); + wifiManager.disconnect(); + if (found == null){ + statusView.setText(R.string.wifi_creating_network); } else { - statusT.setText("Modifying network..."); - networkId = mWifiManager.updateNetwork(config); - } - if (networkId == -1){ - return networkId; - } - if (!mWifiManager.enableNetwork(networkId, disableOthers)) { - return -1; + statusView.setText(R.string.wifi_modifying_network); + Log.d(TAG, "Removing network " + found.networkId); + wifiManager.removeNetwork(found.networkId); + wifiManager.saveConfiguration(); + } + networkId = wifiManager.addNetwork(config); + Log.d(TAG, "Inserted/Modified network " + networkId); + if (networkId < 0) + return FAILURE; + + // Try to disable the current network and start a new one. + if (!wifiManager.enableNetwork(networkId, disableOthers)) { + networkId = -1; + return FAILURE; } - mWifiManager.saveConfiguration(); + errorCount = 0; + wifiManager.reassociate(); return networkId; } } \ No newline at end of file