Commit 66545027 authored by kirk's avatar kirk

scan wi fi settings from qr code

parent be022e84
...@@ -7,3 +7,4 @@ ...@@ -7,3 +7,4 @@
**/.project **/.project
**/libs/* **/libs/*
lint.xml lint.xml
ZxingIntegration/*
...@@ -12,4 +12,3 @@ ...@@ -12,4 +12,3 @@
# Project target. # Project target.
target=android-17 target=android-17
android.library.reference.1=../../ZxingIntegration
...@@ -40,12 +40,12 @@ ...@@ -40,12 +40,12 @@
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText <EditText
android:id="@+id/password_text" android:id="@+id/p_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="2" android:layout_weight="2"
android:ems="10" android:ems="10"
android:inputType="textPassword" /> android:inputType="textNoSuggestions" />
</TableRow> </TableRow>
<TableRow <TableRow
......
...@@ -34,5 +34,7 @@ ...@@ -34,5 +34,7 @@
<string name="initialized_from_active_connection">Initialized from active connection to %1$s</string> <string name="initialized_from_active_connection">Initialized from active connection to %1$s</string>
<string name="no_active_connection">No active connection</string> <string name="no_active_connection">No active connection</string>
<string name="scan_qr_label">Scan QR&#8230;</string> <string name="scan_qr_label">Scan QR&#8230;</string>
<string name="error_scanning_qr_code">Error scanning QR code</string>
<string name="unsupported_qr_code">Unsupported QR code %1$s</string>
</resources> </resources>
...@@ -41,6 +41,7 @@ import android.view.Menu; ...@@ -41,6 +41,7 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
/** /**
* Launcher {@link Activity} for <code>WyFy</code> app * Launcher {@link Activity} for <code>WyFy</code> app
...@@ -71,7 +72,7 @@ public final class MainActivity extends FragmentActivity implements ...@@ -71,7 +72,7 @@ public final class MainActivity extends FragmentActivity implements
try { try {
return wifiSettings.connect(manager); return wifiSettings.connect(wifiManager);
} catch (Exception e) { } catch (Exception e) {
...@@ -109,6 +110,7 @@ public final class MainActivity extends FragmentActivity implements ...@@ -109,6 +110,7 @@ public final class MainActivity extends FragmentActivity implements
break; break;
case FAILED: case FAILED:
default:
alert(getString(R.string.failed_to_enable_wifi, ssid)); alert(getString(R.string.failed_to_enable_wifi, ssid));
break; break;
...@@ -117,10 +119,9 @@ public final class MainActivity extends FragmentActivity implements ...@@ -117,10 +119,9 @@ public final class MainActivity extends FragmentActivity implements
if (wifiSettingsFragment != null) { if (wifiSettingsFragment != null) {
wifiSettingsFragment.updateSettings(); wifiSettingsFragment.onSettingsChanged();
} }
} }
} }
...@@ -149,7 +150,7 @@ public final class MainActivity extends FragmentActivity implements ...@@ -149,7 +150,7 @@ public final class MainActivity extends FragmentActivity implements
try { try {
return wifiSettings.getActiveConnection(manager); return wifiSettings.getActiveConnection(wifiManager);
} catch (Exception e) { } catch (Exception e) {
...@@ -186,7 +187,7 @@ public final class MainActivity extends FragmentActivity implements ...@@ -186,7 +187,7 @@ public final class MainActivity extends FragmentActivity implements
if (wifiSettingsFragment != null) { if (wifiSettingsFragment != null) {
wifiSettingsFragment.updateSettings(); wifiSettingsFragment.onSettingsChanged();
} }
} }
...@@ -234,11 +235,6 @@ public final class MainActivity extends FragmentActivity implements ...@@ -234,11 +235,6 @@ public final class MainActivity extends FragmentActivity implements
} }
/**
* Cached singleton instance of {@link WifiManager}
*/
private WifiManager manager;
/** /**
* {@link QrCodeFragment} to notify when the wi fi wifiSettings model state * {@link QrCodeFragment} to notify when the wi fi wifiSettings model state
* changes * changes
...@@ -248,6 +244,11 @@ public final class MainActivity extends FragmentActivity implements ...@@ -248,6 +244,11 @@ public final class MainActivity extends FragmentActivity implements
*/ */
private QrCodeFragment qrCodeFragment; private QrCodeFragment qrCodeFragment;
/**
* Cached singleton instance of {@link WifiManager}
*/
private WifiManager wifiManager;
/** /**
* {@link WifiSettingsFragment} to notify when {@link WifiSettings} state * {@link WifiSettingsFragment} to notify when {@link WifiSettings} state
* changes * changes
...@@ -372,7 +373,7 @@ public final class MainActivity extends FragmentActivity implements ...@@ -372,7 +373,7 @@ public final class MainActivity extends FragmentActivity implements
case IntentIntegrator.REQUEST_CODE: case IntentIntegrator.REQUEST_CODE:
onQrCodeScanned(resultCode, resultData); onQrCodeScanned(requestCode, resultCode, resultData);
break; break;
default: default:
...@@ -396,7 +397,7 @@ public final class MainActivity extends FragmentActivity implements ...@@ -396,7 +397,7 @@ public final class MainActivity extends FragmentActivity implements
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
manager = (WifiManager) getSystemService(WIFI_SERVICE); wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
setContentView(R.layout.main); setContentView(R.layout.main);
if (savedInstanceState == null) { if (savedInstanceState == null) {
...@@ -457,17 +458,67 @@ public final class MainActivity extends FragmentActivity implements ...@@ -457,17 +458,67 @@ public final class MainActivity extends FragmentActivity implements
* Handle notification that a QR code was scanned at the user's request * Handle notification that a QR code was scanned at the user's request
* using zxing's {@link IntentIntegrator} * using zxing's {@link IntentIntegrator}
* *
* @param requestCode
* request code
*
* @param resultCode * @param resultCode
* the result code * result code
* *
* @param resultData * @param resultData
* the {@link Intent} representing the result from the quest * {@link Intent} representing the result from the quest
*/ */
private void onQrCodeScanned(int resultCode, Intent resultData) { private void onQrCodeScanned(int requestCode, int resultCode,
Intent resultData) {
try {
switch (resultCode) {
case RESULT_OK:
IntentResult scanResult = IntentIntegrator
.parseActivityResult(requestCode, resultCode,
resultData);
if (scanResult == null) {
alert(getString(R.string.error_scanning_qr_code));
} else {
// TODO Auto-generated method stub String uri = scanResult.getContents();
throw new RuntimeException("not yet implemented"); //$NON-NLS-1$
if (wifiSettings.parse(uri)) {
wifiSettingsFragment.onSettingsChanged();
} else {
alert(getString(R.string.unsupported_qr_code, uri));
}
}
break;
case RESULT_CANCELED:
alert(getString(R.string.canceled));
break;
default:
alert(getString(R.string.error_scanning_qr_code));
break;
}
} catch (Exception e) {
Log.e(getClass().getName(), "onQrCodeScanned", e); //$NON-NLS-1$
alert(getString(R.string.error_scanning_qr_code));
}
} }
/** /**
......
...@@ -96,6 +96,31 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -96,6 +96,31 @@ public final class WifiSettingsFragment extends Fragment {
} }
/**
* {@link TextWatcher} for edits to password control
*
* @author Kirk
*/
private final class PasswordTextWatcher extends WifiSettingsTextWatcher {
/**
* Notify {@link #listener} that SSID has been edited by the user
*
* @param editable
* ignored due to ill-thought out Android API
*
* @see android.text.TextWatcher#afterTextChanged(android.text.Editable)
*/
@Override
public void afterTextChanged(Editable editable) {
wifiSettings.setPassword(editable.toString());
notifyListener();
}
}
/** /**
* {@Link RadioGroup.OnCheckedChangeListener} used to track selected * {@Link RadioGroup.OnCheckedChangeListener} used to track selected
* security protocol * security protocol
...@@ -148,15 +173,14 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -148,15 +173,14 @@ public final class WifiSettingsFragment extends Fragment {
} }
/** /**
* {@link TextWatcher} for edits to SSID and password strings * {@link TextWatcher} for edits to SSID control
* *
* @author Kirk * @author Kirk
*/ */
private class WifiSettingsTextWatcher implements TextWatcher { private final class SsidTextWatcher extends WifiSettingsTextWatcher {
/** /**
* Notify {@link #listener} that SSID or password has been edited by the * Notify {@link #listener} that SSID has been edited by the user
* user
* *
* @param editable * @param editable
* ignored due to ill-thought out Android API * ignored due to ill-thought out Android API
...@@ -166,12 +190,32 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -166,12 +190,32 @@ public final class WifiSettingsFragment extends Fragment {
@Override @Override
public void afterTextChanged(Editable editable) { public void afterTextChanged(Editable editable) {
wifiSettings.setSsid(ssidText.getText().toString()); wifiSettings.setSsid(editable.toString());
wifiSettings.setPassword(passwordText.getText().toString());
notifyListener(); notifyListener();
} }
}
/**
* {@link TextWatcher} used to track changes to text controls in this
* fragment's layout
*
* @author Kirk
*/
private abstract class WifiSettingsTextWatcher implements TextWatcher {
/**
* Handle new value of {@link Editable} control
*
* @param editable
* new value of {@link Editable} control
*
* @see android.text.TextWatcher#afterTextChanged(android.text.Editable)
*/
@Override
public abstract void afterTextChanged(Editable editable);
/** /**
* Ignored * Ignored
* *
...@@ -191,8 +235,8 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -191,8 +235,8 @@ public final class WifiSettingsFragment extends Fragment {
* int, int, int) * int, int, int)
*/ */
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, public final void beforeTextChanged(CharSequence s, int start,
int after) { int count, int after) {
// nothing to do here // nothing to do here
...@@ -202,21 +246,22 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -202,21 +246,22 @@ public final class WifiSettingsFragment extends Fragment {
* Ignored * Ignored
* *
* @param s * @param s
* ignored * Ignored
* *
* @param start * @param start
* ignored * Ignored
* *
* @param before * @param before
* ignored * Ignored
* *
* @param count * @param count
* ignored * Ignored
* *
* @see TextWatcher#onTextChanged(CharSequence, int, int, int) * @see android.text.TextWatcher#onTextChanged(java.lang.CharSequence,
* int, int, int)
*/ */
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, public final void onTextChanged(CharSequence s, int start, int before,
int count) { int count) {
// nothing to do here // nothing to do here
...@@ -320,13 +365,12 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -320,13 +365,12 @@ public final class WifiSettingsFragment extends Fragment {
View view = inflater.inflate(R.layout.wifi_settings_fragment, View view = inflater.inflate(R.layout.wifi_settings_fragment,
container, false); container, false);
ssidText = (EditText) view.findViewById(R.id.ssid_text); ssidText = (EditText) view.findViewById(R.id.ssid_text);
passwordText = (EditText) view.findViewById(R.id.password_text); passwordText = (EditText) view.findViewById(R.id.p_text);
securityGroup = (RadioGroup) view.findViewById(R.id.security_group); securityGroup = (RadioGroup) view.findViewById(R.id.security_group);
hiddenCheckBox = (CheckBox) view.findViewById(R.id.hidden_checkbox); hiddenCheckBox = (CheckBox) view.findViewById(R.id.hidden_checkbox);
updateSettings(); onSettingsChanged();
WifiSettingsTextWatcher textWatcher = new WifiSettingsTextWatcher(); ssidText.addTextChangedListener(new SsidTextWatcher());
ssidText.addTextChangedListener(textWatcher); passwordText.addTextChangedListener(new PasswordTextWatcher());
passwordText.addTextChangedListener(textWatcher);
securityGroup securityGroup
.setOnCheckedChangeListener(new SecurityCheckedChangeListener()); .setOnCheckedChangeListener(new SecurityCheckedChangeListener());
hiddenCheckBox hiddenCheckBox
...@@ -355,10 +399,10 @@ public final class WifiSettingsFragment extends Fragment { ...@@ -355,10 +399,10 @@ public final class WifiSettingsFragment extends Fragment {
} }
/** /**
* Update the state of the UI widgets to match the current wi fi * Update the state of the UI widgets to match the current wi fi settings
* wifiSettings model state * model state
*/ */
public void updateSettings() { public void onSettingsChanged() {
// don't queue up a bunch of notifications while updating multiple // don't queue up a bunch of notifications while updating multiple
// widgets... // widgets...
......
...@@ -167,7 +167,7 @@ public final class WifiSettings implements Serializable { ...@@ -167,7 +167,7 @@ public final class WifiSettings implements Serializable {
case WEP: case WEP:
config.wepKeys = new String[] { denormalize(password) }; config.wepKeys = new String[] { password };
if (password.length() == 10) { if (password.length() == 10) {
...@@ -185,7 +185,7 @@ public final class WifiSettings implements Serializable { ...@@ -185,7 +185,7 @@ public final class WifiSettings implements Serializable {
case WPA: case WPA:
config.preSharedKey = denormalize(password); config.preSharedKey = password;
config.allowedGroupCiphers config.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.CCMP); .set(WifiConfiguration.GroupCipher.CCMP);
...@@ -202,29 +202,6 @@ public final class WifiSettings implements Serializable { ...@@ -202,29 +202,6 @@ public final class WifiSettings implements Serializable {
} }
/**
* Wrap the given string in double-quoes
*
* TODO: this should probably try to detect whether such wrapping is
* actually necessary for a given string. Need more research
*
* @param string
* the string
*
* @return the wrapped string
*/
private static String denormalize(String string) {
if (string == null) {
return ""; //$NON-NLS-1$
}
return "\"" + string + "\""; //$NON-NLS-1$//$NON-NLS-2$
}
/** /**
* Remove the first and last character from the given string if they are * Remove the first and last character from the given string if they are
* double quotes * double quotes
...@@ -376,11 +353,9 @@ public final class WifiSettings implements Serializable { ...@@ -376,11 +353,9 @@ public final class WifiSettings implements Serializable {
*/ */
public ConnectionOutcome connect(WifiManager manager) { public ConnectionOutcome connect(WifiManager manager) {
String denormalizedSsid = denormalize(ssid);
for (WifiConfiguration configuration : manager.getConfiguredNetworks()) { for (WifiConfiguration configuration : manager.getConfiguredNetworks()) {
if (configuration.SSID.equals(denormalizedSsid)) { if (configuration.SSID.equals(ssid)) {
if (manager.enableNetwork(configuration.networkId, false)) { if (manager.enableNetwork(configuration.networkId, false)) {
...@@ -393,8 +368,7 @@ public final class WifiSettings implements Serializable { ...@@ -393,8 +368,7 @@ public final class WifiSettings implements Serializable {
} }
} }
int networkId = addNetwork(manager, denormalizedSsid, password, int networkId = addNetwork(manager, ssid, password, security);
security);
if (networkId == -1) { if (networkId == -1) {
...@@ -774,16 +748,16 @@ public final class WifiSettings implements Serializable { ...@@ -774,16 +748,16 @@ public final class WifiSettings implements Serializable {
case WEP: case WEP:
buffer.append("P:"); //$NON-NLS-1$ buffer.append("T:WEP;P:"); //$NON-NLS-1$
buffer.append(password); buffer.append(password);
buffer.append(";T:WEP;"); //$NON-NLS-1$ buffer.append(';');
break; break;
case WPA: case WPA:
buffer.append("P:"); //$NON-NLS-1$ buffer.append("T:WPA;P:"); //$NON-NLS-1$
buffer.append(password); buffer.append(password);
buffer.append(";T:WPA;"); //$NON-NLS-1$ buffer.append(';');
break; break;
default: default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment