Commit e013f269 authored by kirk's avatar kirk

fix screen rotation bug

parent 66545027
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="us.rader.wyfy"
android:versionCode="19"
android:versionName="1.19" >
android:versionCode="20"
android:versionName="1.20" >
<uses-sdk
android:minSdkVersion="10"
......
......@@ -17,7 +17,6 @@ package us.rader.wyfy;
import us.rader.wyfy.model.WifiSettings;
import us.rader.wyfy.model.WifiSettings.ConnectionOutcome;
import us.rader.wyfy.model.WifiSettings.Security;
import us.rader.wyfy.nfc.ForegroundDispatchActivity;
import us.rader.wyfy.nfc.NdefReaderActivity;
import android.app.Activity;
......@@ -198,31 +197,7 @@ public final class MainActivity extends FragmentActivity implements
* {@link Activity#startActivityForResult(Intent, int)} request code when
* launching {@link WriteTagActivity}
*/
public static final int REQUEST_WRITE_TAG = 1;
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#isHidden()} across screen rotations, etc.
*/
private static final String HIDDEN_PARAMETER = "HIDDEN"; //$NON-NLS-1$
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#getPassword()} across screen rotations, etc.
*/
private static final String PASSWORD_PARAMETER = "PASSWORD"; //$NON-NLS-1$
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#getSecurity()} across screen rotations, etc.
*/
private static final String SECURITY_PARAMETER = "SECURITY"; //$NON-NLS-1$
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#getSsid()} across screen rotations, etc.
*/
private static final String SSID_PARAMETER = "SSID"; //$NON-NLS-1$
public static final int REQUEST_WRITE_TAG = 1;
/**
* Cached singleton instance of {@link WifiSettings}
......@@ -306,26 +281,6 @@ public final class MainActivity extends FragmentActivity implements
}
}
/**
* Save the app-specific state of this instance
*
* @param outState
* saved state
*
* @see android.support.v4.app.Fragment#onSaveInstanceState(android.os.Bundle)
*/
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(SSID_PARAMETER, wifiSettings.getSsid());
outState.putString(PASSWORD_PARAMETER, wifiSettings.getPassword());
outState.putBoolean(HIDDEN_PARAMETER, wifiSettings.isHidden());
outState.putSerializable(SECURITY_PARAMETER, wifiSettings.getSecurity());
Log.i(getClass().getName(), "instance state saved"); //$NON-NLS-1$
}
/**
* Handle notification that the {@link WifiSettings} model state has been
* changed by the user
......@@ -399,31 +354,15 @@ public final class MainActivity extends FragmentActivity implements
super.onCreate(savedInstanceState);
wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
setContentView(R.layout.main);
setFragments(savedInstanceState);
if (savedInstanceState == null) {
setFragments(savedInstanceState);
Log.i(getClass().getName(),
"initializing instance state asynchronously"); //$NON-NLS-1$
if (!parseIntentData()) {
new GetActiveConnectionTask().execute();
}
} else {
wifiSettings.setSsid(savedInstanceState.getString(SSID_PARAMETER));
wifiSettings.setPassword(savedInstanceState
.getString(PASSWORD_PARAMETER));
wifiSettings.setHidden(savedInstanceState
.getBoolean(HIDDEN_PARAMETER));
wifiSettings.setSecurity((Security) savedInstanceState
.getSerializable(SECURITY_PARAMETER));
Log.i(getClass().getName(), "instance state restored"); //$NON-NLS-1$
setFragments(savedInstanceState);
}
}
......
......@@ -17,11 +17,10 @@ package us.rader.wyfy;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Timer;
import java.util.TimerTask;
import us.rader.wyfy.model.WifiSettings;
import us.rader.wyfy.provider.FileProvider;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
......@@ -29,6 +28,7 @@ import android.graphics.Bitmap.CompressFormat;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
......@@ -36,6 +36,7 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
/**
......@@ -64,7 +65,7 @@ public final class QrCodeFragment extends Fragment {
* @return {@link Bitmap} for QR code image or <code>null</code>
*
* @see android.os.AsyncTask#doInBackground(Void...)
* @see WifiSettings#getQrCode(int)
* @see WifiSettings#getQrCode(int, int, int)
* @see #onPostExecute(Bitmap)
*/
@Override
......@@ -76,7 +77,8 @@ public final class QrCodeFragment extends Fragment {
if (size > 0) {
return wifiSettings.getQrCode(size);
return wifiSettings.getQrCode(Color.BLACK, Color.WHITE,
size);
}
......@@ -164,35 +166,32 @@ public final class QrCodeFragment extends Fragment {
});
return view;
view.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
/**
* Update the QR code bitmap now that the wifiSettings have, presumably,
* been restored and the view is, hopefully, ready
*
* @see android.support.v4.app.Fragment#onResume()
*/
@Override
public void onResume() {
if (Build.VERSION.SDK_INT < 16) {
super.onResume();
getView().getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
// TODO: figure out a better way to work around state-management bug in
// Android UI classes than using a Timer to delay this initial refresh
TimerTask task = new TimerTask() {
} else {
@Override
public void run() {
getView().getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
updateQrCode();
}
}
updateQrCode();
};
}
});
new Timer().schedule(task, 500);
return view;
}
......@@ -209,7 +208,8 @@ public final class QrCodeFragment extends Fragment {
try {
FragmentActivity activity = getActivity();
Bitmap bitmap = wifiSettings.getQrCode(getQrCodeSize());
Bitmap bitmap = wifiSettings.getQrCode(Color.BLACK, Color.WHITE,
getQrCodeSize());
File file = activity.getFileStreamPath("wyfy_qr.png"); //$NON-NLS-1$
FileOutputStream stream = activity
.openFileOutput(file.getName(), 0);
......@@ -260,21 +260,7 @@ public final class QrCodeFragment extends Fragment {
private int getQrCodeSize() {
View view = getView();
if (view == null) {
return 0;
}
View qrView = view.findViewById(R.id.qr_code_layout);
if (qrView == null) {
return 0;
}
int size = Math.min(qrView.getWidth(), qrView.getHeight());
return size;
......
......@@ -270,6 +270,30 @@ public final class WifiSettingsFragment extends Fragment {
}
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#isHidden()} across screen rotations, etc.
*/
private static final String HIDDEN_PARAMETER = "HIDDEN"; //$NON-NLS-1$
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#getPassword()} across screen rotations, etc.
*/
private static final String PASSWORD_PARAMETER = "PASSWORD"; //$NON-NLS-1$
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#getSecurity()} across screen rotations, etc.
*/
private static final String SECURITY_PARAMETER = "SECURITY"; //$NON-NLS-1$
/**
* {@link Bundle} parameter name used to persist state of
* {@link WifiSettings#getSsid()} across screen rotations, etc.
*/
private static final String SSID_PARAMETER = "SSID"; //$NON-NLS-1$
/**
* Cache the singleton instance of {@link WifiSettings}
*/
......@@ -281,12 +305,6 @@ public final class WifiSettingsFragment extends Fragment {
}
/**
* Turn {@link #notifyListener()} into a no-op while
* {@link #delayNotifications} is not 0
*/
private int delayNotifications;
/**
* {@link CheckBox} for a wifi access point with a SSID that isn't broadcast
*/
......@@ -313,15 +331,6 @@ public final class WifiSettingsFragment extends Fragment {
*/
private EditText ssidText;
/**
* Initialize {@link #delayNotifications}
*/
public WifiSettingsFragment() {
delayNotifications = 0;
}
/**
* Set the {@link #listener}
*
......@@ -338,6 +347,32 @@ public final class WifiSettingsFragment extends Fragment {
}
/**
* Prepare this instance to be displayed
*
* @param savedInstanceState
* saved state or <code>null</code>
*
* @see android.support.v4.app.Fragment#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
wifiSettings.setSsid(savedInstanceState.getString(SSID_PARAMETER));
wifiSettings.setPassword(savedInstanceState
.getString(PASSWORD_PARAMETER));
wifiSettings.setHidden(savedInstanceState
.getBoolean(HIDDEN_PARAMETER));
wifiSettings.setSecurity((Security) savedInstanceState
.getSerializable(SECURITY_PARAMETER));
}
}
/**
* Inflate the {@ink View}
*
......@@ -357,32 +392,21 @@ public final class WifiSettingsFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// don't notify during initialization of UI...
delayNotifications += 1;
try {
View view = inflater.inflate(R.layout.wifi_settings_fragment,
container, false);
ssidText = (EditText) view.findViewById(R.id.ssid_text);
passwordText = (EditText) view.findViewById(R.id.p_text);
securityGroup = (RadioGroup) view.findViewById(R.id.security_group);
hiddenCheckBox = (CheckBox) view.findViewById(R.id.hidden_checkbox);
onSettingsChanged();
ssidText.addTextChangedListener(new SsidTextWatcher());
passwordText.addTextChangedListener(new PasswordTextWatcher());
securityGroup
.setOnCheckedChangeListener(new SecurityCheckedChangeListener());
hiddenCheckBox
.setOnCheckedChangeListener(new HiddenCheckedChangeListener());
return view;
} finally {
// now that things are set up, enable notifications...
delayNotifications -= 1;
View view = inflater.inflate(R.layout.wifi_settings_fragment,
container, false);
ssidText = (EditText) view.findViewById(R.id.ssid_text);
passwordText = (EditText) view.findViewById(R.id.p_text);
securityGroup = (RadioGroup) view.findViewById(R.id.security_group);
hiddenCheckBox = (CheckBox) view.findViewById(R.id.hidden_checkbox);
onSettingsChanged();
ssidText.addTextChangedListener(new SsidTextWatcher());
passwordText.addTextChangedListener(new PasswordTextWatcher());
securityGroup
.setOnCheckedChangeListener(new SecurityCheckedChangeListener());
hiddenCheckBox
.setOnCheckedChangeListener(new HiddenCheckedChangeListener());
return view;
}
}
/**
......@@ -399,45 +423,50 @@ public final class WifiSettingsFragment extends Fragment {
}
/**
* Update the state of the UI widgets to match the current wi fi settings
* model state
* Save the app-specific state of this instance
*
* @param outState
* saved state
*
* @see android.support.v4.app.Fragment#onSaveInstanceState(android.os.Bundle)
*/
public void onSettingsChanged() {
// don't queue up a bunch of notifications while updating multiple
// widgets...
delayNotifications += 1;
try {
@Override
public void onSaveInstanceState(Bundle outState) {
ssidText.setText(wifiSettings.getSsid());
passwordText.setText(wifiSettings.getPassword());
hiddenCheckBox.setChecked(wifiSettings.isHidden());
super.onSaveInstanceState(outState);
outState.putString(SSID_PARAMETER, wifiSettings.getSsid());
outState.putString(PASSWORD_PARAMETER, wifiSettings.getPassword());
outState.putBoolean(HIDDEN_PARAMETER, wifiSettings.isHidden());
outState.putSerializable(SECURITY_PARAMETER, wifiSettings.getSecurity());
switch (wifiSettings.getSecurity()) {
}
case WEP:
/**
* Update the state of the UI widgets to match the current wi fi settings
* model state
*/
public void onSettingsChanged() {
securityGroup.check(R.id.wep_radio);
break;
ssidText.setText(wifiSettings.getSsid());
passwordText.setText(wifiSettings.getPassword());
hiddenCheckBox.setChecked(wifiSettings.isHidden());
case WPA:
switch (wifiSettings.getSecurity()) {
securityGroup.check(R.id.wpa_radio);
break;
case WEP:
default:
securityGroup.check(R.id.wep_radio);
break;
securityGroup.check(R.id.nopass_radio);
break;
case WPA:
}
securityGroup.check(R.id.wpa_radio);
break;
} finally {
default:
// notify at most once for all of the preceding updates...
delayNotifications -= 1;
notifyListener();
securityGroup.check(R.id.nopass_radio);
break;
}
}
......@@ -450,24 +479,12 @@ public final class WifiSettingsFragment extends Fragment {
try {
if (delayNotifications != 0) {
Log.i(getClass().getName(),
"noifyListener(): delayNotifications is " //$NON-NLS-1$
+ delayNotifications + ", exiting"); //$NON-NLS-1$
return;
}
if (listener == null) {
Log.i(getClass().getName(),
"noifyListener(): lisetener is null, exiting"); //$NON-NLS-1$
return;
}
Log.i(getClass().getName(), "noifyListener(): notifying listener"); //$NON-NLS-1$
listener.onWifiSettingsChanged();
} catch (Exception e) {
......
......@@ -25,7 +25,6 @@ import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
......@@ -399,48 +398,28 @@ public final class WifiSettings implements Serializable {
*/
public boolean getActiveConnection(WifiManager manager) {
try {
WifiInfo info = manager.getConnectionInfo();
WifiInfo info = manager.getConnectionInfo();
if (info != null) {
if (info != null) {
int activeId = info.getNetworkId();
int activeId = info.getNetworkId();
if (activeId != -1) {
if (activeId != -1) {
for (WifiConfiguration configuration : manager
.getConfiguredNetworks()) {
for (WifiConfiguration configuration : manager
.getConfiguredNetworks()) {
if (configuration.networkId == activeId) {
if (configuration.networkId == activeId) {
return initialize(configuration);
return initialize(configuration);
}
}
}
}
}
return false;
} finally {
// TODO: putting in a little delay here to allow the UI to settle
// down at
// launch. otherwise, QrCodeFragment.updateQrCode() is invoked when
// it is not yet ready to display its image -- investigate better
// ways to deal with this
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// ignore this exception
}
return false;
}
}
/**
......@@ -455,6 +434,12 @@ public final class WifiSettings implements Serializable {
/**
* Create the QR code {@link Bitmap}
*
* @param foregroundColor
* foreground color
*
* @param backgroundColor
* background color
*
* @param size
* size of the QR code bitmap to create
*
......@@ -463,7 +448,8 @@ public final class WifiSettings implements Serializable {
* @throws WriterException
* if a zxing error occurs
*/
public Bitmap getQrCode(int size) throws WriterException {
public Bitmap getQrCode(int foregroundColor, int backgroundColor, int size)
throws WriterException {
QRCodeWriter writer = new QRCodeWriter();
Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
......@@ -477,8 +463,8 @@ public final class WifiSettings implements Serializable {
for (int x = 0; x < bitMatrix.getWidth(); ++x) {
bitmap.setPixel(x, y, (bitMatrix.get(x, y) ? Color.BLACK
: Color.WHITE));
bitmap.setPixel(x, y, (bitMatrix.get(x, y) ? foregroundColor
: backgroundColor));
}
}
......
......@@ -49,19 +49,10 @@ public abstract class NdefWriterActivity extends NdefReaderActivity {
/**
* Create a AAR {@link NdefRecord} for the given {@link Package} name
*
* <p>
* Even though AAR records will only be used by devices running ice cream
* sandwich or later, this method uses API's available since gingerbread mr1
* to create them. They will be benignly ignored by older devices when
* reading tags that include them.
* </p>
*
* <p>
* TODO: inferred this format by inspecting some actual AAR records created
* using {@link NdefRecord#createApplicationRecord(String)} (that only
* became available in ice cream sandwich). Should investigate if there is,
* somewhere, an official public specification.
* </p>
*
* @param pkg
* the {@link Package} name
......
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