diff options
author | Antonio Zugaldia <antonio@mapbox.com> | 2016-02-17 10:55:12 -0500 |
---|---|---|
committer | Antonio Zugaldia <antonio@mapbox.com> | 2016-02-26 09:13:17 -0500 |
commit | 01e55f183e4468d040e7b144536ca592c9b64cb5 (patch) | |
tree | f448bd208c3b43650ae5aa3918090f298d708fbf /platform/android/MapboxGLAndroidSDK | |
parent | f683b10e106e7376322b9c67c2baf57f5022cec2 (diff) | |
download | qtlocation-mapboxgl-01e55f183e4468d040e7b144536ca592c9b64cb5.tar.gz |
# This is a combination of 8 commits.
# The first commit's message is:
# This is a combination of 2 commits.
# The first commit's message is:
# This is a combination of 3 commits.
# The first commit's message is:
# This is a combination of 2 commits.
# The first commit's message is:
# This is a combination of 21 commits.
# The first commit's message is:
[android] - Implements Android bindings for offline API
Fixes #3891
# The 2nd commit message will be skipped:
# [android] #3891 - rename OFFLINE_MAX_CACHE_SIZE to DEFAULT_MAX_CACHE_SIZE and adjust value
# The 3rd commit message will be skipped:
# [android] #3891 - makes de documentation more relevant to the current android implementation
# The 4th commit message will be skipped:
# [android] #3891 - rename isRequiredResourceCountIsIndeterminate() to isRequiredResourceCountPrecise()
# The 5th commit message will be skipped:
# [android] #3891 - rename complete() to isComplete()
# The 6th commit message will be skipped:
# [android] #3891 - rename OfflineRegionDefinition to OfflineTilePyramidRegionDefinition and make OfflineRegionDefinition an interface. Docs for corresponding classes updated.
# The 7th commit message will be skipped:
# [android] #3891 - make reason a more idiomatic ErrorReason Android IntDef and remove unnecessary constructor
# The 8th commit message will be skipped:
# [android] #3891 - reuse the calling object instead of creating a new manager
# The 9th commit message will be skipped:
# [android] #3891 - location, location, location
# The 10th commit message will be skipped:
# [android] #3891 - simpler list regions iteration
# The 11th commit message will be skipped:
# [android] #3891 - proper indeterminate -> precise transition
# The 12th commit message will be skipped:
# [android] #3891 - improve description for DEFAULT_MAX_CACHE_SIZE
# The 13th commit message will be skipped:
# [android] #3891 - delete global refs for obj and listCallback
# The 14th commit message will be skipped:
# [android] #3891 - simplify metadata conversion and fix metadata object
# The 15th commit message will be skipped:
# [android] - Implements Android bindings for offline API
# Fixes #3891
# The 16th commit message will be skipped:
# [android] #3891 - avoid exposing the int reason value in the public API
# The 17th commit message will be skipped:
# [android] #3891 - delete global refs for remaining callbacks and observer
# The 18th commit message will be skipped:
# [android] #3891 - remove unused offlineManagerClassConstructorId together with unnecessary private java constructor
# The 19th commit message will be skipped:
# [android] #3891 - remove non-relevant line
# The 20th commit message will be skipped:
# [android] #3891 - handle requiredResourceCountIsIndeterminate -> requiredResourceCountIsPrecise rename
# The 21st commit message will be skipped:
# [android] #3891 - revert map changes to allow rebase
# The 2nd commit message will be skipped:
# [android] #3891 - avoid exposing the int reason value in the public API
# The 2nd commit message will be skipped:
# [android] #3891 - rename complete() to isComplete()
# The 3rd commit message will be skipped:
# [android] #3891 - rename OfflineRegionDefinition to OfflineTilePyramidRegionDefinition and make OfflineRegionDefinition an interface. Docs for corresponding classes updated.
# The 2nd commit message will be skipped:
# [android] #3891 - location, location, location
# The 2nd commit message will be skipped:
# [android] #3891 - improve description for DEFAULT_MAX_CACHE_SIZE
# The 3rd commit message will be skipped:
# [android] #3891 - delete global refs for obj and listCallback
# The 4th commit message will be skipped:
# [android] #3891 - simplify metadata conversion and fix metadata object
# The 5th commit message will be skipped:
# [android] #3891 - delete global refs for remaining callbacks and observer
# The 6th commit message will be skipped:
# [android] #3891 - remove unused offlineManagerClassConstructorId together with unnecessary private java constructor
# The 7th commit message will be skipped:
# [android] #3891 - remove non-relevant line
# The 8th commit message will be skipped:
# [android] #3891 - handle requiredResourceCountIsIndeterminate -> requiredResourceCountIsPrecise rename
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK')
9 files changed, 766 insertions, 4 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 0c2690aec1..6b213bb655 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -620,11 +620,26 @@ public class MapView extends FrameLayout { // Zoom // - double getZoom() { + /** + * Returns the current zoom level of the map view. + * + * @return The current zoom. + */ + @UiThread + @FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) + public double getZoom() { return mNativeMapView.getZoom(); } - void setMinZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) { + /** + * <p> + * Sets the minimum zoom level the map can be displayed at. + * </p> + * + * @param minZoom The new minimum zoom level. + */ + @UiThread + public void setMinZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) { mNativeMapView.setMinZoom(minZoom); } @@ -640,7 +655,19 @@ public class MapView extends FrameLayout { return mNativeMapView.getMaxZoom(); } - void setZoomControlsEnabled(boolean enabled) { + /** + * <p> + * Sets whether the zoom controls are enabled. + * If enabled, the zoom controls are a pair of buttons + * (one for zooming in, one for zooming out) that appear on the screen. + * When pressed, they cause the camera to zoom in (or out) by one zoom level. + * If disabled, the zoom controls are not shown. + * </p> + * By default the zoom controls are enabled if the device is only single touch capable; + * + * @param enabled If true, the zoom controls are enabled. + */ + public void setZoomControlsEnabled(boolean enabled) { mZoomButtonsController.setVisible(enabled); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 6c9806f79b..9530096131 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -1,7 +1,6 @@ package com.mapbox.mapboxsdk.maps; import android.content.Context; - import android.location.Location; import android.os.Bundle; import android.os.SystemClock; 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 new file mode 100644 index 0000000000..b56ecfc057 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java @@ -0,0 +1,184 @@ +package com.mapbox.mapboxsdk.offline; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.NonNull; + +import java.io.File; + +/** + * The offline manager is the main entry point for offline-related functionality. + * It'll help you list and create offline regions. + */ +public class OfflineManager { + + // Default database name + private final static String OFFLINE_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; + + // Holds the pointer to JNI DefaultFileSource + private long mDefaultFileSourcePtr = 0; + + // Makes sure callbacks come back to the main thread + private Handler handler; + + // This object is implemented as a singleton + private static OfflineManager instance; + + /* + * Callbacks + */ + + public interface ListOfflineRegionsCallback { + void onList(OfflineRegion[] offlineRegions); + void onError(String error); + } + + public interface CreateOfflineRegionCallback { + void onCreate(OfflineRegion offlineRegion); + void onError(String error); + } + + /* + * Constructors + */ + + private OfflineManager(Context context) { + // Get a pointer to the DefaultFileSource instance + String assetRoot = context.getFilesDir().getAbsolutePath(); + String cachePath = assetRoot + File.separator + OFFLINE_DATABASE_NAME; + mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE); + } + + public static synchronized OfflineManager getInstance(Context context) { + if (instance == null) { + instance = new OfflineManager(context); + } + + return instance; + } + + /* + * Access token getter/setter + */ + public void setAccessToken(String accessToken) { + setAccessToken(mDefaultFileSourcePtr, accessToken); + } + + public String getAccessToken() { + return getAccessToken(mDefaultFileSourcePtr); + } + + private Handler getHandler() { + if (handler == null) { + handler = new Handler(Looper.getMainLooper()); + } + + return handler; + } + + /** + * Retrieve all regions in the offline database. + * + * The query will be executed asynchronously and the results passed to the given + * callback on the main thread. + */ + 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. + * + * When the initial database queries have completed, the provided callback will be + * executed on the main thread. + * + * 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. + */ + public void createOfflineRegion( + @NonNull OfflineRegionDefinition definition, + @NonNull OfflineRegionMetadata 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); + } + + + /* + * Native methods + */ + + private native long createDefaultFileSource( + String cachePath, String assetRoot, long maximumCacheSize); + + private native void setAccessToken(long defaultFileSourcePtr, String accessToken); + private native String getAccessToken(long defaultFileSourcePtr); + + private native void listOfflineRegions( + long defaultFileSourcePtr, ListOfflineRegionsCallback callback); + + private native void createOfflineRegion( + long defaultFileSourcePtr, OfflineRegionDefinition definition, + OfflineRegionMetadata metadata, CreateOfflineRegionCallback callback); + + 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 new file mode 100644 index 0000000000..9e518f1e6a --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -0,0 +1,278 @@ +package com.mapbox.mapboxsdk.offline; + +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.IntDef; +import android.support.annotation.NonNull; +import android.util.Log; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * To use offline maps on mobile, you will first have to create an offline region. + * Use OfflineManager.createOfflineRegion() to create a new offline region. + */ +public class OfflineRegion { + + private final static String LOG_TAG = "OfflineRegion"; + + // Parent OfflineManager + private OfflineManager offlineManager; + + // Members + private long mId = 0; + private OfflineRegionDefinition mDefinition = null; + private OfflineRegionMetadata mMetadata = null; + + // Holds the pointer to JNI OfflineRegion + private long mOfflineRegionPtr = 0; + + // 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 { + /** + * 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. + * + * This method will be executed on the main thread. + */ + 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. + * + * This method will be executed on the main thread. + */ + 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); + } + + /* + * Callbacks + */ + + public interface OfflineRegionStatusCallback { + void onStatus(OfflineRegionStatus status); + void onError(String error); + } + + public interface OfflineRegionDeleteCallback { + void onDelete(); + 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). + * + * 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()`. + */ + + @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; + + /* + * Constructor + */ + + private OfflineRegion() { + // For JNI use only, to create a new offline region, use + // OfflineManager.createOfflineRegion() instead. + } + + /* + * Getters + */ + + public long getID() { + return mId; + } + + public OfflineRegionDefinition getDefinition() { + return mDefinition; + } + + public OfflineRegionMetadata getMetadata() { + return mMetadata; + } + + private Handler getHandler() { + if (handler == null) { + handler = new Handler(Looper.getMainLooper()); + } + + return handler; + } + + /** + * Register an observer to be notified when the state of the region changes. + */ + public void setObserver(@NonNull final OfflineRegionObserver observer) { + setOfflineRegionObserver(this, new OfflineRegionObserver() { + @Override + public void onStatusChanged(final OfflineRegionStatus status) { + getHandler().post(new Runnable() { + @Override + public void run() { + observer.onStatusChanged(status); + } + }); + } + + @Override + public void onError(final OfflineRegionError error) { + getHandler().post(new Runnable() { + @Override + public void run() { + observer.onError(error); + } + }); + } + + @Override + public void mapboxTileCountLimitExceeded(final long limit) { + getHandler().post(new Runnable() { + @Override + public void run() { + observer.mapboxTileCountLimitExceeded(limit); + } + }); + } + }); + } + + /** + * Pause or resume downloading of regional resources. + */ + public void setDownloadState(@DownloadState int state) { + setOfflineRegionDownloadState(this, 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. + */ + public void getStatus(@NonNull final OfflineRegionStatusCallback callback) { + getOfflineRegionStatus(this, 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); + } + }); + } + }); + } + + /** + * Remove an offline region from the database and perform any resources evictions + * necessary as a result. + * + * Eviction works by removing the least-recently requested resources not also required + * by other regions, until the database shrinks below a certain size. + * + * When the operation is complete or encounters an error, the given callback will be + * executed on the main thread. + */ + public void delete(@NonNull final OfflineRegionDeleteCallback callback) { + deleteOfflineRegion(this, 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); + } + }); + } + }); + } + + @Override + protected void finalize() { + try { + super.finalize(); + destroyOfflineRegion(mOfflineRegionPtr); + mOfflineRegionPtr = 0; + } catch (Throwable throwable) { + Log.e(LOG_TAG, "Failed to finalize OfflineRegion: " + throwable.getMessage()); + } + } + + /* + * Native methods + */ + + private native void destroyOfflineRegion(long offlineRegionPtr); + + private native void setOfflineRegionObserver( + OfflineRegion offlineRegion, + OfflineRegionObserver observerCallback); + + private native void setOfflineRegionDownloadState( + OfflineRegion offlineRegion, + @DownloadState int offlineRegionDownloadState); + + private native void getOfflineRegionStatus( + OfflineRegion offlineRegion, + OfflineRegionStatusCallback statusCallback); + + private native void deleteOfflineRegion( + OfflineRegion offlineRegion, + OfflineRegionDeleteCallback deleteCallback); + +} 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 new file mode 100644 index 0000000000..0e7fb38e1c --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java @@ -0,0 +1,9 @@ +package com.mapbox.mapboxsdk.offline; + +/** + * This is the interface that all Offline Region definitions have to implement. + * + * 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 new file mode 100644 index 0000000000..e7a57379c5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java @@ -0,0 +1,53 @@ +package com.mapbox.mapboxsdk.offline; + +import android.support.annotation.StringDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * An Offline Region error + */ +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; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionMetadata.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionMetadata.java new file mode 100644 index 0000000000..bbea4580f8 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionMetadata.java @@ -0,0 +1,63 @@ +package com.mapbox.mapboxsdk.offline; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * Arbitrary binary region metadata. The contents are opaque to the SDK implementation; + * it just stores and retrieves a byte[]. + */ +public class OfflineRegionMetadata { + + private byte[] metadata; + + /* + * Constructor + */ + + public OfflineRegionMetadata(byte[] metadata) { + this.metadata = metadata; + } + + /* + * Getters and setters + */ + + public byte[] getMetadata() { + return metadata; + } + + public void setMetadata(byte[] metadata) { + this.metadata = metadata; + } + + /* + * Overrides + */ + + @Override + public String toString() { + return "OfflineRegionMetadata{metadata=" + metadata + "}"; + } + + /* + * byte[] utils + */ + + public static byte[] serialize(Object obj) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream os = new ObjectOutputStream(out); + os.writeObject(obj); + return out.toByteArray(); + } + + public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException { + ByteArrayInputStream in = new ByteArrayInputStream(data); + ObjectInputStream is = new ObjectInputStream(in); + return is.readObject(); + } + +} 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 new file mode 100644 index 0000000000..e65a20f18e --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java @@ -0,0 +1,84 @@ +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. + * + * 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 that have been fully downloaded and are ready for + * offline access. + */ + private long completedResourceCount = 0; + + /** + * The cumulative size, in bytes, of all resources that have been fully downloaded. + */ + private long completedResourceSize = 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 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 new file mode 100644 index 0000000000..5a0be6b33f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java @@ -0,0 +1,65 @@ +package com.mapbox.mapboxsdk.offline; + +import com.mapbox.mapboxsdk.geometry.LatLngBounds; + +/** + * An offline region defined by a style URL, geographic bounding box, zoom range, and + * device pixel ratio. + * + * Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom. + * + * 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. + * + * 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; + + /* + * Constructors + */ + + 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; + } + + /* + * Getters + */ + + public String getStyleURL() { + return styleURL; + } + + public LatLngBounds getBounds() { + return bounds; + } + + public double getMinZoom() { + return minZoom; + } + + public double getMaxZoom() { + return maxZoom; + } + + public float getPixelRatio() { + return pixelRatio; + } + +} |