summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Guardiola <guardiola31337@gmail.com>2017-04-20 20:10:29 +0200
committerGitHub <noreply@github.com>2017-04-20 20:10:29 +0200
commitc6be40b71b2f81f07e24c14f0b9624b0fcf85798 (patch)
tree276e05bd8c40a6852dfbfacf6345fb7d3bd0be09
parent97f2a448594d7f904f298c61ab7ba673418d36e5 (diff)
downloadqtlocation-mapboxgl-c6be40b71b2f81f07e24c14f0b9624b0fcf85798.tar.gz
[android] Add a way to use a custom location source (#8710)
* add a way to use a custom location source * add custom location engine example to test app
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java14
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java46
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java131
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java93
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_custom_location_engine.xml27
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml2
8 files changed, 315 insertions, 21 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index be301839eb..79d36667ff 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -37,10 +37,12 @@ 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;
import com.mapbox.mapboxsdk.style.sources.Source;
+import com.mapbox.services.android.telemetry.location.LocationEngine;
import com.mapbox.services.commons.geojson.Feature;
import java.lang.reflect.ParameterizedType;
@@ -1773,6 +1775,18 @@ 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) {
+ trackingSettings.setLocationSource(locationSource);
+ }
+
+ /**
* Sets a callback that's invoked when the location tracking mode changes.
*
* @param listener The callback that's invoked when the location tracking mode changes.
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
index 476f4554c1..25b60aa72d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
@@ -12,6 +12,7 @@ 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;
import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
@@ -26,6 +27,7 @@ public final class TrackingSettings {
private final UiSettings uiSettings;
private final FocalPointChangeListener focalPointChangedListener;
private final CameraZoomInvalidator zoomInvalidator;
+ private LocationEngine locationSource;
private LocationEngineListener myLocationListener;
private boolean myLocationEnabled;
@@ -45,6 +47,7 @@ public final class TrackingSettings {
}
void initialise(MapboxMapOptions options) {
+ locationSource = LocationSource.getLocationEngine(myLocationView.getContext());
setMyLocationEnabled(options.getLocationEnabled());
}
@@ -328,9 +331,9 @@ public final class TrackingSettings {
}
}
};
- LocationSource.getLocationEngine(myLocationView.getContext()).addLocationEngineListener(myLocationListener);
+ locationSource.addLocationEngineListener(myLocationListener);
} else {
- LocationSource.getLocationEngine(myLocationView.getContext()).removeLocationEngineListener(myLocationListener);
+ locationSource.removeLocationEngineListener(myLocationListener);
myLocationListener = null;
}
}
@@ -362,6 +365,11 @@ public final class TrackingSettings {
myLocationView.setEnabled(locationEnabled);
}
+ void setLocationSource(LocationEngine locationSource) {
+ this.locationSource = locationSource;
+ myLocationView.setLocationSource(locationSource);
+ }
+
void update() {
if (!myLocationView.isEnabled()) {
return;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
index d7f31b3faf..aecf3cc655 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
@@ -58,6 +58,7 @@ public class MyLocationView extends View {
private LatLng latLng;
private Location location;
+ private LocationEngine locationSource;
private long locationUpdateTimestamp;
private float previousDirection;
@@ -320,8 +321,7 @@ public class MyLocationView extends View {
if (location != null) {
setCompass(location.getBearing() - bearing);
}
- } else if (myBearingTrackingMode == MyBearingTracking.COMPASS
- && compassListener.isSensorAvailable()) {
+ } else if (myBearingTrackingMode == MyBearingTracking.COMPASS && compassListener.isSensorAvailable()) {
setCompass(magneticHeading - bearing);
}
}
@@ -335,8 +335,7 @@ public class MyLocationView extends View {
}
public void onStart() {
- if (myBearingTrackingMode == MyBearingTracking.COMPASS
- && compassListener.isSensorAvailable()) {
+ if (myBearingTrackingMode == MyBearingTracking.COMPASS && compassListener.isSensorAvailable()) {
compassListener.onResume();
}
if (isEnabled()) {
@@ -369,7 +368,8 @@ public class MyLocationView extends View {
}
if (userLocationListener != null) {
- LocationSource.getLocationEngine(getContext()).removeLocationEngineListener(userLocationListener);
+ locationSource.removeLocationEngineListener(userLocationListener);
+ locationSource = null;
userLocationListener = null;
}
}
@@ -419,29 +419,32 @@ public class MyLocationView extends View {
* @param enableGps true if GPS is to be enabled, false if GPS is to be disabled
*/
private void toggleGps(boolean enableGps) {
- LocationEngine locationEngine = LocationSource.getLocationEngine(getContext());
+ if (locationSource == null) {
+ locationSource = LocationSource.getLocationEngine(this.getContext());
+ }
+
if (enableGps) {
// Set an initial location if one available
- Location lastLocation = locationEngine.getLastLocation();
+ Location lastLocation = locationSource.getLastLocation();
if (lastLocation != null) {
setLocation(lastLocation);
}
if (userLocationListener == null) {
- userLocationListener = new GpsLocationListener(this);
+ userLocationListener = new GpsLocationListener(this, locationSource);
}
- locationEngine.addLocationEngineListener(userLocationListener);
- locationEngine.activate();
+ locationSource.addLocationEngineListener(userLocationListener);
+ locationSource.activate();
} else {
// Disable location and user dot
location = null;
- locationEngine.removeLocationEngineListener(userLocationListener);
- locationEngine.deactivate();
+ locationSource.removeLocationEngineListener(userLocationListener);
+ locationSource.deactivate();
}
- locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
+ locationSource.setPriority(LocationEnginePriority.HIGH_ACCURACY);
}
public Location getLocation() {
@@ -460,8 +463,7 @@ public class MyLocationView extends View {
public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
this.myBearingTrackingMode = myBearingTrackingMode;
- if (myBearingTrackingMode == MyBearingTracking.COMPASS
- && compassListener.isSensorAvailable()) {
+ if (myBearingTrackingMode == MyBearingTracking.COMPASS && compassListener.isSensorAvailable()) {
compassListener.onResume();
} else {
compassListener.onPause();
@@ -561,22 +563,28 @@ public class MyLocationView extends View {
contentPaddingY = (padding[1] - padding[3]) / 2;
}
+ public void setLocationSource(LocationEngine locationSource) {
+ this.locationSource = locationSource;
+ }
+
private static class GpsLocationListener implements LocationEngineListener {
private WeakReference<MyLocationView> userLocationView;
+ private WeakReference<LocationEngine> locationSource;
- GpsLocationListener(MyLocationView myLocationView) {
+ GpsLocationListener(MyLocationView myLocationView, LocationEngine locationEngine) {
userLocationView = new WeakReference<>(myLocationView);
+ locationSource = new WeakReference<>(locationEngine);
}
@Override
public void onConnected() {
MyLocationView locationView = userLocationView.get();
if (locationView != null) {
- LocationEngine locationSource = LocationSource.getLocationEngine(locationView.getContext());
- Location location = locationSource.getLastLocation();
+ LocationEngine locationEngine = locationSource.get();
+ Location location = locationEngine.getLastLocation();
locationView.setLocation(location);
- locationSource.requestLocationUpdates();
+ locationEngine.requestLocationUpdates();
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index eee7c86403..2d2a262055 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -247,6 +247,17 @@
android:value=".activity.FeatureOverviewActivity"/>
</activity>
<activity
+ android:name=".activity.userlocation.CustomLocationEngineActivity"
+ android:description="@string/description_custom_location_engine"
+ android:label="@string/activity_custom_location_engine">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_userlocation"/>
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity"/>
+ </activity>
+ <activity
android:name=".activity.annotation.PolygonActivity"
android:description="@string/description_polygon"
android:label="@string/activity_polygon">
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java
new file mode 100644
index 0000000000..f4268830a0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/CustomLocationEngineActivity.java
@@ -0,0 +1,131 @@
+package com.mapbox.mapboxsdk.testapp.activity.userlocation;
+
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v4.app.ActivityCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+
+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.permissions.PermissionsManager;
+
+public class CustomLocationEngineActivity extends AppCompatActivity {
+
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private FloatingActionButton locationToggleFab;
+
+ private LocationEngine locationServices;
+
+ private static final int PERMISSIONS_LOCATION = 0;
+
+ @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);
+ }
+ });
+
+ locationToggleFab = (FloatingActionButton) findViewById(R.id.fabLocationToggle);
+ locationToggleFab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ toggleGps(!mapboxMap.isMyLocationEnabled());
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @UiThread
+ public 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);
+ } else {
+ enableLocation(true);
+ }
+ } else {
+ enableLocation(false);
+ }
+ }
+
+ private void enableLocation(boolean enabled) {
+ mapboxMap.setMyLocationEnabled(enabled);
+ if (enabled) {
+ locationToggleFab.setImageResource(R.drawable.ic_location_disabled);
+ } else {
+ locationToggleFab.setImageResource(R.drawable.ic_my_location);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ enableLocation(true);
+ }
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java
new file mode 100644
index 0000000000..b87c723fda
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java
@@ -0,0 +1,93 @@
+package com.mapbox.mapboxsdk.testapp.activity.userlocation;
+
+
+import android.location.Location;
+import android.os.Handler;
+
+import com.mapbox.services.android.telemetry.location.LocationEngine;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
+
+/**
+ * Sample LocationEngine that provides mocked locations simulating GPS updates
+ */
+public class MockLocationEngine extends LocationEngine {
+
+ // 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 Handler handler;
+ int currentIndex;
+
+ public MockLocationEngine() {
+ super();
+ }
+
+ @Override
+ public void activate() {
+ currentIndex = 0;
+
+ // "Connection" is immediate here
+ for (LocationEngineListener listener : locationListeners) {
+ listener.onConnected();
+ }
+ }
+
+ @Override
+ public void deactivate() {
+ handler = null;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return true; // Always connected
+ }
+
+ @Override
+ public Location getLastLocation() {
+ return getNextLocation();
+ }
+
+ @Override
+ public void requestLocationUpdates() {
+ // Fake regular updates with a handler
+ handler = new Handler();
+ handler.postDelayed(new LocationUpdateRunnable(), UPDATE_INTERVAL_MS);
+ }
+
+ @Override
+ public void removeLocationUpdates() {
+ handler.removeCallbacksAndMessages(null);
+ }
+
+ 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 class LocationUpdateRunnable implements Runnable {
+ @Override
+ public void run() {
+ // Notify of an update
+ Location location = getNextLocation();
+ for (LocationEngineListener listener : locationListeners) {
+ listener.onLocationChanged(location);
+ }
+
+ if (handler != null) {
+ // Schedule the next update
+ handler.postDelayed(new LocationUpdateRunnable(), UPDATE_INTERVAL_MS);
+ }
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_custom_location_engine.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_custom_location_engine.xml
new file mode 100644
index 0000000000..e9f461c7ee
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_custom_location_engine.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@id/coordinator_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:mapbox_cameraTargetLat="40.416872"
+ app:mapbox_cameraTargetLng="-3.703807"
+ app:mapbox_cameraZoom="4"/>
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/fabLocationToggle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|bottom"
+ android:layout_margin="@dimen/fab_margin"
+ android:src="@drawable/ic_my_location"
+ tools:backgroundTint="@color/primary"/>
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 5e0d25d2ec..3df14caf0c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -28,6 +28,7 @@
<string name="activity_user_tracking_customization">User location drawable</string>
<string name="activity_user_dot_color">User location tint color</string>
<string name="activity_user_location_toggle">User location toggle</string>
+ <string name="activity_custom_location_engine">Custom location engine</string>
<string name="activity_custom_layer">Custom Layer</string>
<string name="activity_map_padding">Map Padding</string>
<string name="activity_debug_mode">Debug Mode</string>
@@ -62,6 +63,7 @@
<string name="description_user_location_customization">Customize the location of the user</string>
<string name="description_user_location_dot_color">Customize the user location color</string>
<string name="description_user_location_toggle">Toggle location of the user on and off</string>
+ <string name="description_custom_location_engine">Customize location engine</string>
<string name="description_custom_layer">Overlay a custom native layer on the map</string>
<string name="description_info_window_adapter">Learn how to create a custom InfoWindow</string>
<string name="description_cameraposition">CameraPosition capabilities</string>