[android] Adding builder pattern for LocationComponent activation (#13941)
* initial additions of activation builder * [android] refactoring LocationComponentActivationOptions based on code review * [android] initial addition of LocationComponentActivationOptionsTest unit tests * [android] more refactoring based on code review * [android] refactoring test app location examples * [android] espresso test refactor with LocationComponentActivationOptions usage * [android] locationComponent builder instrumentation test tweaks and log removal * [android] method and docs refactoring based @lukaspaczos 's review * [android] locationEngine setting logic refactor * [android] add null locationEngine to stillStaleAfterResuming test * added .locationEngine(null) to other tests * [android] javadocs, method, and test adjustments based on @lukaspaczos review * [android] test tweaks based on Lukasz review
This commit is contained in:
@@ -217,8 +217,10 @@ public final class LocationComponent {
|
||||
*
|
||||
* @param context the context
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style) {
|
||||
activateLocationComponent(context, style,
|
||||
LocationComponentOptions.createFromAttributes(context, R.style.mapbox_LocationComponent));
|
||||
@@ -232,8 +234,10 @@ public final class LocationComponent {
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param useDefaultLocationEngine true if you want to initialize and use the built-in location engine or false if
|
||||
* there should be no location engine initialized
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
boolean useDefaultLocationEngine) {
|
||||
if (useDefaultLocationEngine) {
|
||||
@@ -252,8 +256,10 @@ public final class LocationComponent {
|
||||
* @param useDefaultLocationEngine true if you want to initialize and use the built-in location engine or false if
|
||||
* there should be no location engine initialized
|
||||
* @param locationEngineRequest the location request
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
boolean useDefaultLocationEngine,
|
||||
@NonNull LocationEngineRequest locationEngineRequest) {
|
||||
@@ -275,8 +281,10 @@ public final class LocationComponent {
|
||||
* there should be no location engine initialized
|
||||
* @param locationEngineRequest the location request
|
||||
* @param options the options
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
boolean useDefaultLocationEngine,
|
||||
@NonNull LocationEngineRequest locationEngineRequest,
|
||||
@@ -298,8 +306,10 @@ public final class LocationComponent {
|
||||
* @param context the context
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param styleRes the LocationComponent style res
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style, @StyleRes int styleRes) {
|
||||
activateLocationComponent(context, style, LocationComponentOptions.createFromAttributes(context, styleRes));
|
||||
}
|
||||
@@ -314,8 +324,10 @@ public final class LocationComponent {
|
||||
* @param context the context
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param options the options
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@NonNull LocationComponentOptions options) {
|
||||
initialize(context, style, options);
|
||||
@@ -331,8 +343,10 @@ public final class LocationComponent {
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param locationEngine the engine, or null if you'd like to only force location updates
|
||||
* @param styleRes the LocationComponent style res
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine, @StyleRes int styleRes) {
|
||||
activateLocationComponent(context, style, locationEngine,
|
||||
@@ -348,8 +362,10 @@ public final class LocationComponent {
|
||||
* @param locationEngine the engine, or null if you'd like to only force location updates
|
||||
* @param locationEngineRequest the location request
|
||||
* @param styleRes the LocationComponent style res
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine,
|
||||
@NonNull LocationEngineRequest locationEngineRequest, @StyleRes int styleRes) {
|
||||
@@ -363,8 +379,10 @@ public final class LocationComponent {
|
||||
* @param context the context
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param locationEngine the engine
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine) {
|
||||
activateLocationComponent(context, style, locationEngine, R.style.mapbox_LocationComponent);
|
||||
@@ -377,8 +395,10 @@ public final class LocationComponent {
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param locationEngine the engine
|
||||
* @param locationEngineRequest the location request
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine,
|
||||
@NonNull LocationEngineRequest locationEngineRequest) {
|
||||
@@ -392,8 +412,10 @@ public final class LocationComponent {
|
||||
* @param locationEngine the engine, or null if you'd like to only force location updates
|
||||
* @param style the proxy object for current map style. More info at {@link Style}
|
||||
* @param options the options
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine,
|
||||
@NonNull LocationComponentOptions options) {
|
||||
@@ -411,7 +433,9 @@ public final class LocationComponent {
|
||||
* @param locationEngine the engine, or null if you'd like to only force location updates
|
||||
* @param locationEngineRequest the location request
|
||||
* @param options the options
|
||||
* @deprecated use {@link LocationComponentActivationOptions.Builder} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void activateLocationComponent(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine,
|
||||
@NonNull LocationEngineRequest locationEngineRequest,
|
||||
@@ -422,6 +446,50 @@ public final class LocationComponent {
|
||||
applyStyle(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the component and needs to be called before any other operations are performed.
|
||||
* Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
|
||||
*
|
||||
* @param activationOptions a fully built {@link LocationComponentActivationOptions} object
|
||||
*/
|
||||
public void activateLocationComponent(@NonNull LocationComponentActivationOptions
|
||||
activationOptions) {
|
||||
LocationComponentOptions options = activationOptions.locationComponentOptions();
|
||||
if (options == null) {
|
||||
int styleRes = activationOptions.styleRes();
|
||||
if (styleRes == 0) {
|
||||
styleRes = R.style.mapbox_LocationComponent;
|
||||
}
|
||||
options = LocationComponentOptions.createFromAttributes(activationOptions.context(), styleRes);
|
||||
}
|
||||
|
||||
// Initialize the LocationComponent with Context, the map's `Style`, and either custom LocationComponentOptions
|
||||
// or backup options created from default/custom attributes
|
||||
initialize(activationOptions.context(), activationOptions.style(), options);
|
||||
|
||||
// Apply the LocationComponent styling
|
||||
// TODO avoid doubling style initialization
|
||||
applyStyle(options);
|
||||
|
||||
// Set the LocationEngine request if one was given to LocationComponentActivationOptions
|
||||
LocationEngineRequest locationEngineRequest = activationOptions.locationEngineRequest();
|
||||
if (locationEngineRequest != null) {
|
||||
setLocationEngineRequest(locationEngineRequest);
|
||||
}
|
||||
|
||||
// Set the LocationEngine if one was given to LocationComponentActivationOptions
|
||||
LocationEngine locationEngine = activationOptions.locationEngine();
|
||||
if (locationEngine != null) {
|
||||
setLocationEngine(locationEngine);
|
||||
} else {
|
||||
if (activationOptions.useDefaultLocationEngine()) {
|
||||
initializeLocationEngine(activationOptions.context());
|
||||
} else {
|
||||
setLocationEngine(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage component's visibility after activation.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
package com.mapbox.mapboxsdk.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.mapbox.android.core.location.LocationEngine;
|
||||
import com.mapbox.android.core.location.LocationEngineRequest;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
|
||||
/**
|
||||
* A class which holds the various options for activating the Maps SDK's {@link LocationComponent} to eventually
|
||||
* show the device location on the map.
|
||||
*/
|
||||
public class LocationComponentActivationOptions {
|
||||
|
||||
private final Context context;
|
||||
private final Style style;
|
||||
private final LocationEngine locationEngine;
|
||||
private final LocationEngineRequest locationEngineRequest;
|
||||
private final LocationComponentOptions locationComponentOptions;
|
||||
private final int styleRes;
|
||||
private final boolean useDefaultLocationEngine;
|
||||
|
||||
private LocationComponentActivationOptions(@NonNull Context context, @NonNull Style style,
|
||||
@Nullable LocationEngine locationEngine,
|
||||
@Nullable LocationEngineRequest locationEngineRequest,
|
||||
@Nullable LocationComponentOptions locationComponentOptions,
|
||||
int styleRes,
|
||||
boolean useDefaultLocationEngine) {
|
||||
this.context = context;
|
||||
this.style = style;
|
||||
this.locationEngine = locationEngine;
|
||||
this.locationEngineRequest = locationEngineRequest;
|
||||
this.locationComponentOptions = locationComponentOptions;
|
||||
this.styleRes = styleRes;
|
||||
this.useDefaultLocationEngine = useDefaultLocationEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to retrieve a {@link LocationComponentActivationOptions} object which is ready to build with
|
||||
*
|
||||
* @return a builder object
|
||||
*/
|
||||
@NonNull
|
||||
public static Builder builder(@NonNull Context context, @NonNull Style fullyLoadedMapStyle) {
|
||||
return new LocationComponentActivationOptions.Builder(context, fullyLoadedMapStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* The application's current context
|
||||
*
|
||||
* @return the application's current context
|
||||
*/
|
||||
@NonNull
|
||||
public Context context() {
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* The proxy object for current map style. More info at {@link Style}
|
||||
*
|
||||
* @return the map's fully loaded Style object
|
||||
*/
|
||||
@NonNull
|
||||
public Style style() {
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link LocationEngine} which the {@link LocationComponent} should use
|
||||
*
|
||||
* @return the engine
|
||||
*/
|
||||
@Nullable
|
||||
public LocationEngine locationEngine() {
|
||||
return locationEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* The location request which the {@link LocationComponent} should use
|
||||
*
|
||||
* @return the LocationEngineRequest object
|
||||
*/
|
||||
@Nullable
|
||||
public LocationEngineRequest locationEngineRequest() {
|
||||
return locationEngineRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* A built {@link LocationComponentOptions} object, which holds the various {@link LocationComponent} styling options
|
||||
*
|
||||
* @return the options for styling the actual LocationComponent
|
||||
*/
|
||||
@Nullable
|
||||
public LocationComponentOptions locationComponentOptions() {
|
||||
return locationComponentOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* The LocationComponent style resource (e.g. R.style.style_name)
|
||||
*
|
||||
* @return the style resource.
|
||||
*/
|
||||
public int styleRes() {
|
||||
return styleRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if you want to initialize and use the built-in location engine or false if there should be no
|
||||
* location engine initialized
|
||||
*
|
||||
* @return whether the default LocationEngine is used
|
||||
*/
|
||||
public boolean useDefaultLocationEngine() {
|
||||
return useDefaultLocationEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for constructing a new instance of {@link LocationComponentActivationOptions}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private final Context context;
|
||||
private final Style style;
|
||||
private LocationEngine locationEngine;
|
||||
private LocationEngineRequest locationEngineRequest;
|
||||
private LocationComponentOptions locationComponentOptions;
|
||||
private int styleRes;
|
||||
|
||||
/**
|
||||
* Set to true as the default in case a true/false value isn't declared via the builder's
|
||||
* {@link LocationComponentActivationOptions#useDefaultLocationEngine()} method.
|
||||
* <p>
|
||||
* Please be aware that this activation boolean is ignored when a non-null
|
||||
* {@link LocationEngine} is set via the builder's `locationEngine()` method.
|
||||
*/
|
||||
private boolean useDefaultLocationEngine = true;
|
||||
|
||||
/**
|
||||
* Constructor for the {@link LocationComponentActivationOptions} builder class.
|
||||
* While other activation options are optional, the activation process always requires
|
||||
* context and a fully-loaded map {@link Style} object, which is why the two are in this
|
||||
* constructor.
|
||||
*/
|
||||
public Builder(@NonNull Context context, @NonNull Style style) {
|
||||
this.context = context;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deliver your own {@link LocationEngine} to the LocationComponent.
|
||||
* <p>
|
||||
* The true/false
|
||||
* {@link LocationComponentActivationOptions#builder(Context, Style)#useDefaultLocationEngine}
|
||||
* activation option is ignored when a non-null {@link LocationEngine} is set via
|
||||
* this `locationEngine()` method.
|
||||
*
|
||||
* @param locationEngine a {@link LocationEngine} object
|
||||
* @return the {@link Builder} object being constructed
|
||||
*/
|
||||
@NonNull
|
||||
public Builder locationEngine(@Nullable LocationEngine locationEngine) {
|
||||
this.locationEngine = locationEngine;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locationEngineRequest the location request which the
|
||||
* {@link LocationComponent} should use
|
||||
* @return the {@link Builder} object being constructed
|
||||
*/
|
||||
public Builder locationEngineRequest(LocationEngineRequest locationEngineRequest) {
|
||||
this.locationEngineRequest = locationEngineRequest;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locationComponentOptions a built {@link LocationComponentOptions} object,
|
||||
* which holds the various {@link LocationComponent}
|
||||
* styling options
|
||||
* @return the {@link Builder} object being constructed
|
||||
*/
|
||||
public Builder locationComponentOptions(LocationComponentOptions locationComponentOptions) {
|
||||
this.locationComponentOptions = locationComponentOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param styleRes the LocationComponent style resource (e.g. R.style.style_name)
|
||||
* @return the {@link Builder} object being constructed
|
||||
*/
|
||||
public Builder styleRes(int styleRes) {
|
||||
this.styleRes = styleRes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param useDefaultLocationEngine true if you want to initialize and use the
|
||||
* built-in location engine or false if there
|
||||
* should be no location engine initialized
|
||||
* This is ignored when null is set as the parameter
|
||||
* for {@link LocationComponentActivationOptions#builder
|
||||
* (Context, Style)#locationEngine()}.
|
||||
* @return the {@link Builder} object being constructed
|
||||
*/
|
||||
public Builder useDefaultLocationEngine(boolean useDefaultLocationEngine) {
|
||||
this.useDefaultLocationEngine = useDefaultLocationEngine;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method which actually builds the {@link LocationComponentActivationOptions} object while
|
||||
* taking the various options into account.
|
||||
*
|
||||
* @return a built {@link LocationComponentActivationOptions} object
|
||||
*/
|
||||
public LocationComponentActivationOptions build() {
|
||||
if (styleRes != 0 && locationComponentOptions != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"You've provided both a style resource and a LocationComponentOptions object to the "
|
||||
+ "LocationComponentActivationOptions builder. You can't use both and "
|
||||
+ "you must choose one of the two to style the LocationComponent.");
|
||||
}
|
||||
if (context == null) {
|
||||
throw new NullPointerException(
|
||||
"Context in LocationComponentActivationOptions is null.");
|
||||
}
|
||||
if (style == null) {
|
||||
throw new NullPointerException(
|
||||
"Style in LocationComponentActivationOptions is null. Make sure the "
|
||||
+ "Style object isn't null. Wait for the map to fully load before passing "
|
||||
+ "the Style object to LocationComponentActivationOptions.");
|
||||
}
|
||||
if (!style.isFullyLoaded()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Style in LocationComponentActivationOptions isn't fully loaded. Wait for the "
|
||||
+ "map to fully load before passing the Style object to "
|
||||
+ "LocationComponentActivationOptions.");
|
||||
}
|
||||
return new LocationComponentActivationOptions(context, style, locationEngine,
|
||||
locationEngineRequest, locationComponentOptions, styleRes, useDefaultLocationEngine);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user