Custom location source fix (#9142)
* [android] - custom location engine fixes (#9139) * Update to latest LOST dependency, fixup internal location source integration
This commit is contained in:
@@ -30,6 +30,7 @@ public final class Mapbox {
|
||||
private Context context;
|
||||
private String accessToken;
|
||||
private Boolean connected;
|
||||
private LocationSource locationSource;
|
||||
|
||||
/**
|
||||
* Get an instance of Mapbox.
|
||||
@@ -45,8 +46,8 @@ public final class Mapbox {
|
||||
public static synchronized Mapbox getInstance(@NonNull Context context, @NonNull String accessToken) {
|
||||
if (INSTANCE == null) {
|
||||
Context appContext = context.getApplicationContext();
|
||||
INSTANCE = new Mapbox(appContext, accessToken);
|
||||
LocationEngine locationEngine = LocationSource.getLocationEngine(appContext);
|
||||
INSTANCE = new Mapbox(appContext, accessToken, new LocationSource(appContext));
|
||||
LocationEngine locationEngine = new LocationSource(appContext);
|
||||
locationEngine.setPriority(LocationEnginePriority.NO_POWER);
|
||||
MapboxTelemetry.getInstance().initialize(
|
||||
appContext, accessToken, BuildConfig.MAPBOX_EVENTS_USER_AGENT, locationEngine);
|
||||
@@ -55,9 +56,10 @@ public final class Mapbox {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
Mapbox(@NonNull Context context, @NonNull String accessToken) {
|
||||
Mapbox(@NonNull Context context, @NonNull String accessToken, LocationSource locationSource) {
|
||||
this.context = context;
|
||||
this.accessToken = accessToken;
|
||||
this.locationSource = locationSource;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,4 +130,8 @@ public final class Mapbox {
|
||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||
return (activeNetwork != null && activeNetwork.isConnected());
|
||||
}
|
||||
|
||||
public static LocationSource getLocationSource() {
|
||||
return INSTANCE.locationSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,5 +134,5 @@ public class MapboxConstants {
|
||||
public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "mapbox_atrrMarginBottom";
|
||||
public static final String STATE_ATTRIBUTION_ENABLED = "mapbox_atrrEnabled";
|
||||
public static final String STATE_LOCATION_CHANGE_ANIMATION_ENABLED = "mapbox_locationChangeAnimationEnabled";
|
||||
|
||||
public static final String STATE_USING_CUSTOM_LOCATION_SOURCE = "mapbox_usingCustomLocationSource";
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngine;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
|
||||
@@ -13,10 +13,6 @@ import com.mapzen.android.lost.api.LocationRequest;
|
||||
import com.mapzen.android.lost.api.LocationServices;
|
||||
import com.mapzen.android.lost.api.LostApiClient;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Manages locational updates. Contains methods to register and unregister location listeners.
|
||||
* <ul>
|
||||
@@ -35,40 +31,24 @@ import timber.log.Timber;
|
||||
public class LocationSource extends LocationEngine implements
|
||||
LostApiClient.ConnectionCallbacks, LocationListener {
|
||||
|
||||
private static LocationEngine instance;
|
||||
|
||||
private WeakReference<Context> context;
|
||||
private Context context;
|
||||
private LostApiClient lostApiClient;
|
||||
|
||||
private LocationSource(Context context) {
|
||||
public LocationSource(Context context) {
|
||||
super();
|
||||
this.context = new WeakReference<>(context);
|
||||
lostApiClient = new LostApiClient.Builder(this.context.get())
|
||||
this.context = context.getApplicationContext();
|
||||
lostApiClient = new LostApiClient.Builder(this.context)
|
||||
.addConnectionCallbacks(this)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the LocationEngine instance.
|
||||
*
|
||||
* @param context a Context from which the application context is derived
|
||||
* @return the LocationEngine instance
|
||||
*/
|
||||
public static synchronized LocationEngine getLocationEngine(@NonNull Context context) {
|
||||
if (instance == null) {
|
||||
instance = new LocationSource(context.getApplicationContext());
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the location engine which will connect whichever location provider you are using. You'll need to call
|
||||
* this before requesting user location updates using {@link LocationEngine#requestLocationUpdates()}.
|
||||
*/
|
||||
@Override
|
||||
public void activate() {
|
||||
if (lostApiClient != null && !lostApiClient.isConnected()) {
|
||||
if (!lostApiClient.isConnected()) {
|
||||
lostApiClient.connect();
|
||||
}
|
||||
}
|
||||
@@ -80,7 +60,7 @@ public class LocationSource extends LocationEngine implements
|
||||
*/
|
||||
@Override
|
||||
public void deactivate() {
|
||||
if (lostApiClient != null && lostApiClient.isConnected()) {
|
||||
if (lostApiClient.isConnected()) {
|
||||
lostApiClient.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -111,7 +91,6 @@ public class LocationSource extends LocationEngine implements
|
||||
*/
|
||||
@Override
|
||||
public void onConnectionSuspended() {
|
||||
Timber.d("Connection suspended.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,8 +99,9 @@ public class LocationSource extends LocationEngine implements
|
||||
* @return the last known location
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public Location getLastLocation() {
|
||||
if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) {
|
||||
if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) {
|
||||
//noinspection MissingPermission
|
||||
return LocationServices.FusedLocationApi.getLastLocation(lostApiClient);
|
||||
}
|
||||
@@ -151,7 +131,7 @@ public class LocationSource extends LocationEngine implements
|
||||
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
|
||||
}
|
||||
|
||||
if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) {
|
||||
if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context)) {
|
||||
//noinspection MissingPermission
|
||||
LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.constants.Style;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
|
||||
import com.mapbox.mapboxsdk.style.layers.Filter;
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
@@ -1872,8 +1871,6 @@ public final class MapboxMap {
|
||||
* Replaces the location source of the my-location layer.
|
||||
*
|
||||
* @param locationSource A {@link LocationEngine} location source to use in the my-location layer.
|
||||
* Set to null to use the default {@link LocationSource}
|
||||
* location source.
|
||||
*/
|
||||
@UiThread
|
||||
public void setLocationSource(@Nullable LocationEngine locationSource) {
|
||||
|
||||
@@ -6,11 +6,11 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngine;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
|
||||
@@ -30,6 +30,7 @@ public final class TrackingSettings {
|
||||
private LocationEngine locationSource;
|
||||
private LocationEngineListener myLocationListener;
|
||||
private boolean locationChangeAnimationEnabled = true;
|
||||
private boolean isCustomLocationSource;
|
||||
|
||||
private boolean myLocationEnabled;
|
||||
private boolean dismissLocationTrackingOnGesture = true;
|
||||
@@ -47,7 +48,7 @@ public final class TrackingSettings {
|
||||
}
|
||||
|
||||
void initialise(MapboxMapOptions options) {
|
||||
locationSource = LocationSource.getLocationEngine(myLocationView.getContext());
|
||||
locationSource = Mapbox.getLocationSource();
|
||||
setMyLocationEnabled(options.getLocationEnabled());
|
||||
}
|
||||
|
||||
@@ -58,11 +59,15 @@ public final class TrackingSettings {
|
||||
outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture());
|
||||
outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled());
|
||||
outState.putBoolean(MapboxConstants.STATE_LOCATION_CHANGE_ANIMATION_ENABLED, isLocationChangeAnimationEnabled());
|
||||
outState.putBoolean(MapboxConstants.STATE_USING_CUSTOM_LOCATION_SOURCE, isCustomLocationSource());
|
||||
}
|
||||
|
||||
void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
try {
|
||||
setMyLocationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED));
|
||||
setMyLocationEnabled(
|
||||
savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED),
|
||||
savedInstanceState.getBoolean(MapboxConstants.STATE_USING_CUSTOM_LOCATION_SOURCE)
|
||||
);
|
||||
} catch (SecurityException ignore) {
|
||||
// User did not accept location permissions
|
||||
}
|
||||
@@ -339,6 +344,10 @@ public final class TrackingSettings {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCustomLocationSource() {
|
||||
return isCustomLocationSource;
|
||||
}
|
||||
|
||||
void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
|
||||
this.onMyLocationTrackingModeChangeListener = listener;
|
||||
}
|
||||
@@ -357,16 +366,30 @@ public final class TrackingSettings {
|
||||
}
|
||||
|
||||
void setMyLocationEnabled(boolean locationEnabled) {
|
||||
setMyLocationEnabled(locationEnabled, isCustomLocationSource());
|
||||
}
|
||||
|
||||
private void setMyLocationEnabled(boolean locationEnabled, boolean isCustomLocationSource) {
|
||||
if (!PermissionsManager.areLocationPermissionsGranted(myLocationView.getContext())) {
|
||||
Timber.e("Could not activate user location tracking: "
|
||||
+ "user did not accept the permission or permissions were not requested.");
|
||||
return;
|
||||
}
|
||||
myLocationEnabled = locationEnabled;
|
||||
myLocationView.setEnabled(locationEnabled);
|
||||
this.isCustomLocationSource = isCustomLocationSource;
|
||||
myLocationView.setEnabled(locationEnabled, isCustomLocationSource);
|
||||
}
|
||||
|
||||
void setLocationSource(LocationEngine locationSource) {
|
||||
if (this.locationSource != null && this.locationSource.equals(locationSource)) {
|
||||
// this source is already active
|
||||
return;
|
||||
}
|
||||
|
||||
this.isCustomLocationSource = locationSource != null;
|
||||
if (locationSource == null) {
|
||||
locationSource = Mapbox.getLocationSource();
|
||||
}
|
||||
this.locationSource = locationSource;
|
||||
myLocationView.setLocationSource(locationSource);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
@@ -40,6 +41,8 @@ import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* UI element overlaid on a map to show the user's location.
|
||||
*/
|
||||
@@ -148,6 +151,10 @@ public class MyLocationView extends View {
|
||||
compassListener = new CompassListener(context);
|
||||
}
|
||||
|
||||
public void init(LocationSource locationSource) {
|
||||
this.locationSource = locationSource;
|
||||
}
|
||||
|
||||
public final void setForegroundDrawables(Drawable defaultDrawable, Drawable bearingDrawable) {
|
||||
if (defaultDrawable == null) {
|
||||
return;
|
||||
@@ -391,9 +398,13 @@ public class MyLocationView extends View {
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
setEnabled(enabled, false);
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled, boolean isCustomLocationSource) {
|
||||
super.setEnabled(enabled);
|
||||
setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
|
||||
toggleGps(enabled);
|
||||
toggleGps(enabled, isCustomLocationSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -414,22 +425,23 @@ public class MyLocationView extends View {
|
||||
super.onRestoreInstanceState(state);
|
||||
}
|
||||
|
||||
private void toggleGps(boolean enableGps) {
|
||||
toggleGps(enableGps, mapboxMap != null && mapboxMap.getTrackingSettings().isCustomLocationSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enabled / Disable GPS location updates along with updating the UI
|
||||
*
|
||||
* @param enableGps true if GPS is to be enabled, false if GPS is to be disabled
|
||||
*/
|
||||
private void toggleGps(boolean enableGps) {
|
||||
if (locationSource == null) {
|
||||
locationSource = LocationSource.getLocationEngine(this.getContext());
|
||||
}
|
||||
|
||||
private void toggleGps(boolean enableGps, boolean isCustomLocationSource) {
|
||||
if (enableGps) {
|
||||
// Set an initial location if one available
|
||||
Location lastLocation = locationSource.getLastLocation();
|
||||
|
||||
if (lastLocation != null) {
|
||||
setLocation(lastLocation);
|
||||
if (locationSource == null) {
|
||||
if (!isCustomLocationSource) {
|
||||
locationSource = Mapbox.getLocationSource();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (userLocationListener == null) {
|
||||
@@ -437,16 +449,18 @@ public class MyLocationView extends View {
|
||||
}
|
||||
|
||||
locationSource.addLocationEngineListener(userLocationListener);
|
||||
locationSource.setPriority(LocationEnginePriority.HIGH_ACCURACY);
|
||||
locationSource.activate();
|
||||
} else {
|
||||
if (locationSource == null) {
|
||||
return;
|
||||
}
|
||||
// Disable location and user dot
|
||||
location = null;
|
||||
locationSource.removeLocationUpdates();
|
||||
locationSource.removeLocationEngineListener(userLocationListener);
|
||||
locationSource.removeLocationUpdates();
|
||||
locationSource.deactivate();
|
||||
}
|
||||
|
||||
locationSource.setPriority(LocationEnginePriority.HIGH_ACCURACY);
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
@@ -564,7 +578,10 @@ public class MyLocationView extends View {
|
||||
}
|
||||
|
||||
public void setLocationSource(LocationEngine locationSource) {
|
||||
toggleGps(false);
|
||||
this.locationSource = locationSource;
|
||||
this.userLocationListener = null;
|
||||
setEnabled(isEnabled(), locationSource != null);
|
||||
}
|
||||
|
||||
private static class GpsLocationListener implements LocationEngineListener {
|
||||
@@ -580,10 +597,12 @@ public class MyLocationView extends View {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
MyLocationView locationView = userLocationView.get();
|
||||
if (locationView != null) {
|
||||
LocationEngine locationEngine = locationSource.get();
|
||||
Location location = locationEngine.getLastLocation();
|
||||
locationView.setLocation(location);
|
||||
LocationEngine locationEngine = locationSource.get();
|
||||
if (locationView != null && locationEngine != null) {
|
||||
Location lastKnownLocation = locationEngine.getLastLocation();
|
||||
if (lastKnownLocation != null) {
|
||||
locationView.setLocation(lastKnownLocation);
|
||||
}
|
||||
locationEngine.requestLocationUpdates();
|
||||
}
|
||||
}
|
||||
@@ -627,6 +646,9 @@ public class MyLocationView extends View {
|
||||
}
|
||||
|
||||
public boolean isSensorAvailable() {
|
||||
if (rotationVectorSensor == null) {
|
||||
Timber.e("Sensor.TYPE_ROTATION_VECTOR is missing from this device. Unable to use MyBearingTracking.COMPASS.");
|
||||
}
|
||||
return rotationVectorSensor != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ import android.support.test.espresso.UiController;
|
||||
import android.support.test.espresso.ViewAction;
|
||||
import android.view.View;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
@@ -104,7 +104,7 @@ public class MyLocationViewTest extends BaseActivityTest {
|
||||
mapboxMap.moveCamera(
|
||||
CameraUpdateFactory.newCameraPosition(
|
||||
new CameraPosition.Builder()
|
||||
.target(new LatLng(LocationSource.getLocationEngine(view.getContext()).getLastLocation()))
|
||||
.target(new LatLng(Mapbox.getLocationSource().getLastLocation()))
|
||||
.build()
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -13,11 +12,10 @@ import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
@@ -25,6 +23,8 @@ import com.mapbox.mapboxsdk.testapp.adapter.FeatureAdapter;
|
||||
import com.mapbox.mapboxsdk.testapp.adapter.FeatureSectionAdapter;
|
||||
import com.mapbox.mapboxsdk.testapp.model.activity.Feature;
|
||||
import com.mapbox.mapboxsdk.testapp.utils.ItemClickSupport;
|
||||
import com.mapbox.services.android.telemetry.permissions.PermissionsListener;
|
||||
import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -40,19 +40,23 @@ import timber.log.Timber;
|
||||
* It uses tags as category and description to order the different entries.
|
||||
* </p>
|
||||
*/
|
||||
public class FeatureOverviewActivity extends AppCompatActivity {
|
||||
public class FeatureOverviewActivity extends AppCompatActivity implements PermissionsListener {
|
||||
|
||||
private static final String KEY_STATE_FEATURES = "featureList";
|
||||
|
||||
private PermissionsManager permissionsManager;
|
||||
private RecyclerView recyclerView;
|
||||
private FeatureSectionAdapter sectionAdapter;
|
||||
private List<Feature> features;
|
||||
private int locationActivityInList;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_feature_overview);
|
||||
|
||||
permissionsManager = new PermissionsManager(this);
|
||||
|
||||
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener());
|
||||
@@ -119,22 +123,26 @@ public class FeatureOverviewActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private boolean requestLocationPermission(final int positionInList) {
|
||||
if ((ContextCompat.checkSelfPermission(FeatureOverviewActivity.this,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
|
||||
|| (ContextCompat.checkSelfPermission(FeatureOverviewActivity.this,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
|
||||
ActivityCompat.requestPermissions(FeatureOverviewActivity.this, new String[] {
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, positionInList);
|
||||
if (isRuntimePermissionsRequired()) {
|
||||
locationActivityInList = positionInList;
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (!isRuntimePermissionsRequired() || isPermissionAccepted(grantResults)) {
|
||||
startFeature(features.get(requestCode));
|
||||
public void onExplanationNeeded(List<String> list) {
|
||||
Snackbar.make(
|
||||
findViewById(android.R.id.content),
|
||||
TextUtils.join("", list.toArray()),
|
||||
Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionResult(boolean isPermissionGranted) {
|
||||
if (isPermissionGranted) {
|
||||
startFeature(features.get(locationActivityInList));
|
||||
} else {
|
||||
Snackbar.make(
|
||||
findViewById(android.R.id.content),
|
||||
@@ -143,12 +151,14 @@ public class FeatureOverviewActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRuntimePermissionsRequired() {
|
||||
return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
private boolean isPermissionAccepted(@NonNull int[] grantResults) {
|
||||
return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
|
||||
private boolean isRuntimePermissionsRequired() {
|
||||
return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -219,13 +229,13 @@ public class FeatureOverviewActivity extends AppCompatActivity {
|
||||
}
|
||||
};
|
||||
|
||||
List<String> requiresPermissionActvities = new ArrayList<String>() {
|
||||
List<String> requiresPermissionActivities = new ArrayList<String>() {
|
||||
{
|
||||
add(resources.getString(R.string.activity_double_map));
|
||||
}
|
||||
};
|
||||
|
||||
return requiresPermissionCategories.contains(category) || requiresPermissionActvities.contains(name);
|
||||
return requiresPermissionCategories.contains(category) || requiresPermissionActivities.contains(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mapbox.services.android.telemetry.permissions.PermissionsListener;
|
||||
import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
|
||||
|
||||
public abstract class BaseLocationActivity extends AppCompatActivity {
|
||||
import java.util.List;
|
||||
|
||||
private static final int PERMISSIONS_LOCATION = 0;
|
||||
public abstract class BaseLocationActivity extends AppCompatActivity implements PermissionsListener {
|
||||
|
||||
private PermissionsManager permissionsManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
permissionsManager = new PermissionsManager(this);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
protected final void toggleGps(boolean enableGps) {
|
||||
if (enableGps) {
|
||||
if (!PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
|
||||
if (!isRuntimePermissionsRequired()) {
|
||||
permissionsManager.requestLocationPermissions(this);
|
||||
} else {
|
||||
enableLocation(true);
|
||||
}
|
||||
@@ -29,16 +38,21 @@ public abstract class BaseLocationActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (requestCode == PERMISSIONS_LOCATION) {
|
||||
if (!isRuntimePermissionsRequired() || isPermissionAccepted(grantResults)) {
|
||||
enableLocation(true);
|
||||
}
|
||||
}
|
||||
public void onExplanationNeeded(List<String> list) {
|
||||
Snackbar.make(
|
||||
findViewById(android.R.id.content),
|
||||
TextUtils.join("", list.toArray()),
|
||||
Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private boolean isPermissionAccepted(int[] grantResults) {
|
||||
return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
|
||||
@Override
|
||||
public void onPermissionResult(boolean isPermissionAccepted) {
|
||||
enableLocation(isPermissionAccepted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
private boolean isRuntimePermissionsRequired() {
|
||||
|
||||
@@ -2,13 +2,15 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngine;
|
||||
|
||||
public class CustomLocationEngineActivity extends BaseLocationActivity {
|
||||
|
||||
@@ -16,22 +18,18 @@ public class CustomLocationEngineActivity extends BaseLocationActivity {
|
||||
private MapboxMap mapboxMap;
|
||||
private FloatingActionButton locationToggleFab;
|
||||
|
||||
private LocationEngine locationServices;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_custom_location_engine);
|
||||
|
||||
locationServices = new MockLocationEngine();
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
mapboxMap.setLocationSource(locationServices);
|
||||
mapboxMap.setLocationSource(MockLocationEngine.getInstance());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,7 +38,7 @@ public class CustomLocationEngineActivity extends BaseLocationActivity {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mapboxMap != null) {
|
||||
toggleGps(!mapboxMap.isMyLocationEnabled());
|
||||
enableLocation(!mapboxMap.isMyLocationEnabled());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -56,6 +54,30 @@ public class CustomLocationEngineActivity extends BaseLocationActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_location_engine, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (mapboxMap != null) {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.action_id_location_source_lost) {
|
||||
mapboxMap.setLocationSource(Mapbox.getLocationSource());
|
||||
return true;
|
||||
} else if (itemId == R.id.action_id_location_source_mock) {
|
||||
mapboxMap.setLocationSource(MockLocationEngine.getInstance());
|
||||
return true;
|
||||
} else if (itemId == R.id.action_id_location_source_null) {
|
||||
mapboxMap.setLocationSource(null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
@@ -1,38 +1,55 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.TypeEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.location.Location;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngine;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Sample LocationEngine that provides mocked locations simulating GPS updates
|
||||
* Sample LocationEngine that provides mocked LOCATIONS simulating GPS updates
|
||||
*/
|
||||
public class MockLocationEngine extends LocationEngine {
|
||||
private static MockLocationEngine INSTANCE;
|
||||
|
||||
// Mocked data
|
||||
private static final int UPDATE_INTERVAL_MS = 1000;
|
||||
private static final double[][] locations = new double[][] {
|
||||
new double[] {39.489309, -0.360415},
|
||||
new double[] {39.492469, -0.358777},
|
||||
new double[] {40.393285, -3.707260},
|
||||
new double[] {40.394374, -3.707767},
|
||||
new double[] {40.398012, -3.715943},
|
||||
new double[] {40.416913, -3.703861}};
|
||||
private final LocationAnimator locationAnimator;
|
||||
private boolean running;
|
||||
private static int counter;
|
||||
|
||||
private Handler handler;
|
||||
int currentIndex;
|
||||
MockLocationEngine(Location start, Location end) {
|
||||
locationAnimator = new LocationAnimator(start, end, new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
for (LocationEngineListener listener : locationListeners) {
|
||||
listener.onLocationChanged((Location) animation.getAnimatedValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MockLocationEngine() {
|
||||
super();
|
||||
public static synchronized MockLocationEngine getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new MockLocationEngine(
|
||||
MockLocationEngine.createLocation(40.416913, -3.703861),
|
||||
MockLocationEngine.createLocation(39.461643, -0.368041)
|
||||
);
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static Location createLocation(double latitude, double longitude) {
|
||||
Location location = new Location(MockLocationEngine.class.getSimpleName());
|
||||
location.setLatitude(latitude);
|
||||
location.setLongitude(longitude);
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
currentIndex = 0;
|
||||
|
||||
// "Connection" is immediate here
|
||||
for (LocationEngineListener listener : locationListeners) {
|
||||
listener.onConnected();
|
||||
@@ -41,7 +58,6 @@ public class MockLocationEngine extends LocationEngine {
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
handler = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,44 +67,61 @@ public class MockLocationEngine extends LocationEngine {
|
||||
|
||||
@Override
|
||||
public Location getLastLocation() {
|
||||
return getNextLocation();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLocationUpdates() {
|
||||
// Fake regular updates with a handler
|
||||
handler = new Handler();
|
||||
handler.postDelayed(new LocationUpdateRunnable(), UPDATE_INTERVAL_MS);
|
||||
if (!running) {
|
||||
locationAnimator.start();
|
||||
running = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLocationUpdates() {
|
||||
if (handler != null) {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
if (running) {
|
||||
locationAnimator.stop();
|
||||
running = false;
|
||||
Timber.e("LOC %s", counter);
|
||||
}
|
||||
}
|
||||
|
||||
private Location getNextLocation() {
|
||||
// Build the next location and rotate the index
|
||||
Location location = new Location(MockLocationEngine.class.getSimpleName());
|
||||
location.setLatitude(locations[currentIndex][0]);
|
||||
location.setLongitude(locations[currentIndex][1]);
|
||||
currentIndex = (currentIndex == locations.length - 1 ? 0 : currentIndex + 1);
|
||||
return location;
|
||||
}
|
||||
private static class LocationAnimator extends AnimatorListenerAdapter {
|
||||
|
||||
private class LocationUpdateRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
// Notify of an update
|
||||
Location location = getNextLocation();
|
||||
for (LocationEngineListener listener : locationListeners) {
|
||||
listener.onLocationChanged(location);
|
||||
}
|
||||
private static final long DURATION_ANIMATION = 10000;
|
||||
private final ValueAnimator locationAnimator;
|
||||
private long animationTime;
|
||||
|
||||
if (handler != null) {
|
||||
// Schedule the next update
|
||||
handler.postDelayed(new LocationUpdateRunnable(), UPDATE_INTERVAL_MS);
|
||||
LocationAnimator(Location start, Location end, ValueAnimator.AnimatorUpdateListener listener) {
|
||||
locationAnimator = ValueAnimator.ofObject(new LocationEvaluator(), start, end);
|
||||
locationAnimator.setDuration(DURATION_ANIMATION);
|
||||
locationAnimator.addUpdateListener(listener);
|
||||
locationAnimator.addListener(this);
|
||||
}
|
||||
|
||||
void start() {
|
||||
locationAnimator.start();
|
||||
locationAnimator.setCurrentPlayTime(animationTime);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
animationTime = locationAnimator.getCurrentPlayTime();
|
||||
locationAnimator.cancel();
|
||||
}
|
||||
|
||||
private static class LocationEvaluator implements TypeEvaluator<Location> {
|
||||
|
||||
private Location location = new Location(MockLocationEngine.class.getSimpleName());
|
||||
|
||||
@Override
|
||||
public Location evaluate(float fraction, Location startValue, Location endValue) {
|
||||
counter++;
|
||||
location.setLatitude(startValue.getLatitude()
|
||||
+ ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
|
||||
location.setLongitude(startValue.getLongitude()
|
||||
+ ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
|
||||
return location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,33 +11,35 @@ import android.view.ViewGroup;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.Style;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
|
||||
|
||||
import com.mapzen.android.lost.api.LocationListener;
|
||||
import com.mapzen.android.lost.api.LocationRequest;
|
||||
import com.mapzen.android.lost.api.LocationServices;
|
||||
import com.mapzen.android.lost.api.LostApiClient;
|
||||
|
||||
/**
|
||||
* Test activity showcasing how to change the MyLocationView drawable.
|
||||
*/
|
||||
public class MyLocationDrawableActivity extends BaseLocationActivity implements LocationEngineListener {
|
||||
public class MyLocationDrawableActivity extends BaseLocationActivity implements LostApiClient.ConnectionCallbacks,
|
||||
LocationListener {
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private LostApiClient lostApiClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_my_location_customization);
|
||||
|
||||
findViewById(R.id.progress).setVisibility(View.GONE);
|
||||
|
||||
MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
|
||||
mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS);
|
||||
|
||||
// configure MyLocationView drawables
|
||||
mapboxMapOptions.myLocationForegroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_android));
|
||||
mapboxMapOptions.myLocationBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_android));
|
||||
mapboxMapOptions.myLocationForegroundTintColor(Color.GREEN);
|
||||
@@ -45,7 +47,6 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements
|
||||
mapboxMapOptions.myLocationBackgroundPadding(new int[] {0, 0,
|
||||
(int) getResources().getDimension(R.dimen.locationview_background_drawable_padding),
|
||||
(int) getResources().getDimension(R.dimen.locationview_background_drawable_padding)});
|
||||
|
||||
mapboxMapOptions.myLocationAccuracyTint(Color.RED);
|
||||
mapboxMapOptions.myLocationAccuracyAlpha(155);
|
||||
|
||||
@@ -66,29 +67,29 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements
|
||||
|
||||
@Override
|
||||
protected void enableLocation(boolean enabled) {
|
||||
if (enabled) {
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
Location location = mapboxMap.getMyLocation();
|
||||
if (location != null) {
|
||||
onLocationChanged(location);
|
||||
} else {
|
||||
LocationSource.getLocationEngine(this).addLocationEngineListener(this);
|
||||
}
|
||||
} else {
|
||||
mapboxMap.setMyLocationEnabled(false);
|
||||
mapboxMap.setMyLocationEnabled(enabled);
|
||||
if (lostApiClient == null) {
|
||||
lostApiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build();
|
||||
lostApiClient.connect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
// Nothing
|
||||
LocationRequest request = LocationRequest.create()
|
||||
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
|
||||
.setInterval(5000)
|
||||
.setSmallestDisplacement(10);
|
||||
LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14));
|
||||
}
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,6 +114,11 @@ public class MyLocationDrawableActivity extends BaseLocationActivity implements
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
if (lostApiClient.isConnected()) {
|
||||
LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this);
|
||||
lostApiClient.disconnect();
|
||||
}
|
||||
lostApiClient.unregisterConnectionCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,7 +13,6 @@ import android.view.View;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
@@ -133,7 +132,6 @@ public class MyLocationTintActivity extends BaseLocationActivity implements Loca
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
LocationSource.getLocationEngine(this).addLocationEngineListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,7 +149,6 @@ public class MyLocationTintActivity extends BaseLocationActivity implements Loca
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
LocationSource.getLocationEngine(this).removeLocationEngineListener(this);
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.view.View;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngine;
|
||||
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class MyLocationToggleActivity extends BaseLocationActivity {
|
||||
|
||||
@@ -21,16 +17,11 @@ public class MyLocationToggleActivity extends BaseLocationActivity {
|
||||
private MapboxMap mapboxMap;
|
||||
private FloatingActionButton locationToggleFab;
|
||||
|
||||
private LocationEngine locationServices;
|
||||
private LocationEngineListener locationListener;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_my_location_toggle);
|
||||
|
||||
locationServices = LocationSource.getLocationEngine(this);
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@@ -51,6 +42,17 @@ public class MyLocationToggleActivity extends BaseLocationActivity {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enableLocation(boolean enabled) {
|
||||
Timber.e("Enabling location: %s", enabled);
|
||||
mapboxMap.setMyLocationEnabled(enabled);
|
||||
if (enabled) {
|
||||
locationToggleFab.setImageResource(R.drawable.ic_location_disabled);
|
||||
} else {
|
||||
locationToggleFab.setImageResource(R.drawable.ic_my_location);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
@@ -85,11 +87,6 @@ public class MyLocationToggleActivity extends BaseLocationActivity {
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
// Ensure no memory leak occurs if we register the location listener but the call hasn't
|
||||
// been made yet.
|
||||
if (locationListener != null) {
|
||||
locationServices.removeLocationEngineListener(locationListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,40 +95,4 @@ public class MyLocationToggleActivity extends BaseLocationActivity {
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enableLocation(boolean enabled) {
|
||||
if (enabled) {
|
||||
// To move the camera instantly, we attempt to get the last known location and either
|
||||
// ease or animate the camera to that position depending on the zoom level.
|
||||
Location lastLocation = LocationSource.getLocationEngine(this).getLastLocation();
|
||||
|
||||
if (lastLocation != null) {
|
||||
if (mapboxMap.getCameraPosition().zoom > 15.99) {
|
||||
mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(lastLocation)), 1000);
|
||||
} else {
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lastLocation), 16), 1000);
|
||||
}
|
||||
} else {
|
||||
locationListener = new LocationEngineListener() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (location != null) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 16));
|
||||
locationServices.removeLocationEngineListener(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
locationServices.addLocationEngineListener(locationListener);
|
||||
}
|
||||
locationToggleFab.setImageResource(R.drawable.ic_location_disabled);
|
||||
} else {
|
||||
locationToggleFab.setImageResource(R.drawable.ic_my_location);
|
||||
}
|
||||
mapboxMap.setMyLocationEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.ActionBar;
|
||||
@@ -13,14 +14,22 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.TrackingSettings;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapzen.android.lost.api.LocationListener;
|
||||
import com.mapzen.android.lost.api.LocationRequest;
|
||||
import com.mapzen.android.lost.api.LocationServices;
|
||||
import com.mapzen.android.lost.api.LostApiClient;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Test activity showcasing the different tracking modes the SDK exposes.
|
||||
@@ -29,7 +38,11 @@ import com.mapbox.mapboxsdk.testapp.R;
|
||||
* using gesture configurations.
|
||||
* </p>
|
||||
*/
|
||||
public class MyLocationTrackingModeActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
|
||||
public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
AdapterView.OnItemSelectedListener, OnMapReadyCallback, LostApiClient.ConnectionCallbacks, LocationListener {
|
||||
|
||||
// Testing for user defined LostApiClient
|
||||
private LostApiClient lostApiClient;
|
||||
|
||||
public static final int TRACKING_NONE_INDEX = 0;
|
||||
public static final int TRACKING_FOLLOW_INDEX = 1;
|
||||
@@ -41,6 +54,7 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
private MapboxMap mapboxMap;
|
||||
private Spinner locationSpinner;
|
||||
private Spinner bearingSpinner;
|
||||
private boolean firstRun = true;
|
||||
|
||||
private MenuItem dismissLocationTrackingOnGestureItem;
|
||||
private MenuItem dismissBearingTrackingOnGestureItem;
|
||||
@@ -51,7 +65,55 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_my_location_tracking);
|
||||
setupToolbar();
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(MapboxMap mapboxMap) {
|
||||
MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap;
|
||||
lostApiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build();
|
||||
lostApiClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected() {
|
||||
LocationRequest request = LocationRequest.create()
|
||||
.setPriority(LocationRequest.PRIORITY_LOW_POWER)
|
||||
.setInterval(5000)
|
||||
.setSmallestDisplacement(10);
|
||||
|
||||
Location location = LocationServices.FusedLocationApi.getLastLocation(lostApiClient);
|
||||
if (location != null) {
|
||||
setInitialLocation(location, 15);
|
||||
}
|
||||
LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
Timber.e("Location changed %s", location);
|
||||
if (firstRun) {
|
||||
setInitialLocation(location, 16);
|
||||
}
|
||||
}
|
||||
|
||||
private void setInitialLocation(Location location, double zoom) {
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), zoom));
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
setupSpinners(mapboxMap);
|
||||
firstRun = false;
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
@@ -60,72 +122,60 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
|
||||
locationSpinner = (Spinner) findViewById(R.id.spinner_location);
|
||||
ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource(
|
||||
actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item);
|
||||
locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
locationSpinner.setAdapter(locationTrackingAdapter);
|
||||
|
||||
bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
|
||||
ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource(
|
||||
actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item);
|
||||
bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
bearingSpinner.setAdapter(bearingTrackingAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
locationSpinner = (Spinner) findViewById(R.id.spinner_location);
|
||||
ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource(
|
||||
actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item);
|
||||
locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
locationSpinner.setAdapter(locationTrackingAdapter);
|
||||
private void setupSpinners(@NonNull MapboxMap mapboxMap) {
|
||||
locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
setCheckBoxes();
|
||||
|
||||
bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
|
||||
ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource(
|
||||
actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item);
|
||||
bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
bearingSpinner.setAdapter(bearingTrackingAdapter);
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() {
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap;
|
||||
|
||||
locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
setCheckBoxes();
|
||||
|
||||
mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() {
|
||||
@Override
|
||||
public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) {
|
||||
locationSpinner.setOnItemSelectedListener(null);
|
||||
switch (myLocationTrackingMode) {
|
||||
case MyLocationTracking.TRACKING_NONE:
|
||||
locationSpinner.setSelection(TRACKING_NONE_INDEX);
|
||||
break;
|
||||
case MyLocationTracking.TRACKING_FOLLOW:
|
||||
locationSpinner.setSelection(TRACKING_FOLLOW_INDEX);
|
||||
break;
|
||||
}
|
||||
locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
}
|
||||
});
|
||||
|
||||
mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() {
|
||||
@Override
|
||||
public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) {
|
||||
bearingSpinner.setOnItemSelectedListener(null);
|
||||
switch (myBearingTrackingMode) {
|
||||
case MyBearingTracking.NONE:
|
||||
bearingSpinner.setSelection(BEARING_NONE_INDEX);
|
||||
break;
|
||||
|
||||
case MyBearingTracking.GPS:
|
||||
bearingSpinner.setSelection(BEARING_GPS_INDEX);
|
||||
break;
|
||||
|
||||
case MyBearingTracking.COMPASS:
|
||||
bearingSpinner.setSelection(BEARING_COMPASS_INDEX);
|
||||
break;
|
||||
}
|
||||
bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
}
|
||||
});
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) {
|
||||
locationSpinner.setOnItemSelectedListener(null);
|
||||
switch (myLocationTrackingMode) {
|
||||
case MyLocationTracking.TRACKING_NONE:
|
||||
locationSpinner.setSelection(TRACKING_NONE_INDEX);
|
||||
break;
|
||||
case MyLocationTracking.TRACKING_FOLLOW:
|
||||
locationSpinner.setSelection(TRACKING_FOLLOW_INDEX);
|
||||
break;
|
||||
}
|
||||
locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
}
|
||||
});
|
||||
|
||||
mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() {
|
||||
@Override
|
||||
public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) {
|
||||
bearingSpinner.setOnItemSelectedListener(null);
|
||||
switch (myBearingTrackingMode) {
|
||||
case MyBearingTracking.NONE:
|
||||
bearingSpinner.setSelection(BEARING_NONE_INDEX);
|
||||
break;
|
||||
|
||||
case MyBearingTracking.GPS:
|
||||
bearingSpinner.setSelection(BEARING_GPS_INDEX);
|
||||
break;
|
||||
|
||||
case MyBearingTracking.COMPASS:
|
||||
bearingSpinner.setSelection(BEARING_COMPASS_INDEX);
|
||||
break;
|
||||
}
|
||||
bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -186,6 +236,11 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this);
|
||||
if (lostApiClient.isConnected()) {
|
||||
lostApiClient.unregisterConnectionCallbacks(this);
|
||||
lostApiClient.disconnect();
|
||||
}
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,6 @@
|
||||
app:mapbox_myLocationTintColor="@color/primary"
|
||||
app:mapbox_myLocationAccuracyTintColor="@color/primary"
|
||||
app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
|
||||
app:mapbox_cameraZoom="15" />
|
||||
app:mapbox_cameraZoom="8" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:mapbox="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_id_location_source_lost"
|
||||
android:title="@string/menuitem_title_change_location_source_lost"
|
||||
mapbox:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_id_location_source_mock"
|
||||
android:title="@string/menuitem_title_change_location_source_mock"
|
||||
mapbox:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_id_location_source_null"
|
||||
android:title="@string/menuitem_title_change_location_source_null"
|
||||
mapbox:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
@@ -151,6 +151,9 @@
|
||||
<string name="menuitem_title_reset">Reset</string>
|
||||
<string name="menuitem_title_rotate_gesture_enabled">Enable rotate gestures</string>
|
||||
<string name="menuitem_title_scroll_gesture_enabled">Enable scroll gestures</string>
|
||||
<string name="menuitem_title_change_location_source_lost">Change to LOST location source</string>
|
||||
<string name="menuitem_title_change_location_source_mock">Change to mock location source</string>
|
||||
<string name="menuitem_title_change_location_source_null">Reset location source to null</string>
|
||||
|
||||
<!--Button-->
|
||||
<string name="button_camera_move">Move</string>
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
import com.mapbox.mapboxsdk.exceptions.MapboxConfigurationException;
|
||||
import com.mapbox.mapboxsdk.location.LocationSource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -24,11 +25,13 @@ public class MapboxTest {
|
||||
|
||||
private Context context;
|
||||
private Context appContext;
|
||||
private LocationSource locationSource;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
context = mock(Context.class);
|
||||
appContext = mock(Context.class);
|
||||
locationSource = mock(LocationSource.class);
|
||||
when(context.getApplicationContext()).thenReturn(appContext);
|
||||
}
|
||||
|
||||
@@ -80,7 +83,7 @@ public class MapboxTest {
|
||||
}
|
||||
|
||||
private void injectMapboxSingleton(String accessToken) {
|
||||
Mapbox mapbox = new Mapbox(appContext, accessToken);
|
||||
Mapbox mapbox = new Mapbox(appContext, accessToken, locationSource);
|
||||
try {
|
||||
Field field = Mapbox.class.getDeclaredField("INSTANCE");
|
||||
field.setAccessible(true);
|
||||
|
||||
@@ -21,8 +21,8 @@ ext {
|
||||
mapboxAndroidTelemetry : "com.mapbox.mapboxsdk:mapbox-android-telemetry:${mapboxServicesVersion}@aar",
|
||||
|
||||
// mapzen lost
|
||||
lost : 'com.mapzen.android:lost:3.0.0',
|
||||
|
||||
lost : 'com.mapzen.android:lost:3.0.1-20170607.212149-4',
|
||||
|
||||
// unit test
|
||||
junit : 'junit:junit:4.12',
|
||||
mockito : 'org.mockito:mockito-core:2.2.27',
|
||||
|
||||
Reference in New Issue
Block a user