diff options
Diffstat (limited to 'main/src/cgeo/geocaching/utils')
| -rw-r--r-- | main/src/cgeo/geocaching/utils/CancellableHandler.java | 16 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/CryptUtils.java | 3 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/FileUtils.java | 27 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/GeoDirHandler.java | 108 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/IObserver.java | 22 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/ISubject.java | 57 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/ImageUtils.java | 2 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java | 4 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/LogTemplateProvider.java | 4 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/MemorySubject.java | 45 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/RunnableWithArgument.java | 7 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/Subject.java | 76 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java | 11 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/TextUtils.java | 1 |
14 files changed, 115 insertions, 268 deletions
diff --git a/main/src/cgeo/geocaching/utils/CancellableHandler.java b/main/src/cgeo/geocaching/utils/CancellableHandler.java index cb4b9db..01fb568 100644 --- a/main/src/cgeo/geocaching/utils/CancellableHandler.java +++ b/main/src/cgeo/geocaching/utils/CancellableHandler.java @@ -2,6 +2,9 @@ package cgeo.geocaching.utils; import cgeo.geocaching.CgeoApplication; +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + import android.os.Handler; import android.os.Message; @@ -13,6 +16,7 @@ public abstract class CancellableHandler extends Handler { protected static final int UPDATE_LOAD_PROGRESS_DETAIL = 42186; private volatile boolean cancelled = false; + private static CompositeSubscription subscriptions = new CompositeSubscription(); private static class CancelHolder { final Object payload; @@ -30,6 +34,7 @@ public abstract class CancellableHandler extends Handler { if (message.obj instanceof CancelHolder) { cancelled = true; + subscriptions.unsubscribe(); handleCancel(((CancelHolder) message.obj).payload); } else { handleRegularMessage(message); @@ -37,6 +42,17 @@ public abstract class CancellableHandler extends Handler { } /** + * Add a subscription to the list of subscriptions to be subscribed at cancellation time. + */ + final public void unsubscribeIfCancelled(final Subscription subscription) { + subscriptions.add(subscription); + if (cancelled) { + // Protect against race conditions + subscriptions.unsubscribe(); + } + } + + /** * Handle a non-cancel message.<br> * Subclasses must implement this to handle messages. * diff --git a/main/src/cgeo/geocaching/utils/CryptUtils.java b/main/src/cgeo/geocaching/utils/CryptUtils.java index 5273fa5..80d841f 100644 --- a/main/src/cgeo/geocaching/utils/CryptUtils.java +++ b/main/src/cgeo/geocaching/utils/CryptUtils.java @@ -3,6 +3,7 @@ package cgeo.geocaching.utils; import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; import android.text.Spannable; import android.text.SpannableStringBuilder; @@ -66,6 +67,8 @@ public final class CryptUtils { } } + @SuppressWarnings("null") + @NonNull public static String rot13(String text) { if (text == null) { return StringUtils.EMPTY; diff --git a/main/src/cgeo/geocaching/utils/FileUtils.java b/main/src/cgeo/geocaching/utils/FileUtils.java index f650216..54553c2 100644 --- a/main/src/cgeo/geocaching/utils/FileUtils.java +++ b/main/src/cgeo/geocaching/utils/FileUtils.java @@ -1,12 +1,20 @@ package cgeo.geocaching.utils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.StringUtils; import android.os.Handler; import android.os.Message; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.util.List; /** @@ -126,4 +134,23 @@ public final class FileUtils { } return success; } + + public static boolean writeFileUTF16(File file, String content) { + // TODO: replace by some apache.commons IOUtils or FileUtils code + Writer fileWriter = null; + BufferedOutputStream buffer = null; + try { + final OutputStream os = new FileOutputStream(file); + buffer = new BufferedOutputStream(os); + fileWriter = new OutputStreamWriter(buffer, CharEncoding.UTF_16); + fileWriter.write(content.toString()); + } catch (final IOException e) { + Log.e("FieldnoteExport.ExportTask export", e); + return false; + } finally { + IOUtils.closeQuietly(fileWriter); + IOUtils.closeQuietly(buffer); + } + return true; + } } diff --git a/main/src/cgeo/geocaching/utils/GeoDirHandler.java b/main/src/cgeo/geocaching/utils/GeoDirHandler.java index c85648b..7050e61 100644 --- a/main/src/cgeo/geocaching/utils/GeoDirHandler.java +++ b/main/src/cgeo/geocaching/utils/GeoDirHandler.java @@ -4,12 +4,16 @@ import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.IGeoData; import cgeo.geocaching.settings.Settings; -import android.os.Handler; -import android.os.Message; +import rx.Scheduler; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; +import rx.functions.Action1; + +import java.util.concurrent.TimeUnit; /** - * 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. + * GeoData and Direction handler. * <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 @@ -21,47 +25,11 @@ import android.os.Message; * A good place might be the {@code onResume} method of the Activity. Stop the Handler accordingly in {@code onPause}. * </p> */ -public abstract class GeoDirHandler extends Handler implements IObserver<Object> { - - private static final int OBSERVABLE = 1 << 1; - private static final int START_GEO = 1 << 2; - private static final int START_DIR = 1 << 3; - private static final int STOP_GEO = 1 << 4; - private static final int STOP_DIR = 1 << 5; - +public abstract class GeoDirHandler { private static final CgeoApplication app = CgeoApplication.getInstance(); - @Override - final public void handleMessage(final Message message) { - if ((message.what & START_GEO) != 0) { - app.addGeoObserver(this); - } - - if ((message.what & START_DIR) != 0) { - app.addDirectionObserver(this); - } - - if ((message.what & STOP_GEO) != 0) { - app.deleteGeoObserver(this); - } - - if ((message.what & STOP_DIR) != 0) { - app.deleteDirectionObserver(this); - } - - if ((message.what & OBSERVABLE) != 0) { - if (message.obj instanceof IGeoData) { - updateGeoData((IGeoData) message.obj); - } else { - updateDirection((Float) message.obj); - } - } - } - - @Override - final public void update(final Object o) { - obtainMessage(OBSERVABLE, o).sendToTarget(); - } + private Subscription dirSubscription = null; + private Subscription geoSubscription = null; /** * Update method called when new IGeoData is available. @@ -69,7 +37,7 @@ public abstract class GeoDirHandler extends Handler implements IObserver<Object> * @param data * the new data */ - protected void updateGeoData(final IGeoData data) { + public void updateGeoData(final IGeoData data) { // Override this in children } @@ -79,24 +47,38 @@ public abstract class GeoDirHandler extends Handler implements IObserver<Object> * @param direction * the new direction */ - protected void updateDirection(final float direction) { + public void updateDirection(final float direction) { // Override this in children } /** * Register the current GeoDirHandler for GeoData information. */ - public void startGeo() { - sendEmptyMessage(START_GEO); + public synchronized void startGeo() { + geoSubscription = app.currentGeoObject() + .subscribeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1<IGeoData>() { + @Override + public void call(final IGeoData geoData) { + updateGeoData(geoData); + } + }); } /** * Register the current GeoDirHandler for direction information if the preferences * allow it. */ - public void startDir() { + public synchronized void startDir() { if (Settings.isUseCompass()) { - sendEmptyMessage(START_DIR); + dirSubscription = app.currentDirObject() + .subscribeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1<Float>() { + @Override + public void call(final Float direction) { + updateDirection(direction); + } + }); } } @@ -105,27 +87,43 @@ public abstract class GeoDirHandler extends Handler implements IObserver<Object> * preferences allow it). */ public void startGeoAndDir() { - sendEmptyMessage(START_GEO | (Settings.isUseCompass() ? START_DIR : 0)); + startGeo(); + startDir(); } /** * Unregister the current GeoDirHandler for GeoData information. */ - public void stopGeo() { - sendEmptyMessage(STOP_GEO); + public synchronized void stopGeo() { + // Delay the unsubscription by 2.5 seconds, so that another activity has + // the time to subscribe and the GPS receiver will not be turned down. + if (geoSubscription != null) { + final Subscription subscription = geoSubscription; + geoSubscription = null; + Schedulers.newThread().schedule(new Action1<Scheduler.Inner>() { + @Override + public void call(final Scheduler.Inner inner) { + subscription.unsubscribe(); + } + }, 2500, TimeUnit.MILLISECONDS); + } } /** * Unregister the current GeoDirHandler for direction information. */ - public void stopDir() { - sendEmptyMessage(STOP_DIR); + public synchronized void stopDir() { + if (dirSubscription != null) { + dirSubscription.unsubscribe(); + dirSubscription = null; + } } /** * Unregister the current GeoDirHandler for GeoData and direction information. */ public void stopGeoAndDir() { - sendEmptyMessage(STOP_GEO | STOP_DIR); + stopGeo(); + stopDir(); } } diff --git a/main/src/cgeo/geocaching/utils/IObserver.java b/main/src/cgeo/geocaching/utils/IObserver.java deleted file mode 100644 index bfcc798..0000000 --- a/main/src/cgeo/geocaching/utils/IObserver.java +++ /dev/null @@ -1,22 +0,0 @@ -package cgeo.geocaching.utils; - -/** - * Observer interface. - * <p/> - * An observer will receive updates about the observed object (implementing the {@link ISubject} interface) through its - * {@link #update(Object)} method. - * - * @param <T> - * the kind of data to observe - */ -public interface IObserver<T> { - - /** - * Called when an observed object has updated its data. - * - * @param data - * the updated data - */ - void update(final T data); - -} diff --git a/main/src/cgeo/geocaching/utils/ISubject.java b/main/src/cgeo/geocaching/utils/ISubject.java deleted file mode 100644 index c325db0..0000000 --- a/main/src/cgeo/geocaching/utils/ISubject.java +++ /dev/null @@ -1,57 +0,0 @@ -package cgeo.geocaching.utils; - -/** - * Interface for subjects objects. Those can be observed by objects implementing the {@link IObserver} interface. - * - * @param <T> - * the kind of data to observe - */ - -public interface ISubject<T> { - - /** - * Add an observer to the observers list. - * <p/> - * Observers will be notified with no particular order. - * - * @param observer - * the observer to add - * @return true if the observer has been added, false if it was present already - */ - public boolean addObserver(final IObserver<? super T> observer); - - /** - * Delete an observer from the observers list. - * - * @param observer - * the observer to remove - * @return true if the observer has been removed, false if it was not in the list of observers - */ - public boolean deleteObserver(final IObserver<? super T> observer); - - /** - * Number of observers currently observing the object. - * - * @return the number of observers - */ - public int sizeObservers(); - - /** - * Notify all the observers that new data is available. - * <p/> - * The {@link IObserver#update(Object)} method of each observer will be called with no particular order. - * - * @param data - * the updated data - * @return true if at least one observer was notified, false if there were no observers - */ - public boolean notifyObservers(final T data); - - /** - * Clear the observers list. - * - * @return true if there were observers before calling this method, false if the observers list was empty - */ - public boolean clearObservers(); - -} diff --git a/main/src/cgeo/geocaching/utils/ImageUtils.java b/main/src/cgeo/geocaching/utils/ImageUtils.java index 73f322c..9f47ead 100644 --- a/main/src/cgeo/geocaching/utils/ImageUtils.java +++ b/main/src/cgeo/geocaching/utils/ImageUtils.java @@ -78,7 +78,7 @@ public final class ImageUtils { * @return BitmapDrawable The scaled image */ @NonNull - public static BitmapDrawable scaleBitmapTo(@NonNull final Bitmap image, final int maxWidth, final int maxHeight) { + private static BitmapDrawable scaleBitmapTo(@NonNull final Bitmap image, final int maxWidth, final int maxHeight) { final CgeoApplication app = CgeoApplication.getInstance(); Bitmap result = image; int width = image.getWidth(); diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java index 708dff0..0c83076 100644 --- a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java +++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java @@ -1,5 +1,7 @@ package cgeo.geocaching.utils; +import org.eclipse.jdt.annotation.NonNull; + import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; @@ -42,6 +44,8 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> * * @see HashSet */ + @SuppressWarnings("null") + @NonNull @Override public Iterator<E> iterator() { return map.keySet().iterator(); diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index 76fa0f7..5fa0982 100644 --- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java @@ -47,10 +47,6 @@ public final class LogTemplateProvider { this.logEntry = logEntry; } - public LogContext(final boolean offline) { - this(null, null, offline); - } - public LogContext(final Geocache cache, LogEntry logEntry, final boolean offline) { this.cache = cache; this.offline = offline; diff --git a/main/src/cgeo/geocaching/utils/MemorySubject.java b/main/src/cgeo/geocaching/utils/MemorySubject.java deleted file mode 100644 index c424528..0000000 --- a/main/src/cgeo/geocaching/utils/MemorySubject.java +++ /dev/null @@ -1,45 +0,0 @@ -package cgeo.geocaching.utils; - -/** - * Synchronized implementation of the {@link ISubject} interface with an added pull interface. - * - * @param <T> - * the kind of data to observe - */ -public class MemorySubject<T> extends Subject<T> { - - /** - * The latest version of the observed data. - * <p/> - * A child class implementation may want to set this field from its constructors, in case early observers request - * the data before it got a chance to get updated. Otherwise, <code>null</code> will be returned until updated - * data is available. - */ - private T memory; - - @Override - public synchronized boolean addObserver(final IObserver<? super T> observer) { - final boolean added = super.addObserver(observer); - if (added && memory != null) { - observer.update(memory); - } - return added; - } - - @Override - public synchronized boolean notifyObservers(final T data) { - memory = data; - return super.notifyObservers(data); - } - - /** - * Get the memorized version of the data. - * - * @return the initial data set by the subject (which may be <code>null</code>), - * or the updated data if it is available - */ - public synchronized T getMemory() { - return memory; - } - -} diff --git a/main/src/cgeo/geocaching/utils/RunnableWithArgument.java b/main/src/cgeo/geocaching/utils/RunnableWithArgument.java deleted file mode 100644 index 6137efd..0000000 --- a/main/src/cgeo/geocaching/utils/RunnableWithArgument.java +++ /dev/null @@ -1,7 +0,0 @@ -package cgeo.geocaching.utils; - -public interface RunnableWithArgument<T> { - - abstract void run(final T argument); - -} diff --git a/main/src/cgeo/geocaching/utils/Subject.java b/main/src/cgeo/geocaching/utils/Subject.java deleted file mode 100644 index b1754cc..0000000 --- a/main/src/cgeo/geocaching/utils/Subject.java +++ /dev/null @@ -1,76 +0,0 @@ -package cgeo.geocaching.utils; - -import java.util.LinkedHashSet; -import java.util.Set; - -/** - * Synchronized implementation of the {@link ISubject} interface. - * - * @param <T> - * the kind of data to observe - */ -public class Subject<T> implements ISubject<T> { - - /** - * Collection of observers. - */ - protected final Set<IObserver<? super T>> observers = new LinkedHashSet<IObserver<? super T>>(); - - @Override - public synchronized boolean addObserver(final IObserver<? super T> observer) { - final boolean added = observers.add(observer); - if (added && observers.size() == 1) { - onFirstObserver(); - } - return added; - } - - @Override - public synchronized boolean deleteObserver(final IObserver<? super T> observer) { - final boolean removed = observers.remove(observer); - if (removed && observers.isEmpty()) { - onLastObserver(); - } - return removed; - } - - @Override - public synchronized boolean notifyObservers(final T arg) { - final boolean nonEmpty = !observers.isEmpty(); - for (final IObserver<? super T> observer : observers) { - observer.update(arg); - } - return nonEmpty; - } - - @Override - public synchronized int sizeObservers() { - return observers.size(); - } - - @Override - public synchronized boolean clearObservers() { - final boolean nonEmpty = !observers.isEmpty(); - for (final IObserver<? super T> observer : observers) { - deleteObserver(observer); - } - return nonEmpty; - } - - /** - * Method called when the collection of observers goes from empty to non-empty. - * <p/> - * The default implementation does nothing and may be overwritten by child classes. - */ - protected void onFirstObserver() { - } - - /** - * Method called when the collection of observers goes from non-empty to empty. - * <p/> - * The default implementation does nothing and may be overwritten by child classes. - */ - protected void onLastObserver() { - } - -} diff --git a/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java b/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java index 2368469..7848d1a 100644 --- a/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java +++ b/main/src/cgeo/geocaching/utils/SynchronizedDateFormat.java @@ -4,6 +4,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; +import java.util.TimeZone; public class SynchronizedDateFormat { private final SimpleDateFormat format; @@ -12,7 +13,17 @@ public class SynchronizedDateFormat { format = new SimpleDateFormat(pattern, locale); } + public SynchronizedDateFormat(String pattern, TimeZone timeZone, Locale locale) { + format = new SimpleDateFormat(pattern, locale); + format.setTimeZone(timeZone); + } + public synchronized Date parse(final String input) throws ParseException { return format.parse(input); } + + public synchronized String format(final Date date) { + return format.format(date); + } + } diff --git a/main/src/cgeo/geocaching/utils/TextUtils.java b/main/src/cgeo/geocaching/utils/TextUtils.java index efbb2d7..c4e1128 100644 --- a/main/src/cgeo/geocaching/utils/TextUtils.java +++ b/main/src/cgeo/geocaching/utils/TextUtils.java @@ -4,7 +4,6 @@ package cgeo.geocaching.utils; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - import org.eclipse.jdt.annotation.Nullable; import java.util.regex.Matcher; |
