diff options
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline')
6 files changed, 794 insertions, 784 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java index 2ecc23a420..58093f285b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java @@ -7,6 +7,7 @@ import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; + import timber.log.Timber; import com.mapbox.mapboxsdk.MapboxAccountManager; @@ -20,311 +21,310 @@ import java.io.File; */ public class OfflineManager { - // - // Static methods - // + // + // Static methods + // - static { - System.loadLibrary("mapbox-gl"); - } + static { + System.loadLibrary("mapbox-gl"); + } - // Default database name - private final static String DATABASE_NAME = "mbgl-offline.db"; + // Default database name + private static final String DATABASE_NAME = "mbgl-offline.db"; - /* - * The maximumCacheSize parameter is a limit applied to non-offline resources only, - * i.e. resources added to the database for the "ambient use" caching functionality. - * There is no size limit for offline resources. - */ - private final static long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024; + /* + * The maximumCacheSize parameter is a limit applied to non-offline resources only, + * i.e. resources added to the database for the "ambient use" caching functionality. + * There is no size limit for offline resources. + */ + private static final long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024; - // Holds the pointer to JNI DefaultFileSource - private long mDefaultFileSourcePtr = 0; + // Holds the pointer to JNI DefaultFileSource + private long mDefaultFileSourcePtr = 0; - // Makes sure callbacks come back to the main thread - private Handler handler; + // Makes sure callbacks come back to the main thread + private Handler handler; - // This object is implemented as a singleton - private static OfflineManager instance; + // This object is implemented as a singleton + private static OfflineManager instance; + /** + * This callback receives an asynchronous response containing a list of all + * {@link OfflineRegion} in the database, or an error message otherwise. + */ + public interface ListOfflineRegionsCallback { /** - * This callback receives an asynchronous response containing a list of all - * {@link OfflineRegion} in the database, or an error message otherwise. + * Receives the list of offline regions. + * + * @param offlineRegions the offline region array */ - public interface ListOfflineRegionsCallback { - /** - * Receives the list of offline regions. - * - * @param offlineRegions the offline region array - */ - void onList(OfflineRegion[] offlineRegions); - - /** - * Receives the error message. - * - * @param error the error message - */ - void onError(String error); - } + void onList(OfflineRegion[] offlineRegions); /** - * This callback receives an asynchronous response containing the newly created - * {@link OfflineRegion} in the database, or an error message otherwise. + * Receives the error message. + * + * @param error the error message */ - public interface CreateOfflineRegionCallback { - /** - * Receives the newly created offline region. - * - * @param offlineRegion the offline region to create - */ - void onCreate(OfflineRegion offlineRegion); - - /** - * Receives the error message. - * - * @param error the error message to be shown - */ - void onError(String error); - } - - /* - * Constructors + void onError(String error); + } + + /** + * This callback receives an asynchronous response containing the newly created + * {@link OfflineRegion} in the database, or an error message otherwise. + */ + public interface CreateOfflineRegionCallback { + /** + * Receives the newly created offline region. + * + * @param offlineRegion the offline region to create */ - - private OfflineManager(Context context) { - // Get a pointer to the DefaultFileSource instance - String assetRoot = getDatabasePath(context); - String cachePath = assetRoot + File.separator + DATABASE_NAME; - mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE); - - if (MapboxAccountManager.getInstance() != null) { - setAccessToken(mDefaultFileSourcePtr, MapboxAccountManager.getInstance().getAccessToken()); - } - - // Delete any existing previous ambient cache database - deleteAmbientDatabase(context); - } - - public static String getDatabasePath(Context context) { - // Default value - boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL; - - try { - // Try getting a custom value from the app Manifest - ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( - context.getPackageName(), PackageManager.GET_META_DATA); - setStorageExternal = appInfo.metaData.getBoolean( - MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL, - MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL); - } catch (PackageManager.NameNotFoundException e) { - Timber.e("Failed to read the package metadata: " + e.getMessage()); - } catch (Exception e) { - Timber.e("Failed to read the storage key: " + e.getMessage()); - } - - String databasePath = null; - if (setStorageExternal && isExternalStorageReadable()) { - try { - // Try getting the external storage path - databasePath = context.getExternalFilesDir(null).getAbsolutePath(); - } catch (NullPointerException e) { - Timber.e("Failed to obtain the external storage path: " + e.getMessage()); - } - } - - if (databasePath == null) { - // Default to internal storage - databasePath = context.getFilesDir().getAbsolutePath(); - } - - return databasePath; - } + void onCreate(OfflineRegion offlineRegion); /** - * Checks if external storage is available to at least read. In order for this to work, make - * sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> - * (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest. - * <p> - * Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal - * </p> + * Receives the error message. * - * @return true if external storage is readable + * @param error the error message to be shown */ - public static boolean isExternalStorageReadable() { - String state = Environment.getExternalStorageState(); - if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { - return true; - } + void onError(String error); + } - Timber.w("External storage was requested but it isn't readable. For API level < 18" - + " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE" - + " permissions in your app Manifest (defaulting to internal storage)."); + /* + * Constructors + */ - return false; - } + private OfflineManager(Context context) { + // Get a pointer to the DefaultFileSource instance + String assetRoot = getDatabasePath(context); + String cachePath = assetRoot + File.separator + DATABASE_NAME; + mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE); - private void deleteAmbientDatabase(final Context context) { - // Delete the file in a separate thread to avoid affecting the UI - new Thread(new Runnable() { - @Override - public void run() { - try { - String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db"; - File file = new File(path); - if (file.exists()) { - file.delete(); - Timber.d("Old ambient cache database deleted to save space: " + path); - } - } catch (Exception e) { - Timber.e("Failed to delete old ambient cache database: " + e.getMessage()); - } - } - }).start(); + if (MapboxAccountManager.getInstance() != null) { + setAccessToken(mDefaultFileSourcePtr, MapboxAccountManager.getInstance().getAccessToken()); } - public static synchronized OfflineManager getInstance(Context context) { - if (instance == null) { - instance = new OfflineManager(context); - } + // Delete any existing previous ambient cache database + deleteAmbientDatabase(context); + } + + public static String getDatabasePath(Context context) { + // Default value + boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL; + + try { + // Try getting a custom value from the app Manifest + ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( + context.getPackageName(), PackageManager.GET_META_DATA); + setStorageExternal = appInfo.metaData.getBoolean( + MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL, + MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL); + } catch (PackageManager.NameNotFoundException nameNotFoundException) { + Timber.e("Failed to read the package metadata: " + nameNotFoundException.getMessage()); + } catch (Exception exception) { + Timber.e("Failed to read the storage key: " + exception.getMessage()); + } - return instance; + String databasePath = null; + if (setStorageExternal && isExternalStorageReadable()) { + try { + // Try getting the external storage path + databasePath = context.getExternalFilesDir(null).getAbsolutePath(); + } catch (NullPointerException nullPointerException) { + Timber.e("Failed to obtain the external storage path: " + nullPointerException.getMessage()); + } } - /** - * Access token getter/setter - * - * @param accessToken the accessToken to be used by the offline manager. - * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#start(Context, String)} ()} - */ - @Deprecated - public void setAccessToken(String accessToken) { - setAccessToken(mDefaultFileSourcePtr, accessToken); + if (databasePath == null) { + // Default to internal storage + databasePath = context.getFilesDir().getAbsolutePath(); } - /** - * Get Access Token - * - * @return Access Token - * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()} - */ - @Deprecated - public String getAccessToken() { - return getAccessToken(mDefaultFileSourcePtr); + return databasePath; + } + + /** + * Checks if external storage is available to at least read. In order for this to work, make + * sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + * (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest. + * <p> + * Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal + * </p> + * + * @return true if external storage is readable + */ + public static boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + return true; } - private Handler getHandler() { - if (handler == null) { - handler = new Handler(Looper.getMainLooper()); + Timber.w("External storage was requested but it isn't readable. For API level < 18" + + " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE" + + " permissions in your app Manifest (defaulting to internal storage)."); + + return false; + } + + private void deleteAmbientDatabase(final Context context) { + // Delete the file in a separate thread to avoid affecting the UI + new Thread(new Runnable() { + @Override + public void run() { + try { + String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db"; + File file = new File(path); + if (file.exists()) { + file.delete(); + Timber.d("Old ambient cache database deleted to save space: " + path); + } + } catch (Exception exception) { + Timber.e("Failed to delete old ambient cache database: " + exception.getMessage()); } + } + }).start(); + } - return handler; + public static synchronized OfflineManager getInstance(Context context) { + if (instance == null) { + instance = new OfflineManager(context); } - - /** - * Retrieve all regions in the offline database. - * <p> - * The query will be executed asynchronously and the results passed to the given - * callback on the main thread. - * </p> - * - * @param callback the callback to be invoked - */ - public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) { - listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() { - @Override - public void onList(final OfflineRegion[] offlineRegions) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onList(offlineRegions); - } - }); - } - - @Override - public void onError(final String error) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onError(error); - } - }); - } - }); + return instance; + } + + /** + * Access token getter/setter + * + * @param accessToken the accessToken to be used by the offline manager. + * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#start(Context, String)} ()} + */ + @Deprecated + public void setAccessToken(String accessToken) { + setAccessToken(mDefaultFileSourcePtr, accessToken); + } + + /** + * Get Access Token + * + * @return Access Token + * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()} + */ + @Deprecated + public String getAccessToken() { + return getAccessToken(mDefaultFileSourcePtr); + } + + private Handler getHandler() { + if (handler == null) { + handler = new Handler(Looper.getMainLooper()); } - /** - * Create an offline region in the database. - * <p> - * When the initial database queries have completed, the provided callback will be - * executed on the main thread. - * </p> - * <p> - * Note that the resulting region will be in an inactive download state; to begin - * downloading resources, call `OfflineRegion.setDownloadState(DownloadState.STATE_ACTIVE)`, - * optionally registering an `OfflineRegionObserver` beforehand. - * </p> - * - * @param definition the offline region definition - * @param metadata the metadata in bytes - * @param callback the callback to be invoked - */ - public void createOfflineRegion( - @NonNull OfflineRegionDefinition definition, - @NonNull byte[] metadata, - @NonNull final CreateOfflineRegionCallback callback) { - - createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() { - @Override - public void onCreate(final OfflineRegion offlineRegion) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onCreate(offlineRegion); - } - }); - } - - @Override - public void onError(final String error) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onError(error); - } - }); - } + return handler; + } + + /** + * Retrieve all regions in the offline database. + * <p> + * The query will be executed asynchronously and the results passed to the given + * callback on the main thread. + * </p> + * + * @param callback the callback to be invoked + */ + public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) { + listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() { + @Override + public void onList(final OfflineRegion[] offlineRegions) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onList(offlineRegions); + } }); - } + } + + @Override + public void onError(final String error) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } + }); + } + }); + } + + /** + * Create an offline region in the database. + * <p> + * When the initial database queries have completed, the provided callback will be + * executed on the main thread. + * </p> + * <p> + * Note that the resulting region will be in an inactive download state; to begin + * downloading resources, call `OfflineRegion.setDownloadState(DownloadState.STATE_ACTIVE)`, + * optionally registering an `OfflineRegionObserver` beforehand. + * </p> + * + * @param definition the offline region definition + * @param metadata the metadata in bytes + * @param callback the callback to be invoked + */ + public void createOfflineRegion( + @NonNull OfflineRegionDefinition definition, + @NonNull byte[] metadata, + @NonNull final CreateOfflineRegionCallback callback) { + + createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() { + @Override + public void onCreate(final OfflineRegion offlineRegion) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onCreate(offlineRegion); + } + }); + } + + @Override + public void onError(final String error) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } + }); + } + }); + } - /* - * Changing or bypassing this limit without permission from Mapbox is prohibited - * by the Mapbox Terms of Service. - */ - public void setOfflineMapboxTileCountLimit(long limit) { - setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit); - } + /* + * Changing or bypassing this limit without permission from Mapbox is prohibited + * by the Mapbox Terms of Service. + */ + public void setOfflineMapboxTileCountLimit(long limit) { + setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit); + } - /* - * Native methods - */ + /* + * Native methods + */ - private native long createDefaultFileSource( - String cachePath, String assetRoot, long maximumCacheSize); + private native long createDefaultFileSource( + String cachePath, String assetRoot, long maximumCacheSize); - private native void setAccessToken(long defaultFileSourcePtr, String accessToken); + private native void setAccessToken(long defaultFileSourcePtr, String accessToken); - private native String getAccessToken(long defaultFileSourcePtr); + private native String getAccessToken(long defaultFileSourcePtr); - private native void listOfflineRegions( - long defaultFileSourcePtr, ListOfflineRegionsCallback callback); + private native void listOfflineRegions( + long defaultFileSourcePtr, ListOfflineRegionsCallback callback); - private native void createOfflineRegion( - long defaultFileSourcePtr, OfflineRegionDefinition definition, - byte[] metadata, CreateOfflineRegionCallback callback); + private native void createOfflineRegion( + long defaultFileSourcePtr, OfflineRegionDefinition definition, + byte[] metadata, CreateOfflineRegionCallback callback); - private native void setOfflineMapboxTileCountLimit( - long defaultFileSourcePtr, long limit); + private native void setOfflineMapboxTileCountLimit( + long defaultFileSourcePtr, long limit); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index 0dcd34b6e6..a4d8a646d3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -4,6 +4,7 @@ import android.os.Handler; import android.os.Looper; import android.support.annotation.IntDef; import android.support.annotation.NonNull; + import timber.log.Timber; import java.lang.annotation.Retention; @@ -16,414 +17,418 @@ import java.lang.annotation.RetentionPolicy; */ public class OfflineRegion { - // - // Static methods - // + // + // Static methods + // - static { - System.loadLibrary("mapbox-gl"); - } + static { + System.loadLibrary("mapbox-gl"); + } - // Parent OfflineManager - private OfflineManager offlineManager; + // Parent OfflineManager + private OfflineManager offlineManager; - // Members - private long mId = 0; - private OfflineRegionDefinition mDefinition = null; + // Members + private long mId = 0; + private OfflineRegionDefinition mDefinition = null; - /** - * Arbitrary binary region metadata. The contents are opaque to the SDK implementation; - * it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp - * for a sample implementation that uses JSON to store an offline region name. - */ - private byte[] mMetadata = null; + /** + * Arbitrary binary region metadata. The contents are opaque to the SDK implementation; + * it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp + * for a sample implementation that uses JSON to store an offline region name. + */ + private byte[] mMetadata = null; - // Holds the pointer to JNI OfflineRegion - private long mOfflineRegionPtr = 0; + // Holds the pointer to JNI OfflineRegion + private long mOfflineRegionPtr = 0; - // Makes sure callbacks come back to the main thread - private Handler handler; + // Makes sure callbacks come back to the main thread + private Handler handler; + /** + * A region can have a single observer, which gets notified whenever a change + * to the region's status occurs. + */ + public interface OfflineRegionObserver { /** - * A region can have a single observer, which gets notified whenever a change - * to the region's status occurs. + * Implement this method to be notified of a change in the status of an + * offline region. Status changes include any change in state of the members + * of OfflineRegionStatus. + * <p> + * This method will be executed on the main thread. + * </p> + * + * @param status the changed status */ - public interface OfflineRegionObserver { - /** - * Implement this method to be notified of a change in the status of an - * offline region. Status changes include any change in state of the members - * of OfflineRegionStatus. - * <p> - * This method will be executed on the main thread. - * </p> - * - * @param status the changed status - */ - void onStatusChanged(OfflineRegionStatus status); - - /** - * Implement this method to be notified of errors encountered while downloading - * regional resources. Such errors may be recoverable; for example the implementation - * will attempt to re-request failed resources based on an exponential backoff - * algorithm, or when it detects that network access has been restored. - * <p> - * This method will be executed on the main thread. - * </p> - * - * @param error the offline region error message - */ - void onError(OfflineRegionError error); - - /* - * Implement this method to be notified when the limit on the number of Mapbox - * tiles stored for offline regions has been reached. - * - * Once the limit has been reached, the SDK will not download further offline - * tiles from Mapbox APIs until existing tiles have been removed. Contact your - * Mapbox sales representative to raise the limit. - * - * This limit does not apply to non-Mapbox tile sources. - * - * This method will be executed on the main thread. - */ - void mapboxTileCountLimitExceeded(long limit); - } + void onStatusChanged(OfflineRegionStatus status); /** - * This callback receives an asynchronous response containing the {@link OfflineRegionStatus} - * of the offline region, or a {@link String} error message otherwise. + * Implement this method to be notified of errors encountered while downloading + * regional resources. Such errors may be recoverable; for example the implementation + * will attempt to re-request failed resources based on an exponential backoff + * algorithm, or when it detects that network access has been restored. + * <p> + * This method will be executed on the main thread. + * </p> + * + * @param error the offline region error message */ - public interface OfflineRegionStatusCallback { - /** - * Receives the status - * - * @param status the offline region status - */ - void onStatus(OfflineRegionStatus status); - - /** - * Receives the error message - * - * @param error the error message - */ - void onError(String error); - } + void onError(OfflineRegionError error); + /* + * Implement this method to be notified when the limit on the number of Mapbox + * tiles stored for offline regions has been reached. + * + * Once the limit has been reached, the SDK will not download further offline + * tiles from Mapbox APIs until existing tiles have been removed. Contact your + * Mapbox sales representative to raise the limit. + * + * This limit does not apply to non-Mapbox tile sources. + * + * This method will be executed on the main thread. + */ + void mapboxTileCountLimitExceeded(long limit); + } + + /** + * This callback receives an asynchronous response containing the {@link OfflineRegionStatus} + * of the offline region, or a {@link String} error message otherwise. + */ + public interface OfflineRegionStatusCallback { /** - * This callback receives an asynchronous response containing a notification when - * an offline region has been deleted, or a {@link String} error message otherwise. + * Receives the status + * + * @param status the offline region status */ - public interface OfflineRegionDeleteCallback { - /** - * Receives the delete notification - */ - void onDelete(); - - /** - * Receives the error message - * - * @param error the error message - */ - void onError(String error); - } + void onStatus(OfflineRegionStatus status); /** - * This callback receives an asynchronous response containing the newly update - * OfflineMetadata in the database, or an error message otherwise. + * Receives the error message + * + * @param error the error message */ - public interface OfflineRegionUpdateMetadataCallback { - /** - * Receives the newly update offline region metadata. - * - * @param metadata the offline metadata to u[date - */ - void onUpdate(byte[] metadata); - - /** - * Receives the error message. - * - * @param error the error message to be shown - */ - void onError(String error); - } - + void onError(String error); + } + + /** + * This callback receives an asynchronous response containing a notification when + * an offline region has been deleted, or a {@link String} error message otherwise. + */ + public interface OfflineRegionDeleteCallback { /** - * A region is either inactive (not downloading, but previously-downloaded - * resources are available for use), or active (resources are being downloaded - * or will be downloaded, if necessary, when network access is available). - * <p> - * This state is independent of whether or not the complete set of resources - * is currently available for offline use. To check if that is the case, use - * `OfflineRegionStatus.isComplete()`. - * </p> + * Receives the delete notification */ - - @IntDef({STATE_INACTIVE, STATE_ACTIVE}) - @Retention(RetentionPolicy.SOURCE) - public @interface DownloadState { - } - - public static final int STATE_INACTIVE = 0; - public static final int STATE_ACTIVE = 1; - - // Keep track of the region state - private int state = STATE_INACTIVE; - - private boolean deliverInactiveMessages = false; + void onDelete(); /** - * Gets whether or not the `OfflineRegionObserver` will continue to deliver messages even if - * the region state has been set as STATE_INACTIVE. + * Receives the error message * - * @return true if delivering inactive messages + * @param error the error message */ - public boolean isDeliveringInactiveMessages() { - return deliverInactiveMessages; - } + void onError(String error); + } + + /** + * This callback receives an asynchronous response containing the newly update + * OfflineMetadata in the database, or an error message otherwise. + */ + public interface OfflineRegionUpdateMetadataCallback { + /** + * Receives the newly update offline region metadata. + * + * @param metadata the offline metadata to u[date + */ + void onUpdate(byte[] metadata); /** - * When set true, the `OfflineRegionObserver` will continue to deliver messages even if - * the region state has been set as STATE_INACTIVE (operations happen asynchronously). If set - * false, the client won't be notified of further messages. + * Receives the error message. * - * @param deliverInactiveMessages true if it should deliver inactive messages + * @param error the error message to be shown */ - public void setDeliverInactiveMessages(boolean deliverInactiveMessages) { - this.deliverInactiveMessages = deliverInactiveMessages; + void onError(String error); + } + + /** + * A region is either inactive (not downloading, but previously-downloaded + * resources are available for use), or active (resources are being downloaded + * or will be downloaded, if necessary, when network access is available). + * <p> + * This state is independent of whether or not the complete set of resources + * is currently available for offline use. To check if that is the case, use + * `OfflineRegionStatus.isComplete()`. + * </p> + */ + + @IntDef( {STATE_INACTIVE, STATE_ACTIVE}) + @Retention(RetentionPolicy.SOURCE) + public @interface DownloadState { + } + + public static final int STATE_INACTIVE = 0; + public static final int STATE_ACTIVE = 1; + + // Keep track of the region state + private int state = STATE_INACTIVE; + + private boolean deliverInactiveMessages = false; + + /** + * Gets whether or not the `OfflineRegionObserver` will continue to deliver messages even if + * the region state has been set as STATE_INACTIVE. + * + * @return true if delivering inactive messages + */ + public boolean isDeliveringInactiveMessages() { + return deliverInactiveMessages; + } + + /** + * When set true, the `OfflineRegionObserver` will continue to deliver messages even if + * the region state has been set as STATE_INACTIVE (operations happen asynchronously). If set + * false, the client won't be notified of further messages. + * + * @param deliverInactiveMessages true if it should deliver inactive messages + */ + public void setDeliverInactiveMessages(boolean deliverInactiveMessages) { + this.deliverInactiveMessages = deliverInactiveMessages; + } + + private boolean deliverMessages() { + if (state == STATE_ACTIVE) { + return true; } - - private boolean deliverMessages() { - if (state == STATE_ACTIVE) return true; - if (isDeliveringInactiveMessages()) return true; - return false; + if (isDeliveringInactiveMessages()) { + return true; } + return false; + } - /* - * Constructor - */ + /* + * Constructor + */ - private OfflineRegion() { - // For JNI use only, to create a new offline region, use - // OfflineManager.createOfflineRegion() instead. - } + private OfflineRegion() { + // For JNI use only, to create a new offline region, use + // OfflineManager.createOfflineRegion() instead. + } - /* - * Getters - */ + /* + * Getters + */ - public long getID() { - return mId; - } - - public OfflineRegionDefinition getDefinition() { - return mDefinition; - } + public long getID() { + return mId; + } - public byte[] getMetadata() { - return mMetadata; - } + public OfflineRegionDefinition getDefinition() { + return mDefinition; + } - private Handler getHandler() { - if (handler == null) { - handler = new Handler(Looper.getMainLooper()); - } + public byte[] getMetadata() { + return mMetadata; + } - return handler; + private Handler getHandler() { + if (handler == null) { + handler = new Handler(Looper.getMainLooper()); } - /** - * Register an observer to be notified when the state of the region changes. - * - * @param observer the observer to be notified - */ - public void setObserver(@NonNull final OfflineRegionObserver observer) { - setOfflineRegionObserver(new OfflineRegionObserver() { + return handler; + } + + /** + * Register an observer to be notified when the state of the region changes. + * + * @param observer the observer to be notified + */ + public void setObserver(@NonNull final OfflineRegionObserver observer) { + setOfflineRegionObserver(new OfflineRegionObserver() { + @Override + public void onStatusChanged(final OfflineRegionStatus status) { + if (deliverMessages()) { + getHandler().post(new Runnable() { @Override - public void onStatusChanged(final OfflineRegionStatus status) { - if (deliverMessages()) { - getHandler().post(new Runnable() { - @Override - public void run() { - observer.onStatusChanged(status); - } - }); - } + public void run() { + observer.onStatusChanged(status); } + }); + } + } + @Override + public void onError(final OfflineRegionError error) { + if (deliverMessages()) { + getHandler().post(new Runnable() { @Override - public void onError(final OfflineRegionError error) { - if (deliverMessages()) { - getHandler().post(new Runnable() { - @Override - public void run() { - observer.onError(error); - } - }); - } + public void run() { + observer.onError(error); } + }); + } + } + @Override + public void mapboxTileCountLimitExceeded(final long limit) { + if (deliverMessages()) { + getHandler().post(new Runnable() { @Override - public void mapboxTileCountLimitExceeded(final long limit) { - if (deliverMessages()) { - getHandler().post(new Runnable() { - @Override - public void run() { - observer.mapboxTileCountLimitExceeded(limit); - } - }); - } + public void run() { + observer.mapboxTileCountLimitExceeded(limit); } + }); + } + } + }); + } + + /** + * Pause or resume downloading of regional resources. + * + * @param state the download state + */ + public void setDownloadState(@DownloadState int state) { + this.state = state; + setOfflineRegionDownloadState(state); + } + + /** + * Retrieve the current status of the region. The query will be executed + * asynchronously and the results passed to the given callback which will be + * executed on the main thread. + * + * @param callback the callback to invoked. + */ + public void getStatus(@NonNull final OfflineRegionStatusCallback callback) { + getOfflineRegionStatus(new OfflineRegionStatusCallback() { + @Override + public void onStatus(final OfflineRegionStatus status) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onStatus(status); + } }); - } - - /** - * Pause or resume downloading of regional resources. - * - * @param state the download state - */ - public void setDownloadState(@DownloadState int state) { - this.state = state; - setOfflineRegionDownloadState(state); - } - - /** - * Retrieve the current status of the region. The query will be executed - * asynchronously and the results passed to the given callback which will be - * executed on the main thread. - * - * @param callback the callback to invoked. - */ - public void getStatus(@NonNull final OfflineRegionStatusCallback callback) { - getOfflineRegionStatus(new OfflineRegionStatusCallback() { - @Override - public void onStatus(final OfflineRegionStatus status) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onStatus(status); - } - }); - } - - @Override - public void onError(final String error) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onError(error); - } - }); - } + } + + @Override + public void onError(final String error) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } }); - } - - /** - * Remove an offline region from the database and perform any resources evictions - * necessary as a result. - * <p> - * Eviction works by removing the least-recently requested resources not also required - * by other regions, until the database shrinks below a certain size. - * </p> - * <p> - * When the operation is complete or encounters an error, the given callback will be - * executed on the main thread. - * </p> - * <p> - * After you call this method, you may not call any additional methods on this object. - * </p> - * - * @param callback the callback to be invoked - */ - public void delete(@NonNull final OfflineRegionDeleteCallback callback) { - deleteOfflineRegion(new OfflineRegionDeleteCallback() { - @Override - public void onDelete() { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onDelete(); - OfflineRegion.this.finalize(); - } - }); - } - - @Override - public void onError(final String error) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onError(error); - } - }); - } + } + }); + } + + /** + * Remove an offline region from the database and perform any resources evictions + * necessary as a result. + * <p> + * Eviction works by removing the least-recently requested resources not also required + * by other regions, until the database shrinks below a certain size. + * </p> + * <p> + * When the operation is complete or encounters an error, the given callback will be + * executed on the main thread. + * </p> + * <p> + * After you call this method, you may not call any additional methods on this object. + * </p> + * + * @param callback the callback to be invoked + */ + public void delete(@NonNull final OfflineRegionDeleteCallback callback) { + deleteOfflineRegion(new OfflineRegionDeleteCallback() { + @Override + public void onDelete() { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onDelete(); + OfflineRegion.this.finalize(); + } }); - } - - /** - * Update an offline region metadata from the database. - * <p> - * When the operation is complete or encounters an error, the given callback will be - * executed on the main thread. - * </p> - * <p> - * After you call this method, you may not call any additional methods on this object. - * </p> - * - * @param callback the callback to be invoked - */ - public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) { - updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() { - @Override - public void onUpdate(final byte[] metadata) { - getHandler().post(new Runnable() { - @Override - public void run() { - mMetadata = metadata; - callback.onUpdate(metadata); - } - }); - } - - @Override - public void onError(final String error) { - getHandler().post(new Runnable() { - @Override - public void run() { - callback.onError(error); - } - }); - } + } + + @Override + public void onError(final String error) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } }); + } + }); + } + + /** + * Update an offline region metadata from the database. + * <p> + * When the operation is complete or encounters an error, the given callback will be + * executed on the main thread. + * </p> + * <p> + * After you call this method, you may not call any additional methods on this object. + * </p> + * + * @param callback the callback to be invoked + */ + public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) { + updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() { + @Override + public void onUpdate(final byte[] metadata) { + getHandler().post(new Runnable() { + @Override + public void run() { + mMetadata = metadata; + callback.onUpdate(metadata); + } + }); + } + + @Override + public void onError(final String error) { + getHandler().post(new Runnable() { + @Override + public void run() { + callback.onError(error); + } + }); + } + }); + } + + @Override + protected void finalize() { + try { + super.finalize(); + destroyOfflineRegion(); + } catch (Throwable throwable) { + Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage()); } + } - @Override - protected void finalize() { - try { - super.finalize(); - destroyOfflineRegion(); - } catch (Throwable throwable) { - Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage()); - } - } - - /* - * Native methods - */ + /* + * Native methods + */ - private native void destroyOfflineRegion(); + private native void destroyOfflineRegion(); - private native void setOfflineRegionObserver( - OfflineRegionObserver observerCallback); + private native void setOfflineRegionObserver( + OfflineRegionObserver observerCallback); - private native void setOfflineRegionDownloadState( - @DownloadState int offlineRegionDownloadState); + private native void setOfflineRegionDownloadState( + @DownloadState int offlineRegionDownloadState); - private native void getOfflineRegionStatus( - OfflineRegionStatusCallback statusCallback); + private native void getOfflineRegionStatus( + OfflineRegionStatusCallback statusCallback); - private native void deleteOfflineRegion( - OfflineRegionDeleteCallback deleteCallback); + private native void deleteOfflineRegion( + OfflineRegionDeleteCallback deleteCallback); - private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback); + private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java index 0e7fb38e1c..a21ff0a443 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java @@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.offline; /** * This is the interface that all Offline Region definitions have to implement. - * + * <p> * For the present, a tile pyramid is the only type of offline region. */ public interface OfflineRegionDefinition { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java index e7a57379c5..60c4a8661c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java @@ -10,44 +10,47 @@ import java.lang.annotation.RetentionPolicy; */ public class OfflineRegionError { - /** - * Error code, as a string, self-explanatory. - */ - @StringDef({REASON_SUCCESS, REASON_NOT_FOUND, REASON_SERVER, REASON_CONNECTION, REASON_OTHER}) - @Retention(RetentionPolicy.SOURCE) - public @interface ErrorReason {} - - public static final String REASON_SUCCESS = "REASON_SUCCESS"; - public static final String REASON_NOT_FOUND = "REASON_NOT_FOUND"; - public static final String REASON_SERVER = "REASON_SERVER"; - public static final String REASON_CONNECTION = "REASON_CONNECTION"; - public static final String REASON_OTHER = "REASON_OTHER"; - - private @ErrorReason String reason; - - /** - /* An error message from the request handler, e.g. a server message or a system message - /* informing the user about the reason for the failure. - */ - private String message; - - /* - * Constructors - */ - - private OfflineRegionError() { - // For JNI use only - } - - /* - * Getters - */ - - public @ErrorReason String getReason() { - return reason; - } - - public String getMessage() { - return message; - } + /** + * Error code, as a string, self-explanatory. + */ + @StringDef( {REASON_SUCCESS, REASON_NOT_FOUND, REASON_SERVER, REASON_CONNECTION, REASON_OTHER}) + @Retention(RetentionPolicy.SOURCE) + public @interface ErrorReason { + } + + public static final String REASON_SUCCESS = "REASON_SUCCESS"; + public static final String REASON_NOT_FOUND = "REASON_NOT_FOUND"; + public static final String REASON_SERVER = "REASON_SERVER"; + public static final String REASON_CONNECTION = "REASON_CONNECTION"; + public static final String REASON_OTHER = "REASON_OTHER"; + + @ErrorReason + private String reason; + + /** + * /* An error message from the request handler, e.g. a server message or a system message + * /* informing the user about the reason for the failure. + */ + private String message; + + /* + * Constructors + */ + + private OfflineRegionError() { + // For JNI use only + } + + /* + * Getters + */ + + @ErrorReason + public String getReason() { + return reason; + } + + public String getMessage() { + return message; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java index 48609a13bb..11f2da132d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java @@ -4,101 +4,103 @@ package com.mapbox.mapboxsdk.offline; * A region's status includes its active/inactive state as well as counts * of the number of resources that have completed downloading, their total * size in bytes, and the total number of resources that are required. - * + * <p> * Note that the total required size in bytes is not currently available. A * future API release may provide an estimate of this number. */ public class OfflineRegionStatus { - @OfflineRegion.DownloadState private int downloadState = OfflineRegion.STATE_INACTIVE; - - /** - * The number of resources (inclusive of tiles) that have been fully downloaded - * and are ready for offline access. - */ - private long completedResourceCount = 0; - - /** - * The cumulative size, in bytes, of all resources (inclusive of tiles) that have - * been fully downloaded. - */ - private long completedResourceSize = 0; - - /** - * The number of tiles that have been fully downloaded and are ready for - * offline access. - */ - private long completedTileCount = 0; - - /** - * The cumulative size, in bytes, of all tiles that have been fully downloaded. - */ - private long completedTileSize = 0; - - /** - * The number of resources that are known to be required for this region. See the - * documentation for `requiredResourceCountIsPrecise` for an important caveat - * about this number. - */ - private long requiredResourceCount = 0; - - /** - * This property is true when the value of requiredResourceCount is a precise - * count of the number of required resources, and false when it is merely a lower - * bound. - * - * Specifically, it is false during early phases of an offline download. Once - * style and tile sources have been downloaded, it is possible to calculate the - * precise number of required resources, at which point it is set to true. - */ - private boolean requiredResourceCountIsPrecise = true; - - /* - * Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object. - */ - - private OfflineRegionStatus() { - // For JNI use only - } - - /* - * Is the region complete? - */ - - public boolean isComplete() { - return (completedResourceCount == requiredResourceCount); - } - - /* - * Getters - */ - - public @OfflineRegion.DownloadState int getDownloadState() { - return downloadState; - } - - public long getCompletedResourceCount() { - return completedResourceCount; - } - - public long getCompletedResourceSize() { - return completedResourceSize; - } - - public long getCompletedTileCount() { - return completedTileCount; - } - - public long getCompletedTileSize() { - return completedTileSize; - } - - public long getRequiredResourceCount() { - return requiredResourceCount; - } - - public boolean isRequiredResourceCountPrecise() { - return requiredResourceCountIsPrecise; - } + @OfflineRegion.DownloadState + private int downloadState = OfflineRegion.STATE_INACTIVE; + + /** + * The number of resources (inclusive of tiles) that have been fully downloaded + * and are ready for offline access. + */ + private long completedResourceCount = 0; + + /** + * The cumulative size, in bytes, of all resources (inclusive of tiles) that have + * been fully downloaded. + */ + private long completedResourceSize = 0; + + /** + * The number of tiles that have been fully downloaded and are ready for + * offline access. + */ + private long completedTileCount = 0; + + /** + * The cumulative size, in bytes, of all tiles that have been fully downloaded. + */ + private long completedTileSize = 0; + + /** + * The number of resources that are known to be required for this region. See the + * documentation for `requiredResourceCountIsPrecise` for an important caveat + * about this number. + */ + private long requiredResourceCount = 0; + + /** + * This property is true when the value of requiredResourceCount is a precise + * count of the number of required resources, and false when it is merely a lower + * bound. + * <p> + * Specifically, it is false during early phases of an offline download. Once + * style and tile sources have been downloaded, it is possible to calculate the + * precise number of required resources, at which point it is set to true. + */ + private boolean requiredResourceCountIsPrecise = true; + + /* + * Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object. + */ + + private OfflineRegionStatus() { + // For JNI use only + } + + /* + * Is the region complete? + */ + + public boolean isComplete() { + return (completedResourceCount == requiredResourceCount); + } + + /* + * Getters + */ + + @OfflineRegion.DownloadState + public int getDownloadState() { + return downloadState; + } + + public long getCompletedResourceCount() { + return completedResourceCount; + } + + public long getCompletedResourceSize() { + return completedResourceSize; + } + + public long getCompletedTileCount() { + return completedTileCount; + } + + public long getCompletedTileSize() { + return completedTileSize; + } + + public long getRequiredResourceCount() { + return requiredResourceCount; + } + + public boolean isRequiredResourceCountPrecise() { + return requiredResourceCountIsPrecise; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java index 5a0be6b33f..5fc844afe5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java @@ -5,61 +5,61 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds; /** * An offline region defined by a style URL, geographic bounding box, zoom range, and * device pixel ratio. - * + * <p> * Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom. - * + * <p> * maxZoom may be ∞, in which case for each tile source, the region will include * tiles from minZoom up to the maximum zoom level provided by that source. - * + * <p> * pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0. */ public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefinition { - private String styleURL; - private LatLngBounds bounds; - private double minZoom; - private double maxZoom; - private float pixelRatio; + private String styleURL; + private LatLngBounds bounds; + private double minZoom; + private double maxZoom; + private float pixelRatio; - /* - * Constructors - */ + /* + * Constructors + */ - private OfflineTilePyramidRegionDefinition() { - // For JNI use only - } + private OfflineTilePyramidRegionDefinition() { + // For JNI use only + } - public OfflineTilePyramidRegionDefinition( - String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) { - this.styleURL = styleURL; - this.bounds = bounds; - this.minZoom = minZoom; - this.maxZoom = maxZoom; - this.pixelRatio = pixelRatio; - } + public OfflineTilePyramidRegionDefinition( + String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) { + this.styleURL = styleURL; + this.bounds = bounds; + this.minZoom = minZoom; + this.maxZoom = maxZoom; + this.pixelRatio = pixelRatio; + } - /* - * Getters - */ + /* + * Getters + */ - public String getStyleURL() { - return styleURL; - } + public String getStyleURL() { + return styleURL; + } - public LatLngBounds getBounds() { - return bounds; - } + public LatLngBounds getBounds() { + return bounds; + } - public double getMinZoom() { - return minZoom; - } + public double getMinZoom() { + return minZoom; + } - public double getMaxZoom() { - return maxZoom; - } + public double getMaxZoom() { + return maxZoom; + } - public float getPixelRatio() { - return pixelRatio; - } + public float getPixelRatio() { + return pixelRatio; + } } |