diff options
Diffstat (limited to 'main/src/cgeo/geocaching/utils')
18 files changed, 358 insertions, 83 deletions
diff --git a/main/src/cgeo/geocaching/utils/AngleUtils.java b/main/src/cgeo/geocaching/utils/AngleUtils.java index 6e59a91..fdd9a9d 100644 --- a/main/src/cgeo/geocaching/utils/AngleUtils.java +++ b/main/src/cgeo/geocaching/utils/AngleUtils.java @@ -1,6 +1,6 @@ package cgeo.geocaching.utils; -public class AngleUtils { +public final class AngleUtils { private AngleUtils() { // Do not instantiate @@ -8,7 +8,7 @@ public class AngleUtils { /** * Return the angle to turn of to go from an angle to the other - * + * * @param from * the origin angle in degrees * @param to 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/ClipboardUtils.java b/main/src/cgeo/geocaching/utils/ClipboardUtils.java index e6779ad..67069b2 100644 --- a/main/src/cgeo/geocaching/utils/ClipboardUtils.java +++ b/main/src/cgeo/geocaching/utils/ClipboardUtils.java @@ -3,7 +3,6 @@ package cgeo.geocaching.utils; import cgeo.geocaching.cgeoapplication; import android.content.Context; -import android.text.ClipboardManager; /** * Clipboard Utilities. Functions to copy data to the Android clipboard. @@ -13,6 +12,10 @@ import android.text.ClipboardManager; @SuppressWarnings("deprecation") public final class ClipboardUtils { + private ClipboardUtils() { + // utility class + } + /** * Places the text passed in onto the clipboard as text * @@ -20,7 +23,8 @@ public final class ClipboardUtils { * The text to place in the clipboard. */ public static void copyToClipboard(final CharSequence text) { - final ClipboardManager clipboard = (ClipboardManager) cgeoapplication.getInstance().getSystemService(Context.CLIPBOARD_SERVICE); + // fully qualified name used here to avoid buggy deprecation warning (of javac) on the import statement + final android.text.ClipboardManager clipboard = (android.text.ClipboardManager) cgeoapplication.getInstance().getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(text); } diff --git a/main/src/cgeo/geocaching/utils/CryptUtils.java b/main/src/cgeo/geocaching/utils/CryptUtils.java index df2baa0..18a337d 100644 --- a/main/src/cgeo/geocaching/utils/CryptUtils.java +++ b/main/src/cgeo/geocaching/utils/CryptUtils.java @@ -12,6 +12,10 @@ import javax.crypto.spec.SecretKeySpec; public final class CryptUtils { + private CryptUtils() { + // utility class + } + private static char[] base64map1 = new char[64]; private static byte[] base64map2 = new byte[128]; @@ -37,28 +41,36 @@ public final class CryptUtils { } } + private static class Rot13Encryption { + private boolean plaintext = false; + + char getNextEncryptedCharacter(final char c) { + int result = c; + if (result == '[') { + plaintext = true; + } else if (result == ']') { + plaintext = false; + } else if (!plaintext) { + int capitalized = result & 32; + result &= ~capitalized; + result = ((result >= 'A') && (result <= 'Z') ? ((result - 'A' + 13) % 26 + 'A') : result) + | capitalized; + } + return (char) result; + } + } + public static String rot13(String text) { if (text == null) { return ""; } final StringBuilder result = new StringBuilder(); - // plaintext flag (do not convert) - boolean plaintext = false; + Rot13Encryption rot13 = new Rot13Encryption(); final int length = text.length(); for (int index = 0; index < length; index++) { - int c = text.charAt(index); - if (c == '[') { - plaintext = true; - } else if (c == ']') { - plaintext = false; - } else if (!plaintext) { - int capitalized = c & 32; - c &= ~capitalized; - c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c) - | capitalized; - } - result.append((char) c); + char c = text.charAt(index); + result.append(rot13.getNextEncryptedCharacter(c)); } return result.toString(); } @@ -71,7 +83,7 @@ public final class CryptUtils { digest.update(text.getBytes(), 0, text.length()); hashed = new BigInteger(1, digest.digest()).toString(16); } catch (Exception e) { - Log.e("cgBase.md5", e); + Log.e("CryptUtils.md5", e); } return hashed; @@ -85,7 +97,7 @@ public final class CryptUtils { digest.update(text.getBytes(), 0, text.length()); hashed = new BigInteger(1, digest.digest()).toString(16); } catch (Exception e) { - Log.e("cgBase.sha1", e); + Log.e("CryptUtils.sha1", e); } return hashed; @@ -100,7 +112,7 @@ public final class CryptUtils { mac.init(secretKeySpec); macBytes = mac.doFinal(text.getBytes()); } catch (Exception e) { - Log.e("cgBase.hashHmac", e); + Log.e("CryptUtils.hashHmac", e); } return macBytes; @@ -111,22 +123,12 @@ public final class CryptUtils { // a SpannableStringBuilder instead of the pure text and we must replace each character inline. // Otherwise we loose all the images, colors and so on... final SpannableStringBuilder buffer = new SpannableStringBuilder(span); - boolean plaintext = false; + Rot13Encryption rot13 = new Rot13Encryption(); final int length = span.length(); for (int index = 0; index < length; index++) { - int c = span.charAt(index); - if (c == '[') { - plaintext = true; - } else if (c == ']') { - plaintext = false; - } else if (!plaintext) { - int capitalized = c & 32; - c &= ~capitalized; - c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c) - | capitalized; - } - buffer.replace(index, index + 1, String.valueOf((char) c)); + char c = span.charAt(index); + buffer.replace(index, index + 1, String.valueOf(rot13.getNextEncryptedCharacter(c))); } return buffer; } diff --git a/main/src/cgeo/geocaching/utils/DateUtils.java b/main/src/cgeo/geocaching/utils/DateUtils.java index fd5ef4a..b148979 100644 --- a/main/src/cgeo/geocaching/utils/DateUtils.java +++ b/main/src/cgeo/geocaching/utils/DateUtils.java @@ -2,7 +2,12 @@ package cgeo.geocaching.utils; import java.util.Calendar; -public class DateUtils { +public final class DateUtils { + + private DateUtils() { + // utility class + } + public static int daysSince(long date) { final Calendar logDate = Calendar.getInstance(); logDate.setTimeInMillis(date); diff --git a/main/src/cgeo/geocaching/utils/EditUtils.java b/main/src/cgeo/geocaching/utils/EditUtils.java index f2f89e7..d975df9 100644 --- a/main/src/cgeo/geocaching/utils/EditUtils.java +++ b/main/src/cgeo/geocaching/utils/EditUtils.java @@ -8,6 +8,10 @@ import android.widget.TextView; public final class EditUtils { + private EditUtils() { + // utility class + } + public static void setActionListener(final EditText editText, final Runnable runnable) { editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { diff --git a/main/src/cgeo/geocaching/utils/FileUtils.java b/main/src/cgeo/geocaching/utils/FileUtils.java index 6fefc02..5ab8fcc 100644 --- a/main/src/cgeo/geocaching/utils/FileUtils.java +++ b/main/src/cgeo/geocaching/utils/FileUtils.java @@ -9,12 +9,16 @@ import java.io.File; import java.util.List; /** - * Utiliy class for files + * Utility class for files * * @author rsudev * */ -public class FileUtils { +public final class FileUtils { + + private FileUtils() { + // utility class + } public static void listDir(List<File> result, File directory, FileSelector chooser, Handler feedBackHandler) { diff --git a/main/src/cgeo/geocaching/utils/GeoDirHandler.java b/main/src/cgeo/geocaching/utils/GeoDirHandler.java index 21b2562..98a2287 100644 --- a/main/src/cgeo/geocaching/utils/GeoDirHandler.java +++ b/main/src/cgeo/geocaching/utils/GeoDirHandler.java @@ -1,7 +1,7 @@ package cgeo.geocaching.utils; import cgeo.geocaching.IGeoData; -import cgeo.geocaching.Settings; +import cgeo.geocaching.settings.Settings; import cgeo.geocaching.cgeoapplication; import android.os.Handler; @@ -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/HtmlUtils.java b/main/src/cgeo/geocaching/utils/HtmlUtils.java index 8d4eed1..5717a37 100644 --- a/main/src/cgeo/geocaching/utils/HtmlUtils.java +++ b/main/src/cgeo/geocaching/utils/HtmlUtils.java @@ -10,7 +10,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -public class HtmlUtils { +public final class HtmlUtils { + + private HtmlUtils() { + // utility class + } /** * Extract the text from a HTML based string. This is similar to what HTML.fromHtml(...) does, but this method also @@ -20,6 +24,9 @@ public class HtmlUtils { * @return */ public static String extractText(CharSequence html) { + if (StringUtils.isBlank(html)) { + return StringUtils.EMPTY; + } String result = html.toString(); // recognize images in textview HTML contents diff --git a/main/src/cgeo/geocaching/utils/ImageHelper.java b/main/src/cgeo/geocaching/utils/ImageUtils.java index 98cad64..ea7d3ff 100644 --- a/main/src/cgeo/geocaching/utils/ImageHelper.java +++ b/main/src/cgeo/geocaching/utils/ImageUtils.java @@ -8,10 +8,13 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; -public class ImageHelper { +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; - // Do not let this class be instantiated, this is a utility class. - private ImageHelper() { +public final class ImageUtils { + + private ImageUtils() { + // 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("ImageHelper.storeBitmap", e); + } + } } diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java index 698d38a..708dff0 100644 --- a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java +++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java @@ -10,13 +10,13 @@ import java.util.List; /** * Synchronized set wrapper for the LeastRecentlyUsedMap. * - * This code is heavily based on the HashSet code that represent Map as a Set. + * This code is heavily based on the HashSet code that represents Map as a Set. * Unfortunately HashSet does not allow to use a custom Map as its Storage. * Therefore overriding removeEldestEntry() is impossible for a normal LinkedHashSet. * * Synchronization is added to guard against concurrent modification. Iterator * access has to be guarded externally or the synchronized getAsList method can be used - * to get a clone for iteration + * to get a clone for iteration. */ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> implements Cloneable, java.io.Serializable { @@ -28,7 +28,7 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> public LeastRecentlyUsedSet(int maxEntries, int initialCapacity, float loadFactor) { // because we don't use any Map.get() methods from the Set, BOUNDED and LRU_CACHE have the exact same Behaviour - // So we useLRU_CACHE mode because it should perform a bit better (as it doesn't re-add explicitly) + // So we use LRU_CACHE mode because it should perform a bit better (as it doesn't re-add explicitly) map = new LeastRecentlyUsedMap.LruCache<E, Object>(maxEntries, initialCapacity, loadFactor); } diff --git a/main/src/cgeo/geocaching/utils/Log.java b/main/src/cgeo/geocaching/utils/Log.java index 6d57b75..f7f33d9 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; @@ -22,11 +23,11 @@ final public class Log { } /** - * make a non persisted copy of the debug flag from the settings for performance reasons - * + * save a copy of the debug flag from the settings for performance reasons + * * @param isDebug */ - public static void setDebugUnsaved(boolean isDebug) { + public static void setDebug(boolean isDebug) { Log.isDebug = isDebug; } @@ -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); } } } diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index 0a8e547..6d5f130 100644 --- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java @@ -1,7 +1,7 @@ package cgeo.geocaching.utils; import cgeo.geocaching.R; -import cgeo.geocaching.Settings; +import cgeo.geocaching.settings.Settings; import cgeo.geocaching.Trackable; import cgeo.geocaching.Geocache; import cgeo.geocaching.connector.gc.GCConstants; @@ -188,7 +188,7 @@ public class LogTemplateProvider { } try { - return Integer.parseInt(BaseUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")); + return Integer.parseInt(TextUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")); } catch (NumberFormatException e) { Log.e("parseFindCount", e); return -1; diff --git a/main/src/cgeo/geocaching/utils/PeriodicHandler.java b/main/src/cgeo/geocaching/utils/PeriodicHandler.java index 2759580..288bbb0 100644 --- a/main/src/cgeo/geocaching/utils/PeriodicHandler.java +++ b/main/src/cgeo/geocaching/utils/PeriodicHandler.java @@ -3,16 +3,26 @@ package cgeo.geocaching.utils; import android.os.Handler; import android.os.Message; +import java.lang.ref.WeakReference; + /** * A PeriodicHandler class helps with the implementation of a periodic * action embedded in a thread with a looper such as the UI thread. - * The act() method will be called periodically. The clock may drift - * as the implementation does not target real-time actions. + * The onPeriodic() method of the listener will be called periodically. + * The clock may drift as the implementation does not target real-time + * actions. * * The handler will be interrupted if the device goes to sleep. * + * The handler only keeps a weak reference to the listener. If the listener + * is garbage-collected without having stopped the timer, the handler will + * stop itself. */ -abstract public class PeriodicHandler extends Handler { +final public class PeriodicHandler extends Handler { + + public static interface PeriodicHandlerListener { + public void onPeriodic(); + } final static private int START = 0; final static private int STOP = 1; @@ -20,21 +30,19 @@ abstract public class PeriodicHandler extends Handler { final private long period; + final private WeakReference<PeriodicHandlerListener> listenerRef; + /** * Create a new PeriodicHandler object. * * @param period * The period in milliseconds. */ - protected PeriodicHandler(final long period) { + public PeriodicHandler(final long period, final PeriodicHandlerListener listener) { this.period = period; + listenerRef = new WeakReference<PeriodicHandlerListener>(listener); } - /** - * Subclasses of PeriodicHandler must implement this method. - */ - abstract public void act(); - @Override public void handleMessage(final Message msg) { switch (msg.what) { @@ -46,8 +54,11 @@ abstract public class PeriodicHandler extends Handler { removeMessages(ACT); break; case ACT: - sendEmptyMessageDelayed(ACT, period); - act(); + final PeriodicHandlerListener listener = listenerRef.get(); + if (listener != null) { + sendEmptyMessageDelayed(ACT, period); + listener.onPeriodic(); + } break; default: throw new UnsupportedOperationException(); diff --git a/main/src/cgeo/geocaching/utils/ProcessUtils.java b/main/src/cgeo/geocaching/utils/ProcessUtils.java index 53991fb..85cedc5 100644 --- a/main/src/cgeo/geocaching/utils/ProcessUtils.java +++ b/main/src/cgeo/geocaching/utils/ProcessUtils.java @@ -3,14 +3,55 @@ package cgeo.geocaching.utils; import cgeo.geocaching.cgeoapplication; import android.content.Intent; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -public class ProcessUtils { +import java.util.List; - public static boolean isInstalled(final String packageName) { +public final class ProcessUtils { + + private ProcessUtils() { + // utility class + } + + /** + * Preferred method to detect the availability of an external app + * + * @param packageName + * @return + */ + public static boolean isLaunchable(final String packageName) { return getLaunchIntent(packageName) != null; } + /** + * Checks whether a launch intent is available or if the package is just installed + * This function is relatively costly, so if you know that the package in question has + * a launch intent, use isLaunchable() instead. + * + * @param packageName + * @return + */ + public static boolean isInstalled(final String packageName) { + return isLaunchable(packageName) || hasPackageInstalled(packageName); + } + + /** + * This will find installed applications even without launch intent (e.g. the streetview plugin). + */ + private static boolean hasPackageInstalled(final String packageName) { + final List<PackageInfo> packs = cgeoapplication.getInstance().getPackageManager().getInstalledPackages(0); + for (final PackageInfo packageInfo : packs) { + if (packageName.equals(packageInfo.packageName)) { + return true; + } + } + return false; + } + + /** + * This will find applications, which can be launched. + */ public static Intent getLaunchIntent(final String packageName) { if (packageName == null) { return null; @@ -20,7 +61,7 @@ public class ProcessUtils { // This can throw an exception where the exception type is only defined on API Level > 3 // therefore surround with try-catch return packageManager.getLaunchIntentForPackage(packageName); - } catch (Exception e) { + } catch (final Exception e) { return null; } } diff --git a/main/src/cgeo/geocaching/utils/BaseUtils.java b/main/src/cgeo/geocaching/utils/TextUtils.java index 82e48cb..c9d4958 100644 --- a/main/src/cgeo/geocaching/utils/BaseUtils.java +++ b/main/src/cgeo/geocaching/utils/TextUtils.java @@ -9,10 +9,14 @@ import java.util.regex.Pattern; /** * Misc. utils. All methods don't use Android specific stuff to use these methods in plain JUnit tests. */ -public final class BaseUtils { +public final class TextUtils { private static final Pattern PATTERN_REMOVE_NONPRINTABLE = Pattern.compile("\\p{Cntrl}"); + private TextUtils() { + // utility class + } + /** * Searches for the pattern p in the data. If the pattern is not found defaultValue is returned * @@ -69,7 +73,7 @@ public final class BaseUtils { * @return defaultValue or the first group if the pattern matches (trimmed if wanted) */ public static String getMatch(final String data, final Pattern p, final boolean trim, final String defaultValue) { - return BaseUtils.getMatch(data, p, trim, 1, defaultValue, false); + return TextUtils.getMatch(data, p, trim, 1, defaultValue, false); } /** @@ -84,7 +88,7 @@ public final class BaseUtils { * @return defaultValue or the first group if the pattern matches (trimmed) */ public static String getMatch(final String data, final Pattern p, final String defaultValue) { - return BaseUtils.getMatch(data, p, true, 1, defaultValue, false); + return TextUtils.getMatch(data, p, true, 1, defaultValue, false); } /** @@ -104,13 +108,13 @@ public final class BaseUtils { } /** - * Replaces every \n, \r and \t with a single space. Afterwards multiples spaces + * Replaces every \n, \r and \t with a single space. Afterwards multiple spaces * are merged into a single space. Finally leading spaces are deleted. * * This method must be fast, but may not lead to the shortest replacement String. * * You are only allowed to change this code if you can prove it became faster on a device. - * see cgeo.geocaching.test.WhiteSpaceTest#replaceWhitespaceManually in the test project + * see cgeo.geocaching.test.WhiteSpaceTest#replaceWhitespaceManually in the test project. * * @param data * complete HTML page @@ -137,10 +141,11 @@ public final class BaseUtils { } /** - * Quick and naive check for possible html-content of a string. + * Quick and naive check for possible rich HTML content in a string. * - * @param str - * @return True, if <code>str</code> could contain html + * @param str A string containing HTML code. + * @return <tt>true</tt> if <tt>str</tt> contains HTML code that needs to go through a HTML renderer before + * being displayed, <tt>false</tt> if it can be displayed as-is without any loss */ public static boolean containsHtml(final String str) { return str.indexOf('<') != -1 || str.indexOf('&') != -1; diff --git a/main/src/cgeo/geocaching/utils/TranslationUtils.java b/main/src/cgeo/geocaching/utils/TranslationUtils.java index 4d318f0..1224f7e 100644 --- a/main/src/cgeo/geocaching/utils/TranslationUtils.java +++ b/main/src/cgeo/geocaching/utils/TranslationUtils.java @@ -19,6 +19,10 @@ public final class TranslationUtils { public static final int translationTextLengthToWarn = 500; private static final String TRANSLATION_APP = "com.google.android.apps.translate"; + private TranslationUtils() { + // utility class + } + /** * Build a URI for Google Translate * @@ -31,7 +35,7 @@ public final class TranslationUtils { private static String buildTranslationURI(final String toLang, final String text) { String content = Network.encode(text); // the app works better without the "+", the website works better with "+", therefore assume using the app if installed - if (ProcessUtils.isInstalled(TRANSLATION_APP)) { + if (ProcessUtils.isLaunchable(TRANSLATION_APP)) { content = content.replace("+", "%20"); } return translationWebsite + translationForceClassicMode + translationAutoSelect + translationFieldSeparator + toLang + translationFieldSeparator + content; diff --git a/main/src/cgeo/geocaching/utils/XmlUtils.java b/main/src/cgeo/geocaching/utils/XmlUtils.java index 4e08f42..2d85950 100644 --- a/main/src/cgeo/geocaching/utils/XmlUtils.java +++ b/main/src/cgeo/geocaching/utils/XmlUtils.java @@ -4,7 +4,7 @@ import org.xmlpull.v1.XmlSerializer; import java.io.IOException; -public class XmlUtils { +public final class XmlUtils { private XmlUtils() { // Do not instantiate |
