aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2013-01-08 16:49:27 +0100
committerSamuel Tardieu <sam@rfc1149.net>2013-01-08 22:29:47 +0100
commit6ff084480d0f8f1a333549068ffe8a7aad08f32c (patch)
treeadb6e35c7dd761100e6a1429b19b89f1e367a153
parent3f2106d525de0ab38fa5c50c7c44cddc84478b37 (diff)
downloadcgeo-6ff084480d0f8f1a333549068ffe8a7aad08f32c.zip
cgeo-6ff084480d0f8f1a333549068ffe8a7aad08f32c.tar.gz
cgeo-6ff084480d0f8f1a333549068ffe8a7aad08f32c.tar.bz2
Use FragmentActivity instead of Activity as base
Also, this requires the use of a Loader to visit a cache, since data cannot be retained accross a configuration change.
-rw-r--r--main/src/cgeo/geocaching/VisitCacheActivity.java455
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractActivity.java4
-rw-r--r--main/src/cgeo/geocaching/loaders/UrlLoader.java35
3 files changed, 229 insertions, 265 deletions
diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java
index b139aac..0fa2ba0 100644
--- a/main/src/cgeo/geocaching/VisitCacheActivity.java
+++ b/main/src/cgeo/geocaching/VisitCacheActivity.java
@@ -7,7 +7,7 @@ import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.LogTypeTrackable;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.gcvote.GCVote;
-import cgeo.geocaching.network.Network;
+import cgeo.geocaching.loaders.UrlLoader;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.twitter.Twitter;
import cgeo.geocaching.ui.DateDialog;
@@ -22,10 +22,11 @@ import org.apache.commons.lang3.StringUtils;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
-import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -44,13 +45,16 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
-public class VisitCacheActivity extends AbstractLoggingActivity implements DateDialog.DateDialogParent {
+public class VisitCacheActivity extends AbstractLoggingActivity implements DateDialog.DateDialogParent, LoaderManager.LoaderCallbacks<String> {
static final String EXTRAS_FOUND = "found";
static final String EXTRAS_TEXT = "text";
static final String EXTRAS_GEOCODE = "geocode";
static final String EXTRAS_ID = "id";
private static final int SUBMENU_VOTE = 3;
+ private static final String SAVED_STATE_RATING = "cgeo.geocaching.saved_state_rating";
+ private static final String SAVED_STATE_TYPE = "cgeo.geocaching.saved_state_type";
+ private static final String SAVED_STATE_DATE = "cgeo.geocaching.saved_state_date";
private LayoutInflater inflater = null;
private cgCache cache = null;
@@ -61,116 +65,125 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
private boolean alreadyFound = false;
private List<LogType> possibleLogTypes = new ArrayList<LogType>();
private String[] viewstates = null;
- private boolean gettingViewstate = true;
private List<TrackableLog> trackables = null;
- private Calendar date = Calendar.getInstance();
- private LogType typeSelected = LogType.UNKNOWN;
- private int attempts = 0;
private Button postButton = null;
private Button clearButton = null;
private CheckBox tweetCheck = null;
private LinearLayout tweetBox = null;
- private double rating = 0.0;
private boolean tbChanged = false;
- // handlers
- private final Handler loadDataHandler = new Handler() {
+ // Data to be saved while reconfiguring
+ private double rating;
+ private LogType typeSelected;
+ private Calendar date;
- @Override
- public void handleMessage(Message msg) {
- if (!possibleLogTypes.contains(typeSelected)) {
- typeSelected = possibleLogTypes.get(0);
- setType(typeSelected);
+ @Override
+ public Loader<String> onCreateLoader(final int id, final Bundle args) {
+ if (!Settings.isLogin()) { // allow offline logging
+ showToast(res.getString(R.string.err_login));
+ return null;
+ }
+ return new UrlLoader(getBaseContext(), "http://www.geocaching.com/seek/log.aspx", new Parameters("ID", cacheid));
+ }
- showToast(res.getString(R.string.info_log_type_changed));
- }
+ @Override
+ public void onLoaderReset(final Loader<String> loader) {
+ // Nothing to do
+ }
- if (Login.isEmpty(viewstates)) {
- if (attempts < 2) {
- new LoadDataThread().start();
- } else {
- showToast(res.getString(R.string.err_log_load_data));
- showProgress(false);
- }
- return;
- }
+ @Override
+ public void onLoadFinished(final Loader<String> loader, final String page) {
+ if (page == null) {
+ showToast(res.getString(R.string.err_log_load_data));
+ showProgress(false);
+ return;
+ }
- gettingViewstate = false; // we're done, user can post log
+ viewstates = Login.getViewstates(page);
+ trackables = GCParser.parseTrackableLog(page);
+ possibleLogTypes = GCParser.parseTypes(page);
+ possibleLogTypes.remove(LogType.UPDATE_COORDINATES);
- enablePostButton(true);
+ if (!possibleLogTypes.contains(typeSelected)) {
+ typeSelected = possibleLogTypes.get(0);
+ setType(typeSelected);
- // add trackables
- if (CollectionUtils.isNotEmpty(trackables)) {
- if (inflater == null) {
- inflater = getLayoutInflater();
- }
+ showToast(res.getString(R.string.info_log_type_changed));
+ }
- final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory);
- inventoryView.removeAllViews();
-
- for (TrackableLog tb : trackables) {
- LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.visit_trackable, null);
-
- ((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode);
- ((TextView) inventoryItem.findViewById(R.id.name)).setText(tb.name);
- ((TextView) inventoryItem.findViewById(R.id.action))
- .setText(res.getString(Settings.isTrackableAutoVisit()
- ? LogTypeTrackable.VISITED.resourceId
- : LogTypeTrackable.DO_NOTHING.resourceId)
- + " ▼");
-
- inventoryItem.setId(tb.id);
- final String tbCode = tb.trackCode;
- inventoryItem.setClickable(true);
- registerForContextMenu(inventoryItem);
- inventoryItem.findViewById(R.id.info).setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View view) {
- final Intent trackablesIntent = new Intent(VisitCacheActivity.this, TrackableActivity.class);
- trackablesIntent.putExtra(EXTRAS_GEOCODE, tbCode);
- startActivity(trackablesIntent);
- }
- });
- inventoryItem.findViewById(R.id.action).setOnClickListener(new View.OnClickListener() {
+ enablePostButton(true);
- @Override
- public void onClick(View view) {
- openContextMenu(view);
- }
- });
+ // add trackables
+ if (CollectionUtils.isNotEmpty(trackables)) {
+ if (inflater == null) {
+ inflater = getLayoutInflater();
+ }
- inventoryView.addView(inventoryItem);
+ final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory);
+ inventoryView.removeAllViews();
+
+ for (TrackableLog tb : trackables) {
+ LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.visit_trackable, null);
+
+ ((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode);
+ ((TextView) inventoryItem.findViewById(R.id.name)).setText(tb.name);
+ ((TextView) inventoryItem.findViewById(R.id.action))
+ .setText(res.getString(Settings.isTrackableAutoVisit()
+ ? LogTypeTrackable.VISITED.resourceId
+ : LogTypeTrackable.DO_NOTHING.resourceId)
+ + " ▼");
+
+ inventoryItem.setId(tb.id);
+ final String tbCode = tb.trackCode;
+ inventoryItem.setClickable(true);
+ registerForContextMenu(inventoryItem);
+ inventoryItem.findViewById(R.id.info).setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ final Intent trackablesIntent = new Intent(VisitCacheActivity.this, TrackableActivity.class);
+ trackablesIntent.putExtra(EXTRAS_GEOCODE, tbCode);
+ startActivity(trackablesIntent);
+ }
+ });
+ inventoryItem.findViewById(R.id.action).setOnClickListener(new View.OnClickListener() {
- if (Settings.isTrackableAutoVisit()) {
- tb.action = LogTypeTrackable.VISITED;
- tbChanged = true;
+ @Override
+ public void onClick(View view) {
+ openContextMenu(view);
}
- }
+ });
- if (inventoryView.getChildCount() > 0) {
- findViewById(R.id.inventory_box).setVisibility(View.VISIBLE);
+ inventoryView.addView(inventoryItem);
+
+ if (Settings.isTrackableAutoVisit()) {
+ tb.action = LogTypeTrackable.VISITED;
+ tbChanged = true;
}
- if (inventoryView.getChildCount() > 1) {
- final LinearLayout inventoryChangeAllView = (LinearLayout) findViewById(R.id.inventory_changeall);
+ }
- final Button changeButton = (Button) inventoryChangeAllView.findViewById(R.id.changebutton);
- registerForContextMenu(changeButton);
- changeButton.setOnClickListener(new View.OnClickListener() {
+ if (inventoryView.getChildCount() > 0) {
+ findViewById(R.id.inventory_box).setVisibility(View.VISIBLE);
+ }
+ if (inventoryView.getChildCount() > 1) {
+ final LinearLayout inventoryChangeAllView = (LinearLayout) findViewById(R.id.inventory_changeall);
- @Override
- public void onClick(View view) {
- openContextMenu(view);
- }
- });
+ final Button changeButton = (Button) inventoryChangeAllView.findViewById(R.id.changebutton);
+ registerForContextMenu(changeButton);
+ changeButton.setOnClickListener(new View.OnClickListener() {
- inventoryChangeAllView.setVisibility(View.VISIBLE);
- }
- }
+ @Override
+ public void onClick(View view) {
+ openContextMenu(view);
+ }
+ });
- showProgress(false);
+ inventoryChangeAllView.setVisibility(View.VISIBLE);
+ }
}
- };
+
+ showProgress(false);
+ }
private void enablePostButton(boolean enabled) {
postButton.setEnabled(enabled);
@@ -234,14 +247,14 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme();
setContentView(R.layout.visit);
setTitle(res.getString(R.string.log_new_log));
- // get parameters
+ // Get parameters from intent and basic cache information from database
final Bundle extras = getIntent().getExtras();
if (extras != null) {
cacheid = extras.getString(EXTRAS_ID);
@@ -264,13 +277,79 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
setTitle(res.getString(R.string.log_new_log) + ": " + cache.getGeocode());
}
- init();
- }
+ // Get ids for later use
+ postButton = (Button) findViewById(R.id.post);
+ tweetBox = (LinearLayout) findViewById(R.id.tweet_box);
+ tweetCheck = (CheckBox) findViewById(R.id.tweet);
+ clearButton = (Button) findViewById(R.id.clear);
- @Override
- public void onResume() {
- super.onResume();
+ // Restore previous state or initialize with default values
+ date = Calendar.getInstance();
+ if (savedInstanceState != null) {
+ rating = savedInstanceState.getDouble(SAVED_STATE_RATING);
+ typeSelected = LogType.getById(savedInstanceState.getInt(SAVED_STATE_TYPE));
+ date.setTimeInMillis(savedInstanceState.getLong(SAVED_STATE_DATE));
+ } else {
+ rating = 0.0;
+ if (alreadyFound) {
+ typeSelected = LogType.NOTE;
+ } else {
+ typeSelected = LogType.FOUND_IT;
+ }
+
+ // If log had been previously saved, load it now, otherwise initialize signature as needed
+ final LogEntry log = cgData.loadLogOffline(geocode);
+ if (log != null) {
+ typeSelected = log.type;
+ date.setTime(new Date(log.date));
+ text = log.log;
+ } else if (StringUtils.isNotBlank(Settings.getSignature())
+ && Settings.isAutoInsertSignature()
+ && StringUtils.isBlank(((EditText) findViewById(R.id.log)).getText())) {
+ insertIntoLog(LogTemplateProvider.applyTemplates(Settings.getSignature(), new LogContext(cache)), false);
+ }
+ }
+ updatePostButtonText();
+ final Button saveButton = (Button) findViewById(R.id.save);
+
+ possibleLogTypes = cache.getPossibleLogTypes();
+
+ enablePostButton(false);
+
+ final Button typeButton = (Button) findViewById(R.id.type);
+ registerForContextMenu(typeButton);
+ typeButton.setText(typeSelected.getL10n());
+ typeButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View view) {
+ openContextMenu(view);
+ }
+ });
+
+ final Button dateButton = (Button) findViewById(R.id.date);
+ setDate(date);
+ dateButton.setOnClickListener(new DateListener());
+
+ final EditText logView = (EditText) findViewById(R.id.log);
+ if (StringUtils.isBlank(logView.getText()) && StringUtils.isNotBlank(text)) {
+ logView.setText(text);
+ }
+
+ tweetCheck.setChecked(true);
+
+ saveButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ saveLog(true);
+ }
+ });
+
+ clearButton.setOnClickListener(new ClearListener());
+
+ getSupportLoaderManager().initLoader(0, null, this);
}
@Override
@@ -280,13 +359,6 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
@Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
-
- init();
- }
-
- @Override
public boolean onCreateOptionsMenu(final Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -346,7 +418,6 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
if (viewId == R.id.type) {
for (final LogType typeOne : possibleLogTypes) {
menu.add(viewId, typeOne.id, 0, typeOne.getL10n());
- Log.w("Adding " + typeOne + " " + typeOne.getL10n());
}
} else if (viewId == R.id.changebutton) {
final int textId = findViewById(viewId).getId();
@@ -440,79 +511,12 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
return false;
}
- public void init() {
- postButton = (Button) findViewById(R.id.post);
- tweetBox = (LinearLayout) findViewById(R.id.tweet_box);
- tweetCheck = (CheckBox) findViewById(R.id.tweet);
- clearButton = (Button) findViewById(R.id.clear);
- final Button saveButton = (Button) findViewById(R.id.save);
-
- possibleLogTypes = cache.getPossibleLogTypes();
-
- final LogEntry log = cgData.loadLogOffline(geocode);
- if (log != null) {
- typeSelected = log.type;
- date.setTime(new Date(log.date));
- text = log.log;
- updatePostButtonText();
- } else if (StringUtils.isNotBlank(Settings.getSignature())
- && Settings.isAutoInsertSignature()
- && StringUtils.isBlank(((EditText) findViewById(R.id.log)).getText())) {
- insertIntoLog(LogTemplateProvider.applyTemplates(Settings.getSignature(), new LogContext(cache)), false);
- }
-
- if (!possibleLogTypes.contains(typeSelected)) {
- if (alreadyFound) {
- typeSelected = LogType.NOTE;
- } else {
- typeSelected = possibleLogTypes.get(0);
- }
- setType(typeSelected);
- }
-
- final Button typeButton = (Button) findViewById(R.id.type);
- registerForContextMenu(typeButton);
- typeButton.setText(typeSelected.getL10n());
- typeButton.setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View view) {
- openContextMenu(view);
- }
- });
-
- final Button dateButton = (Button) findViewById(R.id.date);
- setDate(date);
- dateButton.setOnClickListener(new DateListener());
-
- final EditText logView = (EditText) findViewById(R.id.log);
- if (StringUtils.isBlank(logView.getText()) && StringUtils.isNotBlank(text)) {
- logView.setText(text);
- }
-
- tweetCheck.setChecked(true);
-
- final ActivityState lastState = (ActivityState) getLastNonConfigurationInstance();
- if (lastState != null) {
- lastState.restore(this);
- }
-
- if (Login.isEmpty(viewstates)) {
- enablePostButton(false);
- new LoadDataThread().start();
- } else {
- enablePostButton(true);
- }
-
- saveButton.setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- saveLog(true);
- }
- });
-
- clearButton.setOnClickListener(new ClearListener());
+ @Override
+ protected void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putDouble(SAVED_STATE_RATING, rating);
+ outState.putInt(SAVED_STATE_TYPE, typeSelected.id);
+ outState.putLong(SAVED_STATE_DATE, date.getTimeInMillis());
}
@Override
@@ -554,19 +558,14 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
private class PostListener implements View.OnClickListener {
-
@Override
public void onClick(View arg0) {
- if (!gettingViewstate) {
- waitDialog = ProgressDialog.show(VisitCacheActivity.this, null, res.getString(R.string.log_saving), true);
- waitDialog.setCancelable(true);
+ waitDialog = ProgressDialog.show(VisitCacheActivity.this, null, res.getString(R.string.log_saving), true);
+ waitDialog.setCancelable(true);
- final String log = ((EditText) findViewById(R.id.log)).getText().toString();
- final Thread thread = new PostLogThread(postLogHandler, log);
- thread.start();
- } else {
- showToast(res.getString(R.string.err_log_load_data_still));
- }
+ final String log = ((EditText) findViewById(R.id.log)).getText().toString();
+ final Thread thread = new PostLogThread(postLogHandler, log);
+ thread.start();
}
}
@@ -600,59 +599,6 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
}
}
- private class LoadDataThread extends Thread {
-
- public LoadDataThread() {
- super("Load data for logging");
- if (cacheid == null) {
- showToast(res.getString(R.string.err_detail_cache_forgot_visit));
-
- finish();
- return;
- }
- if (!Settings.isLogin()) { // allow offline logging
- showToast(res.getString(R.string.err_login));
- }
- }
-
- @Override
- public void run() {
- if (!Settings.isLogin()) {
- // enable only offline logging, don't get the current state of the cache
- return;
- }
- final Parameters params = new Parameters();
-
- gettingViewstate = true;
- attempts++;
-
- try {
- if (StringUtils.isNotBlank(cacheid)) {
- params.put("ID", cacheid);
- } else {
- loadDataHandler.sendEmptyMessage(0);
- return;
- }
-
- final String page = Network.getResponseData(Network.getRequest("http://www.geocaching.com/seek/log.aspx", params));
-
- viewstates = Login.getViewstates(page);
- trackables = GCParser.parseTrackableLog(page);
-
- final List<LogType> typesPre = GCParser.parseTypes(page);
- if (CollectionUtils.isNotEmpty(typesPre)) {
- possibleLogTypes.clear();
- possibleLogTypes.addAll(typesPre);
- possibleLogTypes.remove(LogType.UPDATE_COORDINATES);
- }
- } catch (Exception e) {
- Log.e("cgeovisit.loadData.run: " + e.toString());
- }
-
- loadDataHandler.sendEmptyMessage(0);
- }
- }
-
private class PostLogThread extends Thread {
private final Handler handler;
@@ -727,36 +673,19 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD
return ((EditText) findViewById(R.id.log)).getText().toString();
}
- private static class ActivityState {
+ public static class ActivityState {
private final String[] viewstates;
private final List<TrackableLog> trackables;
- private final int attempts;
private final List<LogType> possibleLogTypes;
- private final LogType typeSelected;
- private final double rating;
-
- public ActivityState(VisitCacheActivity activity) {
- this.viewstates = activity.viewstates;
- this.trackables = activity.trackables;
- this.attempts = activity.attempts;
- this.possibleLogTypes = activity.possibleLogTypes;
- this.typeSelected = activity.typeSelected;
- this.rating = activity.rating;
- }
- public void restore(final VisitCacheActivity activity) {
- activity.viewstates = this.viewstates;
- activity.trackables = this.trackables;
- activity.attempts = this.attempts;
- activity.possibleLogTypes = this.possibleLogTypes;
- activity.typeSelected = this.typeSelected;
- activity.rating = this.rating;
+ public ActivityState(final String[] viewstates,
+ final List<TrackableLog> trackables,
+ final List<LogType> possibleLogTypes) {
+ this.viewstates = viewstates;
+ this.trackables = trackables;
+ this.possibleLogTypes = possibleLogTypes;
}
- }
- @Override
- public Object onRetainNonConfigurationInstance() {
- return new ActivityState(this);
}
@Override
diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java
index a648486..1c5b980 100644
--- a/main/src/cgeo/geocaching/activity/AbstractActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java
@@ -5,14 +5,14 @@ import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.network.Cookies;
-import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.EditText;
-public abstract class AbstractActivity extends Activity implements IAbstractActivity {
+public abstract class AbstractActivity extends FragmentActivity implements IAbstractActivity {
private String helpTopic;
diff --git a/main/src/cgeo/geocaching/loaders/UrlLoader.java b/main/src/cgeo/geocaching/loaders/UrlLoader.java
new file mode 100644
index 0000000..abafd5f
--- /dev/null
+++ b/main/src/cgeo/geocaching/loaders/UrlLoader.java
@@ -0,0 +1,35 @@
+package cgeo.geocaching.loaders;
+
+import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.Log;
+
+import android.content.Context;
+import android.support.v4.content.AsyncTaskLoader;
+
+public class UrlLoader extends AsyncTaskLoader<String> {
+
+ final private String url;
+ final private Parameters params;
+
+ public UrlLoader(final Context context, final String url, final Parameters params) {
+ super(context);
+ this.url = url;
+ this.params = params;
+ }
+
+ @Override
+ protected void onStartLoading() {
+ forceLoad();
+ }
+
+ @Override
+ public String loadInBackground() {
+ try {
+ return Network.getResponseData(Network.getRequest(url, params));
+ } catch (final Exception e) {
+ Log.w("cgeovisit.UrlLoader.loadInBackground", e);
+ return null;
+ }
+ }
+}