aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/utils
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/utils')
-rw-r--r--main/src/cgeo/geocaching/utils/AsyncTaskWithProgress.java139
-rw-r--r--main/src/cgeo/geocaching/utils/GeoDirHandler.java22
-rw-r--r--main/src/cgeo/geocaching/utils/ImageHelper.java38
-rw-r--r--main/src/cgeo/geocaching/utils/Log.java7
4 files changed, 197 insertions, 9 deletions
diff --git a/main/src/cgeo/geocaching/utils/AsyncTaskWithProgress.java b/main/src/cgeo/geocaching/utils/AsyncTaskWithProgress.java
new file mode 100644
index 0000000..7526d92
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/AsyncTaskWithProgress.java
@@ -0,0 +1,139 @@
+package cgeo.geocaching.utils;
+
+import cgeo.geocaching.activity.Progress;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.os.AsyncTask;
+
+/**
+ * AsyncTask which automatically shows a progress dialog. Use it like the {@code AsyncTask} class, but leave away the
+ * middle template parameter. Override {@link #doInBackgroundInternal(Object[])} and related methods.
+ * <p>
+ * If no style is given, the progress dialog uses "determinate" style with known maximum. The progress maximum is
+ * automatically derived from the number of {@code Params} given to the task in {@link #execute(Object...)}.
+ * </p>
+ *
+ * @param <Params>
+ * @param <Result>
+ */
+public abstract class AsyncTaskWithProgress<Params, Result> extends AsyncTask<Params, Integer, Result> {
+
+ private final Progress progress = new Progress();
+ private final Activity activity;
+ private final String progressTitle;
+ private final String progressMessage;
+ private boolean indeterminate = false;
+
+ /**
+ * Creates an AsyncTask with progress dialog.
+ *
+ * @param activity
+ * @param progressTitle
+ * @param progressMessage
+ */
+ public AsyncTaskWithProgress(final Activity activity, final String progressTitle, final String progressMessage) {
+ this(activity, progressTitle, progressMessage, false);
+ }
+
+ /**
+ * Creates an AsyncTask with progress dialog.
+ *
+ * @param activity
+ * @param progressTitle
+ */
+ public AsyncTaskWithProgress(final Activity activity, final String progressTitle) {
+ this(activity, progressTitle, null);
+ }
+
+ /**
+ * Creates an AsyncTask with progress dialog.
+ *
+ * @param activity
+ * @param progressTitle
+ * @param progressMessage
+ */
+ public AsyncTaskWithProgress(final Activity activity, final String progressTitle, final String progressMessage, boolean indeterminate) {
+ this.activity = activity;
+ this.progressTitle = progressTitle;
+ this.progressMessage = progressMessage;
+ this.indeterminate = indeterminate;
+ }
+
+ /**
+ * Creates an AsyncTask with progress dialog.
+ *
+ * @param activity
+ * @param progressTitle
+ */
+ public AsyncTaskWithProgress(final Activity activity, final String progressTitle, boolean indeterminate) {
+ this(activity, progressTitle, null, indeterminate);
+ }
+
+ @Override
+ protected final void onPreExecute() {
+ if (null != activity) {
+ if (indeterminate) {
+ progress.show(activity, progressTitle, progressMessage, true, null);
+ }
+ else {
+ progress.show(activity, progressTitle, progressMessage, ProgressDialog.STYLE_HORIZONTAL, null);
+ }
+ }
+ onPreExecuteInternal();
+ }
+
+ /**
+ * This method should typically be overridden by sub classes instead of {@link #onPreExecute()}.
+ */
+ protected void onPreExecuteInternal() {
+ // empty by default
+ }
+
+ @Override
+ protected final void onPostExecute(Result result) {
+ onPostExecuteInternal(result);
+ if (null != activity) {
+ progress.dismiss();
+ }
+ }
+
+ /**
+ * This method should typically be overridden by sub classes instead of {@link #onPostExecute(Object)}.
+ *
+ * @param result
+ */
+ protected void onPostExecuteInternal(Result result) {
+ // empty by default
+ }
+
+ @Override
+ protected final void onProgressUpdate(Integer... status) {
+ final int progressValue = status[0];
+ if (null != activity && progressValue >= 0) {
+ progress.setProgress(progressValue);
+ }
+ onProgressUpdateInternal(progressValue);
+ }
+
+ /**
+ * This method should by overridden by sub classes instead of {@link #onProgressUpdate(Integer...)}.
+ */
+ protected void onProgressUpdateInternal(@SuppressWarnings("unused") int progress) {
+ // empty by default
+ }
+
+ protected void setMessage(final String message) {
+ progress.setMessage(message);
+ }
+
+ @Override
+ protected final Result doInBackground(Params... params) {
+ if (params != null) {
+ progress.setMaxProgressAndReset(params.length);
+ }
+ return doInBackgroundInternal(params);
+ }
+
+ protected abstract Result doInBackgroundInternal(Params[] params);
+}
diff --git a/main/src/cgeo/geocaching/utils/GeoDirHandler.java b/main/src/cgeo/geocaching/utils/GeoDirHandler.java
index 21b2562..78455c4 100644
--- a/main/src/cgeo/geocaching/utils/GeoDirHandler.java
+++ b/main/src/cgeo/geocaching/utils/GeoDirHandler.java
@@ -9,10 +9,19 @@ import android.os.Message;
/**
* GeoData and Direction handler. Manipulating geodata and direction information
- * through a GeoDirHandler ensures that all listeners are registered from a
- * {@link android.os.Looper} thread.
+ * through a GeoDirHandler ensures that all listeners are registered from a {@link android.os.Looper} thread.
+ * <p>
+ * To use this class, override at least one of {@link #updateDirection(float)} or {@link #updateGeoData(IGeoData)}. You
+ * need to start the handler using one of
+ * <ul>
+ * <li>{@link #startDir()}</li>
+ * <li>{@link #startGeo()}</li>
+ * <li>{@link #startGeoAndDir()}</li>
+ * </ul>
+ * A good place might be the {@code onResume} method of the Activity. Stop the Handler accordingly in {@code onPause}.
+ * </p>
*/
-public class GeoDirHandler extends Handler implements IObserver<Object> {
+public abstract class GeoDirHandler extends Handler implements IObserver<Object> {
private static final int OBSERVABLE = 1 << 1;
private static final int START_GEO = 1 << 2;
@@ -57,7 +66,8 @@ public class GeoDirHandler extends Handler implements IObserver<Object> {
/**
* Update method called when new IGeoData is available.
*
- * @param data the new data
+ * @param data
+ * the new data
*/
protected void updateGeoData(final IGeoData data) {
// Override this in children
@@ -66,7 +76,8 @@ public class GeoDirHandler extends Handler implements IObserver<Object> {
/**
* Update method called when new direction data is available.
*
- * @param direction the new direction
+ * @param direction
+ * the new direction
*/
protected void updateDirection(final float direction) {
// Override this in children
@@ -118,4 +129,3 @@ public class GeoDirHandler extends Handler implements IObserver<Object> {
sendEmptyMessage(STOP_GEO | STOP_DIR);
}
}
-
diff --git a/main/src/cgeo/geocaching/utils/ImageHelper.java b/main/src/cgeo/geocaching/utils/ImageHelper.java
index 98cad64..ec77018 100644
--- a/main/src/cgeo/geocaching/utils/ImageHelper.java
+++ b/main/src/cgeo/geocaching/utils/ImageHelper.java
@@ -8,6 +8,9 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+
public class ImageHelper {
// Do not let this class be instantiated, this is a utility class.
@@ -22,11 +25,21 @@ public class ImageHelper {
* @return BitmapDrawable The scaled image
*/
public static BitmapDrawable scaleBitmapToFitDisplay(final Bitmap image) {
- final cgeoapplication app = cgeoapplication.getInstance();
Point displaySize = Compatibility.getDisplaySize();
final int maxWidth = displaySize.x - 25;
final int maxHeight = displaySize.y - 25;
+ return scaleBitmapTo(image, maxWidth, maxHeight);
+ }
+ /**
+ * Scales a bitmap to the given bounds if it is larger, otherwise returns the original bitmap.
+ *
+ * @param image
+ * The bitmap to scale
+ * @return BitmapDrawable The scaled image
+ */
+ public static BitmapDrawable scaleBitmapTo(final Bitmap image, final int maxWidth, final int maxHeight) {
+ final cgeoapplication app = cgeoapplication.getInstance();
Bitmap result = image;
int width = image.getWidth();
int height = image.getHeight();
@@ -43,4 +56,27 @@ public class ImageHelper {
return resultDrawable;
}
+ /**
+ * Store a bitmap to file.
+ *
+ * @param bitmap
+ * The bitmap to store
+ * @param format
+ * The image format
+ * @param quality
+ * The image quality
+ * @param pathOfOutputImage
+ * Path to store to
+ */
+ public static void storeBitmap(final Bitmap bitmap, final Bitmap.CompressFormat format, final int quality, final String pathOfOutputImage) {
+ try {
+ FileOutputStream out = new FileOutputStream(pathOfOutputImage);
+ BufferedOutputStream bos = new BufferedOutputStream(out);
+ bitmap.compress(format, quality, bos);
+ bos.flush();
+ bos.close();
+ } catch (Exception e) {
+ Log.e("Image", e);
+ }
+ }
}
diff --git a/main/src/cgeo/geocaching/utils/Log.java b/main/src/cgeo/geocaching/utils/Log.java
index 6d57b75..f912ddd 100644
--- a/main/src/cgeo/geocaching/utils/Log.java
+++ b/main/src/cgeo/geocaching/utils/Log.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.utils;
import android.os.Environment;
+import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@@ -100,12 +101,14 @@ final public class Log {
first = false;
file.delete();
}
+ Writer writer = null;
try {
- final Writer writer = new FileWriter(file, true);
+ writer = new BufferedWriter(new FileWriter(file, true));
writer.write(msg);
- writer.close();
} catch (final IOException e) {
Log.e("logToFile: cannot write to " + file, e);
+ } finally {
+ IOUtils.closeQuietly(writer);
}
}
}