diff options
Diffstat (limited to 'main/src/cgeo/geocaching/utils')
| -rw-r--r-- | main/src/cgeo/geocaching/utils/AsyncTaskWithProgress.java | 139 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/GeoDirHandler.java | 22 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/ImageHelper.java | 38 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/Log.java | 7 |
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); } } } |
