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:
Tobrun
2017-06-09 10:00:00 +02:00
committed by GitHub
parent 233117fe57
commit 9f88e37366
20 changed files with 443 additions and 291 deletions

View File

@@ -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;
}
}

View File

@@ -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";
}

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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()
)
);

View File

@@ -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

View File

@@ -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() {

View File

@@ -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();

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);

View File

@@ -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',