summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/INSTALL_LINUX.md2
-rw-r--r--platform/android/INSTALL_OSX.md2
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle5
-rw-r--r--platform/android/MapboxGLAndroidSDK/proguard-rules.pro7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/AndroidManifest.xml1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java38
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java41
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java28
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java44
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java (renamed from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java)2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java (renamed from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java)54
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java15
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java18
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java11
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationService.java166
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java133
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java795
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java694
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java116
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java27
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java121
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java207
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java36
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java (renamed from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassView.java)20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/UserLocationView.java (renamed from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UserLocationView.java)88
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java59
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java532
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java71
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java145
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ApiAccess.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_telemetry_view.xml21
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml14
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml3
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml28
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/build.gradle6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CameraActivityTest.java35
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DirectionsActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivityTest.java35
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/GeocoderActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/InfoWindowConcurrentActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivityTest.java (renamed from platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/VisibleCoordinateBoundsActivityTest.java)2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityScreenTest.java64
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityTest.java28
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivityTest.java34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ScrollByActivityTest.java26
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivityTest.java35
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java29
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java17
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml19
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DirectionsActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivity.java11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivity.java145
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowActivity.java31
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowAdapterActivity.java31
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java35
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapFragmentActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivity.java162
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivity.java10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java40
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TiltActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarker.java18
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarkerOptions.java68
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_arsenal.pngbin0 -> 1178 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_chelsea.pngbin0 -> 1692 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_dynamic_marker.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_map_padding.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml45
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_concurrent.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_padding.xml49
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_mapboxmap.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_padding.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/dimens.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java55
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java86
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java119
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java (renamed from platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/PolygonTest.java)2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java (renamed from platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/PolylineTest.java)2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java77
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java7
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java42
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java390
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MarkerTest.java76
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java53
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java30
-rw-r--r--platform/android/mapboxgl-app.gypi4
-rw-r--r--platform/android/src/asset_file_source.cpp4
-rw-r--r--platform/android/src/http_request_android.cpp21
-rwxr-xr-xplatform/android/src/jni.cpp51
-rwxr-xr-xplatform/android/src/native_map_view.cpp2
130 files changed, 4762 insertions, 1306 deletions
diff --git a/platform/android/INSTALL_LINUX.md b/platform/android/INSTALL_LINUX.md
index 219bb7d0e9..353d0269d0 100644
--- a/platform/android/INSTALL_LINUX.md
+++ b/platform/android/INSTALL_LINUX.md
@@ -21,7 +21,7 @@ In the Android SDK Manager also select and install "Android Support Repository"
_The demo applications use Mapbox vector tiles, which require a Mapbox account and API access token. Obtain an access token on the [Mapbox account page](https://www.mapbox.com/studio/account/tokens/)._
-gradle will take the value of the `MAPBOX_ACCESS_TOKEN` environ variable and save it to `"MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml` where the app will read it from.
+gradle will take the value of the `MAPBOX_ACCESS_TOKEN` environ variable and save it to `"MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml` where the app will read it from. Otherwise, you can edit `developer-config.xml` and add the value manually as `mapbox_access_token`.
## Building
diff --git a/platform/android/INSTALL_OSX.md b/platform/android/INSTALL_OSX.md
index f82bb80da0..00096ebc60 100644
--- a/platform/android/INSTALL_OSX.md
+++ b/platform/android/INSTALL_OSX.md
@@ -22,7 +22,7 @@ By default, the Android SDK will be installed to `/Users/<user>/Library/Android/
_The test application (used for development purposes) uses Mapbox vector tiles, which require a Mapbox account and API access token. Obtain a free access token on the [Mapbox account page](https://www.mapbox.com/studio/account/tokens/)._
If you start Android Studio from your terminal, gradle will take the value of the `MAPBOX_ACCESS_TOKEN` environment variable and save it to `MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml` where the app will read it from. Otherwise,
-you can edit `developer-config.xml` and add the value manually.
+you can edit `developer-config.xml` and add the value manually as `mapbox_access_token`.
## Developing In Android Studio
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 8b44873a27..b9e294966e 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -25,7 +25,7 @@ dependencies {
compile "com.android.support:support-annotations:${supportLibVersion}"
compile "com.android.support:support-v4:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
- compile 'com.squareup.okhttp3:okhttp:3.0.1'
+ compile 'com.squareup.okhttp3:okhttp:3.1.2'
compile 'com.mapzen.android:lost:1.0.1'
}
@@ -66,6 +66,9 @@ android {
consumerProguardFiles 'proguard-rules.pro'
}
}
+
+// resourcePrefix 'mapbox_'
+
}
configurations {
diff --git a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
index 85754a75a5..98647f5518 100644
--- a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
+++ b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
@@ -15,8 +15,11 @@
# Package: http
-keep class com.mapbox.mapboxsdk.http.** { *; }
-# Package views
--keep class com.mapbox.mapboxsdk.views.** { *; }
+# Package maps
+-keep class com.mapbox.mapboxsdk.maps.** { *; }
+
+# Package telemetry
+-keep class com.mapbox.mapboxsdk.telemetry.** { *; }
# Package layers
-keep class com.mapbox.mapboxsdk.layers.** { *; }
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDK/src/main/AndroidManifest.xml
index 1b8b54c86f..0307d462c8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/AndroidManifest.xml
@@ -5,5 +5,6 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
</manifest>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java
new file mode 100644
index 0000000000..5b1eebdb1b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java
@@ -0,0 +1,38 @@
+package com.mapbox.mapboxsdk.annotations;
+
+import android.os.Parcelable;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOptions<U, T>> implements Parcelable {
+
+ protected LatLng position;
+ protected String snippet;
+ protected String title;
+ protected Icon icon;
+
+ public T position(LatLng position) {
+ this.position = position;
+ return getThis();
+ }
+
+ public T snippet(String snippet) {
+ this.snippet = snippet;
+ return getThis();
+ }
+
+ public T title(String title) {
+ this.title = title;
+ return getThis();
+ }
+
+ public T icon(Icon icon) {
+ this.icon = icon;
+ return getThis();
+ }
+
+ public abstract T getThis();
+
+ public abstract U getMarker();
+
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
index bee4ec47c5..d7d41b98be 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
@@ -150,4 +150,8 @@ public final class IconFactory {
}
return fromInputStream(is);
}
+
+ public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) {
+ return new Icon(iconId, bitmap);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
index 9c79ffcbd9..d8763e321d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
@@ -53,22 +53,35 @@ public class InfoWindow {
mIsVisible = false;
mView = new WeakReference<>(view);
- // default behavior: close it when clicking on the tooltip:
- view.setOnTouchListener(new View.OnTouchListener() {
+ view.setOnClickListener(new View.OnClickListener() {
@Override
- public boolean onTouch(View v, MotionEvent e) {
- if (e.getAction() == MotionEvent.ACTION_UP) {
+ public void onClick(View v) {
+ MapboxMap mapboxMap = mMapboxMap.get();
+ if (mapboxMap != null) {
+ MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener = mapboxMap.getOnInfoWindowClickListener();
boolean handledDefaultClick = false;
- MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener =
- mMapboxMap.get().getOnInfoWindowClickListener();
if (onInfoWindowClickListener != null) {
- handledDefaultClick = onInfoWindowClickListener.onMarkerClick(getBoundMarker());
+ handledDefaultClick = onInfoWindowClickListener.onInfoWindowClick(getBoundMarker());
}
if (!handledDefaultClick) {
+ // default behavior: close it when clicking on the tooltip:
close();
}
}
+ }
+ });
+
+ view.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ MapboxMap mapboxMap = mMapboxMap.get();
+ if (mapboxMap != null) {
+ MapboxMap.OnInfoWindowLongClickListener listener = mapboxMap.getOnInfoWindowLongClickListener();
+ if (listener != null) {
+ listener.onInfoWindowLongClick(getBoundMarker());
+ }
+ }
return true;
}
});
@@ -179,11 +192,10 @@ public class InfoWindow {
if (mIsVisible) {
mIsVisible = false;
View view = mView.get();
- if (view != null) {
+ if (view != null && view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
- setBoundMarker(null);
- onClose();
}
+ onClose();
}
return this;
}
@@ -210,7 +222,12 @@ public class InfoWindow {
private void onClose() {
MapboxMap mapboxMap = mMapboxMap.get();
if (mapboxMap != null) {
+ MapboxMap.OnInfoWindowCloseListener listener = mapboxMap.getOnInfoWindowCloseListener();
+ if (listener != null) {
+ listener.onInfoWindowClose(getBoundMarker());
+ }
mapboxMap.deselectMarker(getBoundMarker());
+ setBoundMarker(null);
}
}
@@ -237,4 +254,8 @@ public class InfoWindow {
}
}
+ boolean isVisible() {
+ return mIsVisible;
+ }
+
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
index 27c9c03697..c2683cbb56 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
@@ -15,7 +15,7 @@ import com.mapbox.mapboxsdk.maps.MapView;
* An {@link InfoWindow} can be shown when a Marker is pressed
* <p/>
*/
-public final class Marker extends Annotation {
+public class Marker extends Annotation {
private LatLng position;
private String snippet;
@@ -32,6 +32,13 @@ public final class Marker extends Annotation {
super();
}
+ public Marker(BaseMarkerOptions baseMarkerOptions) {
+ position = baseMarkerOptions.position;
+ snippet = baseMarkerOptions.snippet;
+ icon = baseMarkerOptions.icon;
+ title = baseMarkerOptions.title;
+ }
+
public LatLng getPosition() {
return position;
}
@@ -61,8 +68,17 @@ public final class Marker extends Annotation {
return infoWindowShown;
}
- void setPosition(LatLng position) {
+ /**
+ * Sets the position.
+ *
+ * @param position new position
+ */
+ public void setPosition(LatLng position) {
this.position = position;
+ MapboxMap map = getMapboxMap();
+ if (map != null) {
+ map.updateMarker(this);
+ }
}
void setSnippet(String snippet) {
@@ -70,10 +86,16 @@ public final class Marker extends Annotation {
}
/**
- * Do not use this method. Used internally by the SDK.
+ * Sets the icon.
+ *
+ * @param icon The icon to be used as Marker image
*/
public void setIcon(@Nullable Icon icon) {
this.icon = icon;
+ MapboxMap map = getMapboxMap();
+ if (map != null) {
+ map.updateMarker(this);
+ }
}
public Icon getIcon() {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
index a83a6991b2..5cc54cd1ca 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
@@ -12,9 +12,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
* <p>
* Builder for composing {@link com.mapbox.mapboxsdk.annotations.Marker} objects.
* </p>
- *
+ * <p/>
* <h3>Example</h3>
- *
+ * <p/>
* <pre>
* mMapView.addMarker(new MarkerOptions()
* .title("Intersection")
@@ -22,7 +22,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
* .position(new LatLng(38.9002073, -77.03364419)));
* </pre>
*/
-public final class MarkerOptions implements Parcelable {
+public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions> implements Parcelable {
public static final Parcelable.Creator<MarkerOptions> CREATOR
= new Parcelable.Creator<MarkerOptions>() {
@@ -47,6 +47,11 @@ public final class MarkerOptions implements Parcelable {
}
@Override
+ public MarkerOptions getThis() {
+ return this;
+ }
+
+ @Override
public int describeContents() {
return 0;
}
@@ -72,43 +77,27 @@ public final class MarkerOptions implements Parcelable {
* @return Marker The build marker
*/
public Marker getMarker() {
+ marker.setPosition(position);
+ marker.setSnippet(snippet);
+ marker.setTitle(title);
+ marker.setIcon(icon);
return marker;
}
public LatLng getPosition() {
- return marker.getPosition();
+ return position;
}
public String getSnippet() {
- return marker.getSnippet();
+ return snippet;
}
public String getTitle() {
- return marker.getTitle();
+ return title;
}
public Icon getIcon() {
- return marker.getIcon();
- }
-
- public MarkerOptions position(LatLng position) {
- marker.setPosition(position);
- return this;
- }
-
- public MarkerOptions snippet(String snippet) {
- marker.setSnippet(snippet);
- return this;
- }
-
- public MarkerOptions icon(@Nullable Icon icon) {
- marker.setIcon(icon);
- return this;
- }
-
- public MarkerOptions title(String title) {
- marker.setTitle(title);
- return this;
+ return icon;
}
@Override
@@ -125,7 +114,6 @@ public final class MarkerOptions implements Parcelable {
if (getIcon() != null ? !getIcon().equals(marker.getIcon()) : marker.getIcon() != null)
return false;
return !(getTitle() != null ? !getTitle().equals(marker.getTitle()) : marker.getTitle() != null);
-
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
index 004e7f5f84..ec2f0eb316 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
@@ -9,7 +9,6 @@ import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MathConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
import com.mapbox.mapboxsdk.utils.MathUtils;
public final class CameraPosition implements Parcelable {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
index 0f3e710134..c6852624ef 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.camera;
import android.support.annotation.NonNull;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
index cad5152316..df156961a0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.camera;
import android.graphics.Point;
import android.graphics.PointF;
@@ -6,15 +6,17 @@ import android.graphics.RectF;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
-import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.Projection;
+import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.utils.MathUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-public class CameraUpdateFactory {
+public final class CameraUpdateFactory {
/**
* Returns a CameraUpdate that moves the camera to a specified CameraPosition.
@@ -144,7 +146,7 @@ public class CameraUpdateFactory {
// CameraUpdate types
//
- public static class CameraPositionUpdate implements CameraUpdate {
+ static final class CameraPositionUpdate implements CameraUpdate {
private final float bearing;
private final LatLng target;
@@ -189,7 +191,7 @@ public class CameraUpdateFactory {
}
}
- public static class CameraBoundsUpdate implements CameraUpdate {
+ static final class CameraBoundsUpdate implements CameraUpdate {
private LatLngBounds bounds;
private RectF padding;
@@ -217,39 +219,40 @@ public class CameraUpdateFactory {
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- MapView mapView = mapboxMap.getMapView();
+ // Get required objects
+ Projection projection = mapboxMap.getProjection();
+ UiSettings uiSettings = mapboxMap.getUiSettings();
RectF padding = getPadding();
- // Calculate the bounds of the possibly rotated shape with respect to the viewport.
+ // Calculate the bounds of the possibly rotated shape with respect to the viewport
PointF nePixel = new PointF(-10000, -10000);
- PointF swPixel = new PointF(1000, 10000);
- float viewportHeight = mapView.getHeight();
+ PointF swPixel = new PointF(10000, 10000);
+ float viewportHeight = uiSettings.getHeight();
for (LatLng latLng : getBounds().toLatLngs()) {
- PointF pixel = mapView.toScreenLocation(latLng);
+ PointF pixel = projection.toScreenLocation(latLng);
swPixel.x = Math.min(swPixel.x, pixel.x);
nePixel.x = Math.max(nePixel.x, pixel.x);
swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
}
+ // Calculate wid=th/height
float width = nePixel.x - swPixel.x;
float height = nePixel.y - swPixel.y;
- // Calculate the zoom level.
- float scaleX = (mapView.getWidth() - padding.left - padding.right) / width;
- float scaleY = (mapView.getHeight() - padding.top - padding.bottom) / height;
+ // Calculate the zoom level
+ float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
+ float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
float minScale = scaleX < scaleY ? scaleX : scaleY;
- double zoom = Math.log(mapView.getScale() * minScale) / Math.log(2);
- zoom = MathUtils.clamp(zoom, (float) mapView.getMinZoom(), (float) mapView.getMaxZoom());
+ double zoom = projection.calculateZoom(minScale);
+ zoom = MathUtils.clamp(zoom, (float) uiSettings.getMinZoom(), (float) uiSettings.getMaxZoom());
- // Calculate the center point of a virtual bounds that is extended in all directions by padding.
+ // Calculate the center point
PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
-
centerPixel.y = viewportHeight - centerPixel.y;
-
- LatLng center = mapboxMap.getProjection().fromScreenLocation(centerPixel);
+ LatLng center = projection.fromScreenLocation(centerPixel);
return new CameraPosition.Builder()
.target(center)
@@ -260,7 +263,7 @@ public class CameraUpdateFactory {
}
}
- public static class CameraMoveUpdate implements CameraUpdate {
+ static final class CameraMoveUpdate implements CameraUpdate {
private float x;
private float y;
@@ -272,15 +275,16 @@ public class CameraUpdateFactory {
@Override
public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- MapView mapView = mapboxMap.getMapView();
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ Projection projection = mapboxMap.getProjection();
// Calculate the new center point
- float viewPortWidth = mapView.getWidth();
- float viewPortHeight = mapView.getHeight();
+ float viewPortWidth = uiSettings.getWidth();
+ float viewPortHeight = uiSettings.getHeight();
PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
// Convert point to LatLng
- LatLng latLng = mapView.fromScreenLocation(targetPoint);
+ LatLng latLng = projection.fromScreenLocation(targetPoint);
CameraPosition cameraPosition = mapboxMap.getCameraPosition();
return new CameraPosition.Builder()
@@ -292,7 +296,7 @@ public class CameraUpdateFactory {
}
}
- public static class ZoomUpdate implements CameraUpdate {
+ static final class ZoomUpdate implements CameraUpdate {
@IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
@Retention(RetentionPolicy.SOURCE)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
index 33ebfca2fa..f04087818b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
@@ -18,6 +18,16 @@ public class MapboxConstants {
public static final String KEY_META_DATA_MANIFEST = "com.mapbox.AccessToken";
/**
+ * Key used to store staging data server url in AndroidManifest.xml
+ */
+ public static final String KEY_META_DATA_STAGING_SERVER = "com.mapbox.TestEventsServer";
+
+ /**
+ * Key used to store staging data server access token in AndroidManifest.xml
+ */
+ public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken";
+
+ /**
* Default animation time
*/
public static final int ANIMATION_DURATION = 300;
@@ -58,6 +68,7 @@ public class MapboxConstants {
public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions";
// Save instance state keys
+ public static final String STATE_HAS_SAVED_STATE = "savedState";
public static final String STATE_CAMERA_POSITION = "cameraPosition";
public static final String STATE_ZOOM_ENABLED = "zoomEnabled";
public static final String STATE_SCROLL_ENABLED = "scrollEnabled";
@@ -91,4 +102,8 @@ public class MapboxConstants {
public static final String STATE_ATTRIBUTION_ENABLED = "atrrEnabled";
public static final String TAG = "MapboxMap";
+
+ public static final String MAPBOX_SHARED_PREFERENCES_FILE = "MapboxSharedPreferences";
+ public static final String MAPBOX_SHARED_PREFERENCE_KEY_VENDORID = "mapboxVendorId";
+ public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED = "mapboxTelemetryEnabled";
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
index 2374a98fc1..383a85417c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
@@ -3,7 +3,7 @@ package com.mapbox.mapboxsdk.constants;
import android.support.annotation.IntDef;
import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.UserLocationView;
+import com.mapbox.mapboxsdk.maps.widgets.UserLocationView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
index a8008d3742..9b0ae7285e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
@@ -3,7 +3,7 @@ package com.mapbox.mapboxsdk.constants;
import android.support.annotation.IntDef;
import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.UserLocationView;
+import com.mapbox.mapboxsdk.maps.widgets.UserLocationView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
new file mode 100644
index 0000000000..54908aa58b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
@@ -0,0 +1,18 @@
+package com.mapbox.mapboxsdk.exceptions;
+
+import android.os.Bundle;
+import com.mapbox.mapboxsdk.maps.MapView;
+
+/**
+ * A {@code TelemetryServiceNotConfiguredException} is thrown by {@link MapView} when it checks and finds that
+ * TelemetryService has not been configured in the app's AndroidManifest.xml {@link MapView#onCreate(Bundle)}
+ *
+ * @see MapView#onCreate(Bundle)
+ */
+public class TelemetryServiceNotConfiguredException extends RuntimeException {
+
+ public TelemetryServiceNotConfiguredException() {
+ super("Using Mapbox Android SDK requires configuring TelemetryService. See the INSTALL.md");
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java
index 349120d1f3..de562c3632 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java
@@ -67,6 +67,7 @@ public class VisibleRegion implements Parcelable {
* If the other object is actually a pointer to this object,
* or if all four corners and the bounds of the two objects are the same,
* this method returns true. Otherwise, this method returns false.
+ *
* @param o The Object to compare with.
* @return true if both objects are the same object.
*/
@@ -89,7 +90,15 @@ public class VisibleRegion implements Parcelable {
@Override
public String toString() {
- return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight [" + nearRight + "], latLngBounds ["+latLngBounds+"]]";
+ return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight [" + nearRight + "], latLngBounds [" + latLngBounds + "]]";
+ }
+
+ @Override
+ public int hashCode() {
+ return ((farLeft.hashCode() + 90)
+ + ((farRight.hashCode() + 90) * 1000)
+ + ((nearLeft.hashCode() + 180) * 1000000)
+ + ((nearRight.hashCode() + 180) * 1000000000));
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
index c385820423..f787085d2f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
@@ -2,12 +2,15 @@ package com.mapbox.mapboxsdk.location;
import android.location.Location;
+/**
+ * Callback interface for when a location change occurs.
+ */
public interface LocationListener {
/**
- * Callback method for receiving location updates from LocationServices.
+ * Callback method for receiving location updates from LocationService.
* @param location The new Location data
*/
- public void onLocationChanged(Location location);
+ void onLocationChanged(Location location);
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationService.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationService.java
new file mode 100644
index 0000000000..f459b5ad53
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationService.java
@@ -0,0 +1,166 @@
+package com.mapbox.mapboxsdk.location;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationManager;
+import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
+import android.util.Log;
+
+import com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver;
+import com.mapzen.android.lost.api.LocationRequest;
+import com.mapzen.android.lost.api.LostApiClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LocationService implements com.mapzen.android.lost.api.LocationListener {
+
+ private static final String TAG = "LocationService";
+
+ private static LocationService instance;
+
+ private Context context;
+ private LostApiClient locationClient;
+ private Location lastLocation;
+
+ private List<LocationListener> locationListeners;
+
+ private boolean isGPSEnabled;
+
+ /**
+ * Private constructor for singleton LocationService
+ */
+ private LocationService(Context context) {
+ super();
+ this.context = context;
+ // Setup location services
+ locationClient = new LostApiClient.Builder(context).build();
+ locationListeners = new ArrayList<>();
+ }
+
+ /**
+ * Primary (singleton) access method for LocationService
+ *
+ * @param context Context
+ * @return LocationService
+ */
+ public static LocationService getInstance(@NonNull final Context context) {
+ if (instance == null) {
+ instance = new LocationService(context.getApplicationContext());
+ }
+ return instance;
+ }
+
+ /**
+ * Enabled / Disable GPS focused location tracking
+ *
+ * @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
+ */
+ public void toggleGPS(boolean enableGPS) {
+ if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) &&
+ (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
+ Log.w(TAG, "Location Permissions Not Granted Yet. Try again after requesting.");
+ return;
+ }
+
+ // Disconnect
+ if (locationClient.isConnected()) {
+ // Disconnect first to ensure that the new requests are GPS
+ com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
+ locationClient.disconnect();
+ }
+
+ // Setup Fresh
+ locationClient.connect();
+ Location lastLocation = com.mapzen.android.lost.api.LocationServices.FusedLocationApi.getLastLocation();
+ if (lastLocation != null) {
+ this.lastLocation = lastLocation;
+ }
+
+ LocationRequest locationRequest;
+
+ if (enableGPS) {
+ // LocationRequest Tuned for GPS
+ locationRequest = LocationRequest.create()
+ .setFastestInterval(1000)
+ .setSmallestDisplacement(3.0f)
+ .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+
+ com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
+ } else {
+ // LocationRequest Tuned for PASSIVE
+ locationRequest = LocationRequest.create()
+ .setFastestInterval(1000)
+ .setSmallestDisplacement(3.0f)
+ .setPriority(LocationRequest.PRIORITY_NO_POWER);
+
+ com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
+ }
+
+ isGPSEnabled = enableGPS;
+ }
+
+ /**
+ * Returns if the GPS sensor is currently enabled
+ *
+ * @return active state of the GPS
+ */
+ public boolean isGPSEnabled() {
+ return isGPSEnabled;
+ }
+
+ /**
+ * Called when the location has changed.
+ *
+ * @param location The updated location
+ */
+ @Override
+ public void onLocationChanged(Location location) {
+ Log.i(TAG, "onLocationChanged()..." + location);
+ this.lastLocation = location;
+
+ // Update Listeners
+ for (LocationListener listener : this.locationListeners) {
+ listener.onLocationChanged(location);
+ }
+
+ // Update the Telemetry Receiver
+ Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING);
+ locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
+ context.sendBroadcast(locIntent);
+ }
+
+ /**
+ * Last known location
+ *
+ * @return Last known location data
+ */
+ public Location getLastLocation() {
+ return lastLocation;
+ }
+
+ /**
+ * Registers a LocationListener to receive location updates
+ *
+ * @param locationListener LocationListener
+ */
+ public void addLocationListener(@NonNull LocationListener locationListener) {
+ if (!this.locationListeners.contains(locationListener)) {
+ this.locationListeners.add(locationListener);
+ }
+ }
+
+ /**
+ * Unregister a LocationListener to stop receiving location updates
+ *
+ * @param locationListener LocationListener to remove
+ * @return True if LocationListener was found and removed, False if it was not
+ */
+ public boolean removeLocationListener(@NonNull LocationListener locationListener) {
+ return this.locationListeners.remove(locationListener);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
deleted file mode 100644
index ac2ab64076..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.content.Context;
-import android.location.Location;
-import android.support.annotation.NonNull;
-import com.mapzen.android.lost.api.LocationRequest;
-import com.mapzen.android.lost.api.LostApiClient;
-import java.util.ArrayList;
-import java.util.List;
-
-public class LocationServices implements com.mapzen.android.lost.api.LocationListener {
-
- private static LocationServices instance = null;
-
- private LostApiClient mLocationClient;
- private LocationRequest mLocationRequest;
-
- private Location lastLocation = null;
-
- private List<LocationListener> locationListeners = null;
-
- private boolean isGPSEnabled = false;
-
- /**
- * Private constructor for singleton LocationServices
- */
- private LocationServices(Context context) {
- super();
- // Setup location services
- mLocationClient = new LostApiClient.Builder(context).build();
- locationListeners = new ArrayList<>();
- }
-
- /**
- * Primary (singleton) access method for LocationServices
- * @param context Context
- * @return LocationServices
- */
- public static LocationServices getLocationServices(@NonNull final Context context) {
- if (instance == null) {
- if (context == null) {
- throw new NullPointerException("Context required for accessing LocationServices");
- }
- instance = new LocationServices(context.getApplicationContext());
- }
- return instance;
- }
-
- /**
- * Enabled / Disable GPS focused location tracking
- *
- * @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
- */
- public void toggleGPS(boolean enableGPS) {
-
- if (enableGPS) {
-
- if (mLocationClient.isConnected()) {
- // Disconnect first to ensure that the new requests are GPS
- com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
- mLocationClient.disconnect();
- }
-
- // Setup Fresh
- mLocationClient.connect();
- Location lastLocation = com.mapzen.android.lost.api.LocationServices.FusedLocationApi.getLastLocation();
- if (lastLocation != null) {
- this.lastLocation = lastLocation;
- }
-
- // LocationRequest Tuned for GPS
- mLocationRequest = LocationRequest.create()
- .setFastestInterval(1000)
- .setSmallestDisplacement(3.0f)
- .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
-
- com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(mLocationRequest, this);
-
- } else {
-
- // Disconnect
- if (mLocationClient.isConnected()) {
- // Disconnect first to ensure that the new requests are GPS
- com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
- mLocationClient.disconnect();
- }
-
- }
-
- isGPSEnabled = enableGPS;
- }
-
- public boolean isGPSEnabled() {
- return isGPSEnabled;
- }
-
- @Override
- public void onLocationChanged(Location location) {
- this.lastLocation = location;
-
- // Update Listeners
- for (LocationListener listener : this.locationListeners) {
- listener.onLocationChanged(location);
- }
- }
-
- /**
- * Last known location
- * @return Last known location data
- */
- public Location getLastLocation() {
- return lastLocation;
- }
-
- /**
- * Registers a LocationListener to receive location updates
- * @param locationListener LocationListener
- */
- public void addLocationListener(@NonNull LocationListener locationListener) {
- if(!this.locationListeners.contains(locationListener)){
- this.locationListeners.add(locationListener);
- }
- }
-
- /**
- * Unregister a LocationListener to stop receiving location updates
- * @param locationListener LocationListener to remove
- * @return True if LocationListener was found and removed, False if it was not
- */
- public boolean removeLocationListener(@NonNull LocationListener locationListener) {
- return this.locationListeners.remove(locationListener);
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
index 2789e85ed8..4b5aa0cbaf 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
@@ -2,6 +2,7 @@ package com.mapbox.mapboxsdk.maps;
import android.app.Fragment;
import android.os.Bundle;
+import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
@@ -29,18 +30,10 @@ public class MapFragment extends Fragment {
private MapView mMap;
- public static MapFragment newInstance(){
+ public static MapFragment newInstance() {
return new MapFragment();
}
- public static MapFragment newInstance(MapboxMapOptions mapboxMapOptions) {
- final MapFragment mapFragment = new MapFragment();
- Bundle bundle = new Bundle();
- bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
- mapFragment.setArguments(bundle);
- return mapFragment;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
@@ -94,7 +87,12 @@ public class MapFragment extends Fragment {
}
@NonNull
- public void getMapAsync(@NonNull OnMapReadyCallback onMapReadyCallback){
- mMap.getMapAsync(onMapReadyCallback);
+ public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ mMap.getMapAsync(onMapReadyCallback);
+ }
+ });
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index bd0a010900..cb9459d5f2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -10,7 +10,9 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -27,8 +29,8 @@ import android.support.annotation.FloatRange;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.annotation.RequiresPermission;
import android.support.annotation.UiThread;
+import android.support.v4.content.ContextCompat;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ScaleGestureDetectorCompat;
import android.support.v7.app.AlertDialog;
@@ -47,44 +49,50 @@ import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewConfiguration;
+import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.ZoomButtonsController;
-
import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector;
import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.Polygon;
-import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.annotations.Polyline;
-import com.mapbox.mapboxsdk.annotations.PolylineOptions;
-import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException;
import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
+import com.mapbox.mapboxsdk.exceptions.TelemetryServiceNotConfiguredException;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.layers.CustomLayer;
+import com.mapbox.mapboxsdk.maps.widgets.CompassView;
+import com.mapbox.mapboxsdk.maps.widgets.UserLocationView;
+import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
+import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
import com.mapbox.mapboxsdk.utils.ApiAccess;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
@@ -111,7 +119,6 @@ public class MapView extends FrameLayout {
private static final float DIMENSION_SEVENTYSIX_DP = 76f;
private MapboxMap mMapboxMap;
- private List<Annotation> mAnnotations;
private List<Icon> mIcons;
private NativeMapView mNativeMapView;
@@ -120,7 +127,7 @@ public class MapView extends FrameLayout {
private ImageView mAttributionsView;
private UserLocationView mUserLocationView;
- private List<OnMapChangedListener> mOnMapChangedListener;
+ private CopyOnWriteArrayList<OnMapChangedListener> mOnMapChangedListener;
private ZoomButtonsController mZoomButtonsController;
private ConnectivityReceiver mConnectivityReceiver;
private float mScreenDensity = 1.0f;
@@ -133,13 +140,12 @@ public class MapView extends FrameLayout {
private boolean mTwoTap = false;
private boolean mZoomStarted = false;
private boolean mQuickZoom = false;
+ private boolean mScrollInProgress = false;
- /*
private int mContentPaddingLeft;
private int mContentPaddingTop;
private int mContentPaddingRight;
private int mContentPaddingBottom;
-*/
@UiThread
public MapView(@NonNull Context context) {
@@ -160,11 +166,9 @@ public class MapView extends FrameLayout {
}
private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) {
- mOnMapChangedListener = new ArrayList<>();
+ mOnMapChangedListener = new CopyOnWriteArrayList<>();
mMapboxMap = new MapboxMap(this);
- mAnnotations = new ArrayList<>();
mIcons = new ArrayList<>();
-
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
if (!isInEditMode()) {
@@ -200,7 +204,7 @@ public class MapView extends FrameLayout {
// Shows the zoom controls
if (!context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) {
- mMapboxMap.setZoomControlsEnabled(true);
+ mMapboxMap.getUiSettings().setZoomControlsEnabled(true);
}
mZoomButtonsController = new ZoomButtonsController(this);
mZoomButtonsController.setZoomSpeed(MapboxConstants.ANIMATION_DURATION);
@@ -210,9 +214,9 @@ public class MapView extends FrameLayout {
onConnectivityChanged(isConnected());
mUserLocationView = (UserLocationView) view.findViewById(R.id.userLocationView);
- mUserLocationView.setMapView(this);
+ mUserLocationView.setMapboxMap(mMapboxMap);
mCompassView = (CompassView) view.findViewById(R.id.compassView);
- mCompassView.setOnClickListener(new CompassView.CompassClickListener(this));
+ mCompassView.setOnClickListener(new CompassView.CompassClickListener(mMapboxMap));
mLogoView = (ImageView) view.findViewById(R.id.logoView);
// Setup Attributions control
@@ -232,13 +236,15 @@ public class MapView extends FrameLayout {
mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
// Access token
- if (typedArray.getString(R.styleable.MapView_access_token) != null) {
+ String accessToken = typedArray.getString(R.styleable.MapView_access_token);
+ if (accessToken != null) {
setAccessToken(typedArray.getString(R.styleable.MapView_access_token));
}
// Style url
- if (typedArray.getString(R.styleable.MapView_style_url) != null) {
- mMapboxMap.setStyleUrl(typedArray.getString(R.styleable.MapView_style_url));
+ String styleUrl = typedArray.getString(R.styleable.MapView_style_url);
+ if (styleUrl != null) {
+ mMapboxMap.setStyleUrl(styleUrl);
}
// Enable gestures
@@ -249,6 +255,10 @@ public class MapView extends FrameLayout {
uiSettings.setTiltGesturesEnabled(typedArray.getBoolean(R.styleable.MapView_tilt_enabled, true));
uiSettings.setZoomControlsEnabled(typedArray.getBoolean(R.styleable.MapView_zoom_controls_enabled, false));
+ // Zoom
+ uiSettings.setMaxZoom(typedArray.getFloat(R.styleable.MapView_zoom_max, (float) MapboxConstants.MAXIMUM_ZOOM));
+ uiSettings.setMinZoom(typedArray.getFloat(R.styleable.MapView_zoom_min, (float) MapboxConstants.MINIMUM_ZOOM));
+
// Compass
uiSettings.setCompassEnabled(typedArray.getBoolean(R.styleable.MapView_compass_enabled, true));
uiSettings.setCompassGravity(typedArray.getInt(R.styleable.MapView_compass_gravity, Gravity.TOP | Gravity.END));
@@ -274,13 +284,7 @@ public class MapView extends FrameLayout {
, (int) (typedArray.getDimension(R.styleable.MapView_attribution_margin_bottom, DIMENSION_SEVEN_DP) * mScreenDensity));
// User location
- try {
- //noinspection ResourceType
- mMapboxMap.setMyLocationEnabled(typedArray.getBoolean(R.styleable.MapView_my_location_enabled, false));
- } catch (SecurityException ignore) {
- // User did not accept location permissions
- }
-
+ mMapboxMap.setMyLocationEnabled(typedArray.getBoolean(R.styleable.MapView_my_location_enabled, false));
} finally {
typedArray.recycle();
}
@@ -303,7 +307,7 @@ public class MapView extends FrameLayout {
*/
@UiThread
public void onCreate(@Nullable Bundle savedInstanceState) {
- if (savedInstanceState != null) {
+ if (savedInstanceState != null && savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
// Get previous camera position
CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION);
@@ -357,10 +361,17 @@ public class MapView extends FrameLayout {
// User did not accept location permissions
}
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
//noinspection ResourceType
- mMapboxMap.setMyLocationTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
+ trackingSettings.setMyLocationTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
//noinspection ResourceType
- mMapboxMap.setMyBearingTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
+ trackingSettings.setMyBearingTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
+ } else {
+ // Force a check for Telemetry
+ validateTelemetryServiceConfigured();
+
+ // Start Telemetry (authorization determined in initial MapboxEventManager constructor)
+ MapboxEventManager.getMapboxEventManager(getContext()).isTelemetryEnabled();
}
// Force a check for an access token
@@ -381,6 +392,16 @@ public class MapView extends FrameLayout {
}
}
});
+
+ // Fire MapLoad
+ if (savedInstanceState == null) {
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD);
+ evt.put(MapboxEvent.KEY_LATITUDE, mMapboxMap.getCameraPosition().target.getLatitude());
+ evt.put(MapboxEvent.KEY_LONGITUDE, mMapboxMap.getCameraPosition().target.getLongitude());
+ evt.put(MapboxEvent.KEY_ZOOM, mMapboxMap.getCameraPosition().zoom);
+ MapboxEventManager.getMapboxEventManager(getContext()).pushEvent(evt);
+ }
}
/**
@@ -392,14 +413,19 @@ public class MapView extends FrameLayout {
@UiThread
public void onSaveInstanceState(@NonNull Bundle outState) {
+ outState.putBoolean(MapboxConstants.STATE_HAS_SAVED_STATE, true);
outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, mMapboxMap.getCameraPosition());
outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, mMapboxMap.isDebugActive());
outState.putString(MapboxConstants.STATE_STYLE_URL, mMapboxMap.getStyleUrl());
outState.putString(MapboxConstants.STATE_ACCESS_TOKEN, mMapboxMap.getAccessToken());
outState.putLong(MapboxConstants.STATE_DEFAULT_TRANSITION_DURATION, mNativeMapView.getDefaultTransitionDuration());
outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, mMapboxMap.isMyLocationEnabled());
- outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, mMapboxMap.getMyLocationTrackingMode());
- outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, mMapboxMap.getMyBearingTrackingMode());
+
+
+ // TrackingSettings
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+ outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, trackingSettings.getMyLocationTrackingMode());
+ outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, trackingSettings.getMyBearingTrackingMode());
// UiSettings
UiSettings uiSettings = mMapboxMap.getUiSettings();
@@ -554,13 +580,13 @@ public class MapView extends FrameLayout {
}
//
- // Rotation
+ // Direction
//
/**
- * Returns the current heading of the map relative to true north.
+ * Returns the current direction of the map relative to true north.
*
- * @return The current heading measured in degrees.
+ * @return The current direction measured in degrees.
*/
@UiThread
@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION)
@@ -633,6 +659,46 @@ public class MapView extends FrameLayout {
}
//
+ // Content padding
+ //
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding left
+ */
+ int getContentPaddingLeft() {
+ return mContentPaddingLeft;
+ }
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding left
+ */
+ int getContentPaddingTop() {
+ return mContentPaddingTop;
+ }
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding right
+ */
+ int getContentPaddingRight() {
+ return mContentPaddingRight;
+ }
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding bottom
+ */
+ int getContentPaddingBottom() {
+ return mContentPaddingBottom;
+ }
+
+ //
// Zoom
//
@@ -647,51 +713,6 @@ public class MapView extends FrameLayout {
return mNativeMapView.getZoom();
}
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @return The current content padding left
-// */
-///*
-// public int getContentPaddingLeft() {
-// return mContentPaddingLeft;
-// }
-//*/
-//
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @return The current content padding left
-// */
-///*
-// public int getContentPaddingTop() {
-// return mContentPaddingTop;
-// }
-//*/
-//
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @return The current content padding left
-// */
-///*
-// public int getContentPaddingRight() {
-// return mContentPaddingRight;
-// }
-//*/
-//
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @param zoomLevel The new zoom level.
-// * @param animated If true, animates the change. If false, immediately changes the map.
-// * @see MapboxMap#MAXIMUM_ZOOM
-// */
-///*
-// public int getContentPaddingBottom() {
-// return mContentPaddingBottom;
-//*/
-
/**
* <p>
* Sets the minimum zoom level the map can be displayed at.
@@ -712,7 +733,7 @@ public class MapView extends FrameLayout {
* @return The minimum zoom level.
*/
@UiThread
- public double getMinZoom() {
+ double getMinZoom() {
return mNativeMapView.getMinZoom();
}
@@ -724,7 +745,7 @@ public class MapView extends FrameLayout {
* @param maxZoom The new maximum zoom level.
*/
@UiThread
- public void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
+ void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
mNativeMapView.setMaxZoom(maxZoom);
}
@@ -736,7 +757,7 @@ public class MapView extends FrameLayout {
* @return The maximum zoom level.
*/
@UiThread
- public double getMaxZoom() {
+ double getMaxZoom() {
return mNativeMapView.getMaxZoom();
}
@@ -866,6 +887,28 @@ public class MapView extends FrameLayout {
}
}
+ // Checks that TelemetryService has been configured by developer
+ private void validateTelemetryServiceConfigured() {
+
+ try {
+ // Check Implementing app's AndroidManifest.xml
+ PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), PackageManager.GET_SERVICES);
+
+ if (packageInfo.services != null) {
+
+ for (ServiceInfo service : packageInfo.services) {
+ if (TextUtils.equals("com.mapbox.mapboxsdk.telemetry.TelemetryService", service.name)) {
+ return;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ Log.w(TAG, "Error checking for Telemetry Service Config: " + e);
+ }
+ throw new TelemetryServiceNotConfiguredException();
+ }
+
/**
* <p>
* Sets the current Mapbox access token used to load map styles and tiles.
@@ -942,7 +985,25 @@ public class MapView extends FrameLayout {
// Annotations
//
- private void loadIcon(Icon icon) {
+ Icon loadIconForMarker(Marker marker) {
+ Icon icon = marker.getIcon();
+ if (icon == null) {
+ icon = IconFactory.getInstance(getContext()).defaultMarker();
+ marker.setIcon(icon);
+ }
+ if (!mIcons.contains(icon)) {
+ mIcons.add(icon);
+ loadIcon(icon);
+ } else {
+ Icon oldIcon = mIcons.get(mIcons.indexOf(icon));
+ if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
+ throw new IconBitmapChangedException();
+ }
+ }
+ return icon;
+ }
+
+ void loadIcon(Icon icon) {
Bitmap bitmap = icon.getBitmap();
String id = icon.getId();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
@@ -964,7 +1025,7 @@ public class MapView extends FrameLayout {
scale, buffer.array());
}
- private void reloadIcons() {
+ void reloadIcons() {
int count = mIcons.size();
for (int i = 0; i < count; i++) {
Icon icon = mIcons.get(i);
@@ -972,8 +1033,35 @@ public class MapView extends FrameLayout {
}
}
+ /**
+ * <p>
+ * Updates a marker on this map. Does nothing if the marker is already added.
+ * </p>
+ *
+ * @param updatedMarker An updated marker object.
+ */
+ @UiThread
+ void updateMarker(@NonNull Marker updatedMarker) {
+ if (updatedMarker == null) {
+ Log.w(TAG, "marker was null, doing nothing");
+ return;
+ }
+
+ if (updatedMarker.getId() == -1) {
+ Log.w(TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
+ }
+
+ ensureIconLoaded(updatedMarker);
+ mNativeMapView.updateMarker(updatedMarker);
+ }
+
private Marker prepareMarker(MarkerOptions markerOptions) {
Marker marker = markerOptions.getMarker();
+ ensureIconLoaded(marker);
+ return marker;
+ }
+
+ private void ensureIconLoaded(Marker marker) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(getContext()).defaultMarker();
@@ -988,270 +1076,48 @@ public class MapView extends FrameLayout {
throw new IconBitmapChangedException();
}
}
- marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
- return marker;
- }
- /**
- * <p>
- * Adds a marker to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptions A marker options object that defines how to render the marker.
- * @return The {@code Marker} that was added to the map.
- */
- @UiThread
- @NonNull
- Marker addMarker(@NonNull MarkerOptions markerOptions) {
- if (markerOptions == null) {
- Log.w(TAG, "markerOptions was null, so just returning null");
- return null;
+ // this seems to be a costly operation according to the profiler so I'm trying to save some calls
+ Marker previousMarker = marker.getId() != -1 ? (Marker) mMapboxMap.getAnnotation(marker.getId()) : null;
+ if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
+ marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
-
- Marker marker = prepareMarker(markerOptions);
- long id = mNativeMapView.addMarker(marker);
- marker.setId(id); // the annotation needs to know its id
- marker.setMapboxMap(mMapboxMap); // the annotation needs to know which map view it is in
- mAnnotations.add(marker);
- return marker;
}
- /**
- * <p>
- * Adds multiple markers to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptionsList A list of marker options objects that defines how to render the markers.
- * @return A list of the {@code Marker}s that were added to the map.
- */
- @UiThread
- @NonNull
- List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
- if (markerOptionsList == null) {
- Log.w(TAG, "markerOptionsList was null, so just returning null");
- return null;
- }
-
- int count = markerOptionsList.size();
- List<Marker> markers = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- MarkerOptions markerOptions = markerOptionsList.get(i);
- Marker marker = prepareMarker(markerOptions);
- markers.add(marker);
- }
-
- long[] ids = mNativeMapView.addMarkers(markers);
- Marker m;
- for (int i = 0; i < count; i++) {
- m = markers.get(i);
- m.setId(ids[i]);
- m.setMapboxMap(mMapboxMap);
- mAnnotations.add(m);
+ long addMarker(@NonNull Marker marker) {
+ if (mNativeMapView == null) {
+ return 0l;
}
-
- return new ArrayList<>(markers);
+ return mNativeMapView.addMarker(marker);
}
- /**
- * Adds a polyline to this map.
- *
- * @param polylineOptions A polyline options object that defines how to render the polyline.
- * @return The {@code Polyine} that was added to the map.
- */
- @UiThread
- @NonNull
- Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
- if (polylineOptions == null) {
- Log.w(TAG, "polylineOptions was null, so just returning null");
- return null;
- }
-
- Polyline polyline = polylineOptions.getPolyline();
- long id = mNativeMapView.addPolyline(polyline);
- polyline.setId(id);
- polyline.setMapboxMap(mMapboxMap);
- mAnnotations.add(polyline);
- return polyline;
+ long[] addMarkers(@NonNull List<Marker> markerList) {
+ return mNativeMapView.addMarkers(markerList);
}
- /**
- * Adds multiple polylines to this map.
- *
- * @param polylineOptionsList A list of polyline options objects that defines how to render the polylines.
- * @return A list of the {@code Polyline}s that were added to the map.
- */
- @UiThread
- @NonNull
- List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
- if (polylineOptionsList == null) {
- Log.w(TAG, "polylineOptionsList was null, so just returning null");
- return null;
- }
-
- int count = polylineOptionsList.size();
- List<Polyline> polylines = new ArrayList<>(count);
- for (PolylineOptions options : polylineOptionsList) {
- polylines.add(options.getPolyline());
- }
-
- long[] ids = mNativeMapView.addPolylines(polylines);
-
- Polyline p;
- for (int i = 0; i < count; i++) {
- p = polylines.get(i);
- p.setId(ids[i]);
- p.setMapboxMap(mMapboxMap);
- mAnnotations.add(p);
- }
-
- return new ArrayList<>(polylines);
+ long addPolyline(@NonNull Polyline polyline) {
+ return mNativeMapView.addPolyline(polyline);
}
- /**
- * Adds a polygon to this map.
- *
- * @param polygonOptions A polygon options object that defines how to render the polygon.
- * @return The {@code Polygon} that was added to the map.
- */
- @UiThread
- @NonNull
- Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
- if (polygonOptions == null) {
- Log.w(TAG, "polygonOptions was null, so just returning null");
- return null;
- }
-
- Polygon polygon = polygonOptions.getPolygon();
- long id = mNativeMapView.addPolygon(polygon);
- polygon.setId(id);
- polygon.setMapboxMap(mMapboxMap);
- mAnnotations.add(polygon);
- return polygon;
+ long[] addPolylines(@NonNull List<Polyline> polylines) {
+ return mNativeMapView.addPolylines(polylines);
}
-
- /**
- * Adds multiple polygons to this map.
- *
- * @param polygonOptionsList A list of polygon options objects that defines how to render the polygons.
- * @return A list of the {@code Polygon}s that were added to the map.
- */
- @UiThread
- @NonNull
- List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
- if (polygonOptionsList == null) {
- Log.w(TAG, "polygonOptionsList was null, so just returning null");
- return null;
- }
-
- int count = polygonOptionsList.size();
- List<Polygon> polygons = new ArrayList<>(count);
- for (PolygonOptions polygonOptions : polygonOptionsList) {
- polygons.add(polygonOptions.getPolygon());
- }
-
- long[] ids = mNativeMapView.addPolygons(polygons);
-
- Polygon p;
- for (int i = 0; i < count; i++) {
- p = polygons.get(i);
- p.setId(ids[i]);
- p.setMapboxMap(mMapboxMap);
- mAnnotations.add(p);
- }
-
- return new ArrayList<>(polygons);
+ long addPolygon(@NonNull Polygon polygon) {
+ return mNativeMapView.addPolygon(polygon);
}
-
- /**
- * <p>
- * Convenience method for removing a Marker from the map.
- * </p>
- * Calls removeAnnotation() internally
- *
- * @param marker Marker to remove
- */
- @UiThread
- void removeMarker(@NonNull Marker marker) {
- removeAnnotation(marker);
+ long[] addPolygons(@NonNull List<Polygon> polygons) {
+ return mNativeMapView.addPolygons(polygons);
}
- /**
- * Removes an annotation from the map.
- *
- * @param annotation The annotation object to remove.
- */
- @UiThread
- void removeAnnotation(@NonNull Annotation annotation) {
- if (annotation == null) {
- Log.w(TAG, "annotation was null, so just returning");
- return;
- }
-
- if (annotation instanceof Marker) {
- ((Marker) annotation).hideInfoWindow();
- }
- long id = annotation.getId();
+ void removeAnnotation(long id) {
mNativeMapView.removeAnnotation(id);
- mAnnotations.remove(annotation);
- }
-
- /**
- * Removes multiple annotations from the map.
- *
- * @param annotationList A list of annotation objects to remove.
- */
- @UiThread
- void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
- if (annotationList == null) {
- Log.w(TAG, "annotationList was null, so just returning");
- return;
- }
-
- int count = annotationList.size();
- long[] ids = new long[count];
- for (int i = 0; i < count; i++) {
- ids[i] = annotationList.get(i).getId();
- }
- mNativeMapView.removeAnnotations(ids);
}
- /**
- * Removes all annotations from the map.
- */
- @UiThread
- void removeAllAnnotations() {
- int count = mAnnotations.size();
- long[] ids = new long[mAnnotations.size()];
-
- for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
- long id = annotation.getId();
- ids[i] = id;
- if (annotation instanceof Marker) {
- ((Marker) annotation).hideInfoWindow();
- }
- }
-
+ void removeAnnotations(@NonNull long[] ids) {
mNativeMapView.removeAnnotations(ids);
- mAnnotations.clear();
- }
-
- /**
- * Returns a list of all the annotations on the map.
- *
- * @return A list of all the annotation objects. The returned object is a copy so modifying this
- * list will not update the map.
- */
- @NonNull
- List<Annotation> getAllAnnotations() {
- return new ArrayList<>(mAnnotations);
}
private List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) {
@@ -1269,9 +1135,10 @@ public class MapView extends FrameLayout {
}
List<Marker> annotations = new ArrayList<>(ids.length);
- int count = mAnnotations.size();
+ List<Annotation> annotationList = mMapboxMap.getAnnotations();
+ int count = annotationList.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotationList.get(i);
if (annotation instanceof Marker && idsList.contains(annotation.getId())) {
annotations.add((Marker) annotation);
}
@@ -1280,7 +1147,7 @@ public class MapView extends FrameLayout {
return new ArrayList<>(annotations);
}
- private int getTopOffsetPixelsForIcon(Icon icon) {
+ int getTopOffsetPixelsForIcon(Icon icon) {
// This method will dead lock if map paused. Causes a freeze if you add a marker in an
// activity's onCreate()
if (mNativeMapView.isPaused()) {
@@ -1292,6 +1159,35 @@ public class MapView extends FrameLayout {
}
/**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ * <p/>
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ @UiThread
+ void setContentPadding(int left, int top, int right, int bottom) {
+ if (left == mContentPaddingLeft && top == mContentPaddingTop && right == mContentPaddingRight && bottom == mContentPaddingBottom) {
+ return;
+ }
+
+ mContentPaddingLeft = left;
+ mContentPaddingTop = top;
+ mContentPaddingRight = right;
+ mContentPaddingBottom = bottom;
+
+ mNativeMapView.setContentPadding(top / mScreenDensity, left / mScreenDensity, bottom / mScreenDensity, right / mScreenDensity);
+ }
+
+ /**
* <p>
* Returns the distance spanned by one pixel at the specified latitude and current zoom level.
* </p>
@@ -1400,9 +1296,10 @@ public class MapView extends FrameLayout {
}
private void adjustTopOffsetPixels() {
- int count = mAnnotations.size();
+ List<Annotation> annotations = mMapboxMap.getAnnotations();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.setTopOffsetPixels(
@@ -1419,9 +1316,10 @@ public class MapView extends FrameLayout {
}
private void reloadMarkers() {
- int count = mAnnotations.size();
+ List<Annotation> annotations = mMapboxMap.getAnnotations();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
mNativeMapView.removeAnnotation(annotation.getId());
@@ -1572,6 +1470,26 @@ public class MapView extends FrameLayout {
// Touch events
//
+ /**
+ * Helper method for tracking gesture events
+ * @param gestureId Type of Gesture See {@see MapboxEvent#GESTURE_SINGLETAP MapboxEvent#GESTURE_DOUBLETAP MapboxEvent#GESTURE_TWO_FINGER_SINGLETAP MapboxEvent#GESTURE_QUICK_ZOOM MapboxEvent#GESTURE_PAN_START MapboxEvent#GESTURE_PINCH_START MapboxEvent#GESTURE_ROTATION_START MapboxEvent#GESTURE_PITCH_START}
+ * @param xCoordinate Original x screen coordinate at start of gesture
+ * @param yCoordinate Original y screen cooridnate at start of gesture
+ */
+ private void trackGestureEvent(@NonNull String gestureId, @NonNull float xCoordinate, float yCoordinate) {
+
+ LatLng tapLatLng = fromScreenLocation(new PointF(xCoordinate, yCoordinate));
+
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK);
+ evt.put(MapboxEvent.KEY_GESTURE_ID, gestureId);
+ evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
+ evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
+ evt.put(MapboxEvent.KEY_ZOOM, mMapboxMap.getCameraPosition().zoom);
+
+ MapboxEventManager.getMapboxEventManager(getContext()).pushEvent(evt);
+ }
+
// Called when user touches the screen, all positions are absolute
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
@@ -1596,6 +1514,10 @@ public class MapView extends FrameLayout {
case MotionEvent.ACTION_POINTER_DOWN:
// Second pointer down
mTwoTap = event.getPointerCount() == 2;
+ if (mTwoTap) {
+ // Confirmed 2nd Finger Down
+ trackGestureEvent(MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY());
+ }
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -1617,6 +1539,12 @@ public class MapView extends FrameLayout {
return true;
}
+ // Scroll / Pan Has Stopped
+ if (mScrollInProgress) {
+ trackGestureEvent(MapboxEvent.TYPE_MAP_DRAGEND, event.getX(), event.getY());
+ mScrollInProgress = false;
+ }
+
mTwoTap = false;
mNativeMapView.setGestureInProgress(false);
break;
@@ -1632,8 +1560,7 @@ public class MapView extends FrameLayout {
}
// This class handles one finger gestures
- private class GestureListener extends
- GestureDetector.SimpleOnGestureListener {
+ private class GestureListener extends GestureDetector.SimpleOnGestureListener {
// Must always return true otherwise all events are ignored
@Override
@@ -1665,16 +1592,20 @@ public class MapView extends FrameLayout {
}
// Single finger double tap
- if (mUserLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE) {
+ if (mMapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
// Zoom in on gesture
zoom(true, e.getX(), e.getY());
+ trackGestureEvent(MapboxEvent.GESTURE_QUICK_ZOOM, e.getX(), e.getY());
} else {
- // Zoom in on center map
- zoom(true, getWidth() / 2, getHeight() / 2);
+ // Zoom in on user location view
+ PointF centerPoint = mUserLocationView.getMarkerScreenPoint();
+ zoom(true, centerPoint.x, centerPoint.y);
}
break;
}
+ trackGestureEvent(MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY());
+
return true;
}
@@ -1725,9 +1656,10 @@ public class MapView extends FrameLayout {
}
if (newSelectedMarkerId >= 0) {
- int count = mAnnotations.size();
+ List<Annotation> annotations = mMapboxMap.getAnnotations();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
if (annotation.getId() == newSelectedMarkerId) {
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {
@@ -1749,6 +1681,8 @@ public class MapView extends FrameLayout {
}
}
+ trackGestureEvent(MapboxEvent.GESTURE_SINGLETAP, e.getX(), e.getY());
+
return true;
}
@@ -1771,7 +1705,9 @@ public class MapView extends FrameLayout {
}
// reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ resetTrackingModes();
+ }
// Fling the map
float ease = 0.25f;
@@ -1793,18 +1729,25 @@ public class MapView extends FrameLayout {
listener.onFling();
}
+ trackGestureEvent(MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY());
return true;
}
// Called for drags
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ Log.i(TAG, "onScroll() started");
+ if (!mScrollInProgress) {
+ mScrollInProgress = true;
+ }
if (!mMapboxMap.getUiSettings().isScrollGesturesEnabled()) {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
// Cancel any animation
mNativeMapView.cancelTransitions();
@@ -1817,6 +1760,7 @@ public class MapView extends FrameLayout {
listener.onScroll();
}
+ Log.i(TAG, "onScroll() done");
return true;
}
}
@@ -1834,10 +1778,13 @@ public class MapView extends FrameLayout {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
mBeginTime = detector.getEventTime();
+ trackGestureEvent(MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY());
return true;
}
@@ -1853,7 +1800,8 @@ public class MapView extends FrameLayout {
// Called for pinch zooms and quickzooms/quickscales
@Override
public boolean onScale(ScaleGestureDetector detector) {
- if (!mMapboxMap.getUiSettings().isZoomGesturesEnabled()) {
+ UiSettings uiSettings = mMapboxMap.getUiSettings();
+ if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
@@ -1881,13 +1829,21 @@ public class MapView extends FrameLayout {
// Gesture is a quickzoom if there aren't two fingers
mQuickZoom = !mTwoTap;
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+
// Scale the map
- if (mMapboxMap.getUiSettings().isScrollGesturesEnabled() && !mQuickZoom && mUserLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE) {
+ if (uiSettings.isScrollGesturesEnabled() && !mQuickZoom && trackingSettings.isLocationTrackingDisabled()) {
// around gesture
mNativeMapView.scaleBy(detector.getScaleFactor(), detector.getFocusX() / mScreenDensity, detector.getFocusY() / mScreenDensity);
} else {
- // around center map
- mNativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / mScreenDensity, (getHeight() / 2) / mScreenDensity);
+ if(trackingSettings.isLocationTrackingDisabled()) {
+ // around center map
+ mNativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / mScreenDensity, (getHeight() / 2) / mScreenDensity);
+ }else {
+ // around user location view
+ PointF centerPoint = mUserLocationView.getMarkerScreenPoint();
+ mNativeMapView.scaleBy(detector.getScaleFactor(), centerPoint.x / mScreenDensity, centerPoint.y / mScreenDensity);
+ }
}
return true;
}
@@ -1907,10 +1863,13 @@ public class MapView extends FrameLayout {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
mBeginTime = detector.getEventTime();
+ trackGestureEvent(MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY());
return true;
}
@@ -1957,16 +1916,15 @@ public class MapView extends FrameLayout {
bearing += detector.getRotationDegreesDelta();
// Rotate the map
- if (mUserLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE) {
+ if (mMapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
// around gesture
mNativeMapView.setBearing(bearing,
detector.getFocusX() / mScreenDensity,
detector.getFocusY() / mScreenDensity);
} else {
- // around center map
- mNativeMapView.setBearing(bearing,
- (getWidth() / 2) / mScreenDensity,
- (getHeight() / 2) / mScreenDensity);
+ // around center userlocation
+ PointF centerPoint = mUserLocationView.getMarkerScreenPoint();
+ mNativeMapView.setBearing(bearing, centerPoint.x / mScreenDensity, centerPoint.y / mScreenDensity);
}
return true;
}
@@ -1986,10 +1944,13 @@ public class MapView extends FrameLayout {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
mBeginTime = detector.getEventTime();
+ trackGestureEvent(MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY());
return true;
}
@@ -2056,8 +2017,6 @@ public class MapView extends FrameLayout {
if (!mMapboxMap.getUiSettings().isZoomGesturesEnabled()) {
return;
}
-
- // Zoom in or out
zoom(zoomIn);
}
}
@@ -2408,9 +2367,11 @@ public class MapView extends FrameLayout {
// Forward to any listeners
protected void onMapChanged(int mapChange) {
if (mOnMapChangedListener != null) {
- int count = mOnMapChangedListener.size();
- for (int i = 0; i < count; i++) {
- mOnMapChangedListener.get(i).onMapChanged(mapChange);
+ OnMapChangedListener listener;
+ final Iterator<OnMapChangedListener> iterator = mOnMapChangedListener.iterator();
+ while (iterator.hasNext()) {
+ listener = iterator.next();
+ listener.onMapChanged(mapChange);
}
}
}
@@ -2419,6 +2380,11 @@ public class MapView extends FrameLayout {
// User location
//
+ boolean isPermissionsAccepted() {
+ return (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ||
+ ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
+ }
+
/**
* <p>
* Enables or disables the my-location layer.
@@ -2433,9 +2399,6 @@ public class MapView extends FrameLayout {
* @throws SecurityException if no suitable permission is present
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
void setMyLocationEnabled(boolean enabled) {
mUserLocationView.setEnabled(enabled);
}
@@ -2473,19 +2436,13 @@ public class MapView extends FrameLayout {
* See {@link MyLocationTracking} for different values.
*
* @param myLocationTrackingMode The location tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
* @see MyLocationTracking
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
if (myLocationTrackingMode != MyLocationTracking.TRACKING_NONE && !mMapboxMap.isMyLocationEnabled()) {
- //noinspection ResourceType
mMapboxMap.setMyLocationEnabled(true);
}
-
mUserLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
MapboxMap.OnMyLocationTrackingModeChangeListener listener = mMapboxMap.getOnMyLocationTrackingModeChangeListener();
if (listener != null) {
@@ -2494,19 +2451,6 @@ public class MapView extends FrameLayout {
}
/**
- * Returns the current user location tracking mode.
- *
- * @return The current user location tracking mode.
- * One of the values from {@link MyLocationTracking.Mode}.
- * @see MyLocationTracking.Mode
- */
- @UiThread
- @MyLocationTracking.Mode
- int getMyLocationTrackingMode() {
- return mUserLocationView.getMyLocationTrackingMode();
- }
-
- /**
* <p>
* Set the current my bearing tracking mode.
* </p>
@@ -2518,16 +2462,11 @@ public class MapView extends FrameLayout {
* See {@link MyBearingTracking} for different values.
*
* @param myBearingTrackingMode The bearing tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
* @see MyBearingTracking
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
if (myBearingTrackingMode != MyBearingTracking.NONE && !mMapboxMap.isMyLocationEnabled()) {
- //noinspection ResourceType
mMapboxMap.setMyLocationEnabled(true);
}
mUserLocationView.setMyBearingTrackingMode(myBearingTrackingMode);
@@ -2537,26 +2476,11 @@ public class MapView extends FrameLayout {
}
}
- /**
- * Returns the current user bearing tracking mode.
- * See {@link MyBearingTracking} for possible return values.
- *
- * @return the current user bearing tracking mode.
- * @see MyBearingTracking
- */
- @UiThread
- @MyLocationTracking.Mode
- int getMyBearingTrackingMode() {
- //noinspection ResourceType
- return mUserLocationView.getMyBearingTrackingMode();
- }
-
private void resetTrackingModes() {
try {
- //noinspection ResourceType
- setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
- //noinspection ResourceType
- setMyBearingTrackingMode(MyBearingTracking.NONE);
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
} catch (SecurityException ignore) {
// User did not accept location permissions
}
@@ -2806,6 +2730,10 @@ public class MapView extends FrameLayout {
private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) {
LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
+ left += mContentPaddingLeft;
+ top += mContentPaddingTop;
+ right += mContentPaddingRight;
+ bottom += mContentPaddingBottom;
layoutParams.setMargins(left, top, right, bottom);
view.setLayoutParams(layoutParams);
}
@@ -2813,9 +2741,11 @@ public class MapView extends FrameLayout {
private static class AttributionOnClickListener implements View.OnClickListener, DialogInterface.OnClickListener {
private static final int ATTRIBUTION_INDEX_IMPROVE_THIS_MAP = 2;
+ private static final int ATTRIBUTION_INDEX_TELEMETRY_SETTINGS = 3;
private MapView mMapView;
public AttributionOnClickListener(MapView mapView) {
+ super();
mMapView = mapView;
}
@@ -2825,7 +2755,7 @@ public class MapView extends FrameLayout {
Context context = v.getContext();
String[] items = context.getResources().getStringArray(R.array.attribution_names);
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AttributionAlertDialogStyle);
- builder.setTitle(R.string.attributionsDialogTitle);
+ builder.setTitle(R.string.mapbox_attributionsDialogTitle);
builder.setAdapter(new ArrayAdapter<>(context, R.layout.attribution_list_item, items), this);
builder.show();
}
@@ -2833,7 +2763,49 @@ public class MapView extends FrameLayout {
// Called when someone selects an attribution, 'Improve this map' adds location data to the url
@Override
public void onClick(DialogInterface dialog, int which) {
- Context context = ((Dialog) dialog).getContext();
+ final Context context = ((Dialog) dialog).getContext();
+ if (which == ATTRIBUTION_INDEX_TELEMETRY_SETTINGS) {
+
+ int array = R.array.attribution_telemetry_options;
+ if (MapboxEventManager.getMapboxEventManager(context).isTelemetryEnabled()) {
+ array = R.array.attribution_telemetry_options_already_participating;
+ }
+ String[] items = context.getResources().getStringArray(array);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AttributionAlertDialogStyle);
+ builder.setTitle(R.string.mapbox_attributionTelemetryTitle);
+ LayoutInflater factory = LayoutInflater.from(context);
+ View content = factory.inflate(R.layout.attribution_telemetry_view, null);
+
+ ListView lv = (ListView) content.findViewById(R.id.telemetryOptionsList);
+ lv.setAdapter(new ArrayAdapter<String>(context, R.layout.attribution_list_item, items));
+ lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+
+ builder.setView(content);
+ final AlertDialog telemDialog = builder.show();
+ lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ switch (position) {
+ case 0:
+ String url = context.getResources().getStringArray(R.array.attribution_links)[3];
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(url));
+ context.startActivity(intent);
+ telemDialog.cancel();
+ return;
+ case 1:
+ MapboxEventManager.getMapboxEventManager(context).setTelemetryEnabled(false);
+ telemDialog.cancel();
+ return;
+ case 2:
+ MapboxEventManager.getMapboxEventManager(context).setTelemetryEnabled(true);
+ telemDialog.cancel();
+ return;
+ }
+ }
+ });
+ return;
+ }
String url = context.getResources().getStringArray(R.array.attribution_links)[which];
if (which == ATTRIBUTION_INDEX_IMPROVE_THIS_MAP) {
LatLng latLng = mMapView.getMapboxMap().getCameraPosition().target;
@@ -3044,4 +3016,5 @@ public class MapView extends FrameLayout {
void onMapChanged(@MapChange int change);
}
+
}
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 757a9bc3d9..40b75d3ce1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -1,20 +1,21 @@
package com.mapbox.mapboxsdk.maps;
-import android.Manifest;
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
-import android.support.annotation.FloatRange;
+import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.annotation.RequiresPermission;
import android.support.annotation.UiThread;
+import android.support.v4.util.LongSparseArray;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Annotation;
+import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
+import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
@@ -23,6 +24,8 @@ import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
@@ -39,10 +42,12 @@ public class MapboxMap {
private MapView mMapView;
private UiSettings mUiSettings;
+ private TrackingSettings mTrackingSettings;
private Projection mProjection;
private CameraPosition mCameraPosition;
private boolean mInvalidCameraPosition;
private String mStyleUrl;
+ private LongSparseArray<Annotation> mAnnotations;
private List<Marker> mSelectedMarkers;
private List<InfoWindow> mInfoWindows;
private MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
@@ -54,17 +59,22 @@ public class MapboxMap {
private MapboxMap.OnMapLongClickListener mOnMapLongClickListener;
private MapboxMap.OnMarkerClickListener mOnMarkerClickListener;
private MapboxMap.OnInfoWindowClickListener mOnInfoWindowClickListener;
+ private MapboxMap.OnInfoWindowLongClickListener mOnInfoWindowLongClickListener;
+ private MapboxMap.OnInfoWindowCloseListener mOnInfoWindowCloseListener;
private MapboxMap.OnFlingListener mOnFlingListener;
private MapboxMap.OnScrollListener mOnScrollListener;
private MapboxMap.OnMyLocationTrackingModeChangeListener mOnMyLocationTrackingModeChangeListener;
private MapboxMap.OnMyBearingTrackingModeChangeListener mOnMyBearingTrackingModeChangeListener;
private MapboxMap.OnFpsChangedListener mOnFpsChangedListener;
+ private MapboxMap.OnCameraChangeListener mOnCameraChangeListener;
MapboxMap(@NonNull MapView mapView) {
mMapView = mapView;
mMapView.addOnMapChangedListener(new MapChangeCameraPositionListener());
mUiSettings = new UiSettings(mapView);
+ mTrackingSettings = new TrackingSettings(mMapView, mUiSettings);
mProjection = new Projection(mapView);
+ mAnnotations = new LongSparseArray<>();
mSelectedMarkers = new ArrayList<>();
mInfoWindows = new ArrayList<>();
}
@@ -83,6 +93,19 @@ public class MapboxMap {
}
//
+ // TrackingSettings
+ //
+
+ /**
+ * Gets the tracking interface settings for the map.
+ *
+ * @return
+ */
+ public TrackingSettings getTrackingSettings() {
+ return mTrackingSettings;
+ }
+
+ //
// Projection
//
@@ -105,14 +128,7 @@ public class MapboxMap {
*/
public final CameraPosition getCameraPosition() {
if (mInvalidCameraPosition) {
- // Camera position has changed, need to regenerate position
- mCameraPosition = new CameraPosition.Builder(true)
- .bearing((float) mMapView.getBearing())
- .target(mMapView.getLatLng())
- .tilt((float) mMapView.getTilt())
- .zoom((float) mMapView.getZoom())
- .build();
- mInvalidCameraPosition = false;
+ invalidateCameraPosition();
}
return mCameraPosition;
}
@@ -137,8 +153,26 @@ public class MapboxMap {
*/
@UiThread
public final void moveCamera(CameraUpdate update) {
+ moveCamera(update, null);
+ }
+
+ /**
+ * Repositions the camera according to the instructions defined in the update.
+ * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
+ * See CameraUpdateFactory for a set of updates.
+ *
+ * @param update The change that should be applied to the camera.
+ */
+ @UiThread
+ public final void moveCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
mCameraPosition = update.getCameraPosition(this);
mMapView.jumpTo(mCameraPosition.bearing, mCameraPosition.target, mCameraPosition.tilt, mCameraPosition.zoom);
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
+ }
+ if (callback != null) {
+ callback.onFinish();
+ }
}
/**
@@ -175,7 +209,25 @@ public class MapboxMap {
@UiThread
public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
mCameraPosition = update.getCameraPosition(this);
- mMapView.easeTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, callback);
+ mMapView.easeTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, new CancelableCallback() {
+ @Override
+ public void onCancel() {
+ if (callback != null) {
+ callback.onCancel();
+ }
+ }
+
+ @Override
+ public void onFinish() {
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
+ }
+
+ if (callback != null) {
+ callback.onFinish();
+ }
+ }
+ });
}
/**
@@ -227,7 +279,25 @@ public class MapboxMap {
@UiThread
public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
mCameraPosition = update.getCameraPosition(this);
- mMapView.flyTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, callback);
+ mMapView.flyTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, new CancelableCallback() {
+ @Override
+ public void onCancel() {
+ if (callback != null) {
+ callback.onCancel();
+ }
+ }
+
+ @Override
+ public void onFinish() {
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
+ }
+
+ if (callback != null) {
+ callback.onFinish();
+ }
+ }
+ });
}
// internal time layer conversion
@@ -235,75 +305,34 @@ public class MapboxMap {
return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
}
- //
- // ZOOM
- //
-
- /**
- * <p>
- * Sets the minimum zoom level the map can be displayed at.
- * </p>
- *
- * @param minZoom The new minimum zoom level.
- */
- @UiThread
- public void setMinZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) {
- if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
- Log.e(MapboxConstants.TAG, "Not setting minZoom, value is in unsupported range: " + minZoom);
- return;
+ private void invalidateCameraPosition() {
+ mInvalidCameraPosition = false;
+ mCameraPosition = new CameraPosition.Builder(true)
+ .bearing((float) mMapView.getBearing())
+ .target(mMapView.getLatLng())
+ .tilt((float) mMapView.getTilt())
+ .zoom((float) mMapView.getZoom())
+ .build();
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
}
- mMapView.setMinZoom(minZoom);
}
- /**
- * <p>
- * Gets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @return The minimum zoom level.
- */
- @UiThread
- public double getMinZoom() {
- return mMapView.getMinZoom();
- }
-
- /**
- * <p>
- * Sets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @param maxZoom The new maximum zoom level.
- */
- @UiThread
- public void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
- if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
- Log.e(MapboxConstants.TAG, "Not setting maxZoom, value is in unsupported range: " + maxZoom);
- return;
- }
- mMapView.setMaxZoom(maxZoom);
- }
+ //
+ // Reset North
+ //
/**
- * <p>
- * Gets the maximum zoom level the map can be displayed at.
- * </p>
*
- * @return The maximum zoom level.
*/
- @UiThread
- public double getMaxZoom() {
- return mMapView.getMaxZoom();
+ public void resetNorth() {
+ mMapView.resetNorth();
}
//
// Manual zoom controls
//
- // used by UiSettings
- void setZoomControlsEnabled(boolean enabled) {
- mMapView.setZoomControlsEnabled(enabled);
- }
-
//
// Debug
//
@@ -468,7 +497,17 @@ public class MapboxMap {
@UiThread
@NonNull
public Marker addMarker(@NonNull MarkerOptions markerOptions) {
- return mMapView.addMarker(markerOptions);
+ return addMarker((BaseMarkerOptions) markerOptions);
+ }
+
+ @UiThread
+ @NonNull
+ public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
+ Marker marker = prepareMarker(markerOptions);
+ long id = mMapView.addMarker(marker);
+ marker.setId(id);
+ mAnnotations.put(id, marker);
+ return marker;
}
/**
@@ -484,7 +523,50 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
- return mMapView.addMarkers(markerOptionsList);
+ int count = markerOptionsList.size();
+ List<Marker> markers = new ArrayList<>(count);
+ MarkerOptions markerOptions;
+ Marker marker;
+ for (int i = 0; i < count; i++) {
+ markerOptions = markerOptionsList.get(i);
+ marker = prepareMarker(markerOptions);
+ markers.add(marker);
+ }
+
+ long[] ids = mMapView.addMarkers(markers);
+ long id = 0;
+ Marker m;
+
+ for (int i = 0; i < markers.size(); i++) {
+ m = markers.get(i);
+ m.setMapboxMap(this);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ //unit test
+ id++;
+ }
+ m.setId(id);
+ mAnnotations.put(id, m);
+ }
+ return markers;
+ }
+
+ /**
+ * <p>
+ * Updates a marker on this map. Does nothing if the marker is already added.
+ * </p>
+ *
+ * @param updatedMarker An updated marker object.
+ */
+ @UiThread
+ public void updateMarker(@NonNull Marker updatedMarker) {
+ mMapView.updateMarker(updatedMarker);
+
+ int index = mAnnotations.indexOfKey(updatedMarker.getId());
+ if (index > -1) {
+ mAnnotations.setValueAt(index, updatedMarker);
+ }
}
/**
@@ -496,7 +578,14 @@ public class MapboxMap {
@UiThread
@NonNull
public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
- return mMapView.addPolyline(polylineOptions);
+ Polyline polyline = polylineOptions.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ long id = mMapView.addPolyline(polyline);
+ polyline.setMapboxMap(this);
+ polyline.setId(id);
+ mAnnotations.put(id, polyline);
+ }
+ return polyline;
}
/**
@@ -508,7 +597,33 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
- return mMapView.addPolylines(polylineOptionsList);
+ int count = polylineOptionsList.size();
+ Polyline polyline;
+ List<Polyline> polylines = new ArrayList<>(count);
+ for (PolylineOptions options : polylineOptionsList) {
+ polyline = options.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ polylines.add(polyline);
+ }
+ }
+
+ long[] ids = mMapView.addPolylines(polylines);
+ long id = 0;
+ Polyline p;
+
+ for (int i = 0; i < polylines.size(); i++) {
+ p = polylines.get(i);
+ p.setMapboxMap(this);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ // unit test
+ id++;
+ }
+ p.setId(id);
+ mAnnotations.put(id, p);
+ }
+ return polylines;
}
/**
@@ -520,7 +635,14 @@ public class MapboxMap {
@UiThread
@NonNull
public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
- return mMapView.addPolygon(polygonOptions);
+ Polygon polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ long id = mMapView.addPolygon(polygon);
+ polygon.setId(id);
+ polygon.setMapboxMap(this);
+ mAnnotations.put(id, polygon);
+ }
+ return polygon;
}
/**
@@ -532,7 +654,32 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
- return mMapView.addPolygons(polygonOptionsList);
+ int count = polygonOptionsList.size();
+
+ Polygon polygon;
+ List<Polygon> polygons = new ArrayList<>(count);
+ for (PolygonOptions polygonOptions : polygonOptionsList) {
+ polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ polygons.add(polygon);
+ }
+ }
+
+ long[] ids = mMapView.addPolygons(polygons);
+ long id = 0;
+ for (int i = 0; i < polygons.size(); i++) {
+ polygon = polygons.get(i);
+ polygon.setMapboxMap(this);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ // unit test
+ id++;
+ }
+ polygon.setId(id);
+ mAnnotations.put(id, polygon);
+ }
+ return polygons;
}
/**
@@ -549,13 +696,55 @@ public class MapboxMap {
}
/**
+ * <p>
+ * Convenience method for removing a Polyline from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param polyline Polyline to remove
+ */
+ @UiThread
+ public void removePolyline(@NonNull Polyline polyline) {
+ removeAnnotation(polyline);
+ }
+
+ /**
+ * <p>
+ * Convenience method for removing a Polygon from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param polygon Polygon to remove
+ */
+ @UiThread
+ public void removePolygon(@NonNull Polygon polygon) {
+ removeAnnotation(polygon);
+ }
+
+ /**
* Removes an annotation from the map.
*
* @param annotation The annotation object to remove.
*/
@UiThread
public void removeAnnotation(@NonNull Annotation annotation) {
- mMapView.removeAnnotation(annotation);
+ if (annotation instanceof Marker) {
+ ((Marker) annotation).hideInfoWindow();
+ }
+ long id = annotation.getId();
+ mMapView.removeAnnotation(id);
+ mAnnotations.remove(id);
+ }
+
+ /**
+ * Removes an annotation from the map
+ *
+ * @param id The identifier associated to the annotation to be removed
+ */
+ @UiThread
+ public void removeAnnotation(long id) {
+ mMapView.removeAnnotation(id);
+ mAnnotations.remove(id);
}
/**
@@ -565,15 +754,49 @@ public class MapboxMap {
*/
@UiThread
public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
- mMapView.removeAnnotations(annotationList);
+ int count = annotationList.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof Marker) {
+ ((Marker) annotation).hideInfoWindow();
+ }
+ ids[i] = annotationList.get(i).getId();
+ }
+ mMapView.removeAnnotations(ids);
+ for (long id : ids) {
+ mAnnotations.remove(id);
+ }
}
/**
* Removes all annotations from the map.
*/
@UiThread
- public void removeAllAnnotations() {
- mMapView.removeAllAnnotations();
+ public void removeAnnotations() {
+ Annotation annotation;
+ int count = mAnnotations.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ ids[i] = mAnnotations.keyAt(i);
+ annotation = mAnnotations.get(ids[i]);
+ if (annotation instanceof Marker) {
+ ((Marker) annotation).hideInfoWindow();
+ }
+ }
+ mMapView.removeAnnotations(ids);
+ mAnnotations.clear();
+ }
+
+ /**
+ * Return a annotation based on its id.
+ *
+ * @return An annotation with a matched id, null is returned if no match was found.
+ */
+ @UiThread
+ @Nullable
+ public Annotation getAnnotation(long id) {
+ return mAnnotations.get(id);
}
/**
@@ -583,8 +806,69 @@ public class MapboxMap {
* list will not update the map.
*/
@NonNull
- public List<Annotation> getAllAnnotations() {
- return mMapView.getAllAnnotations();
+ public List<Annotation> getAnnotations() {
+ List<Annotation> annotations = new ArrayList<>();
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotations.add(mAnnotations.get(mAnnotations.keyAt(i)));
+ }
+ return annotations;
+ }
+
+ /**
+ * Returns a list of all the markers on the map.
+ *
+ * @return A list of all the markers objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Marker> getMarkers() {
+ List<Marker> markers = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotation = mAnnotations.get(mAnnotations.keyAt(i));
+ if (annotation instanceof Marker) {
+ markers.add((Marker) annotation);
+ }
+ }
+ return markers;
+ }
+
+ /**
+ * Returns a list of all the polygons on the map.
+ *
+ * @return A list of all the polygon objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Polygon> getPolygons() {
+ List<Polygon> polygons = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotation = mAnnotations.get(mAnnotations.keyAt(i));
+ if (annotation instanceof Polygon) {
+ polygons.add((Polygon) annotation);
+ }
+ }
+ return polygons;
+ }
+
+ /**
+ * Returns a list of all the polylines on the map.
+ *
+ * @return A list of all the polylines objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Polyline> getPolylines() {
+ List<Polyline> polylines = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotation = mAnnotations.get(mAnnotations.keyAt(i));
+ if (annotation instanceof Polyline) {
+ polylines.add((Polyline) annotation);
+ }
+ }
+ return polylines;
}
/**
@@ -670,11 +954,17 @@ public class MapboxMap {
* @return The currently selected marker.
*/
@UiThread
- @Nullable
public List<Marker> getSelectedMarkers() {
return mSelectedMarkers;
}
+ private Marker prepareMarker(BaseMarkerOptions markerOptions) {
+ Marker marker = markerOptions.getMarker();
+ Icon icon = mMapView.loadIconForMarker(marker);
+ marker.setTopOffsetPixels(mMapView.getTopOffsetPixelsForIcon(icon));
+ return marker;
+ }
+
//
// InfoWindow
//
@@ -735,10 +1025,58 @@ public class MapboxMap {
}
//
+ // Padding
+ //
+
+ /**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ * <p/>
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ public void setPadding(int left, int top, int right, int bottom) {
+ mMapView.setContentPadding(left, top, right, bottom);
+ mUiSettings.invalidate();
+
+ moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder(mCameraPosition).build()));
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int[] getPadding() {
+ return new int[]{mMapView.getContentPaddingLeft(),
+ mMapView.getContentPaddingTop(),
+ mMapView.getContentPaddingRight(),
+ mMapView.getContentPaddingBottom()};
+ }
+
+ //
// Map events
//
/**
+ * Sets a callback that's invoked on every change in camera position.
+ *
+ * @param listener The callback that's invoked on every camera change position.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) {
+ mOnCameraChangeListener = listener;
+ }
+
+ /**
* Sets a callback that's invoked on every frame rendered to the map view.
*
* @param listener The callback that's invoked on every frame rendered to the map view.
@@ -845,10 +1183,44 @@ public class MapboxMap {
*
* @return Current active InfoWindow Click Listener
*/
+ @UiThread
public OnInfoWindowClickListener getOnInfoWindowClickListener() {
return mOnInfoWindowClickListener;
}
+ /**
+ * Sets a callback that's invoked when a marker's info window is long pressed.
+ *
+ * @param listener The callback that's invoked when a marker's info window is long pressed. To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnInfoWindowLongClickListener(@Nullable OnInfoWindowLongClickListener listener) {
+ mOnInfoWindowLongClickListener = listener;
+ }
+
+ /**
+ * Return the InfoWindow long click listener
+ *
+ * @return Current active InfoWindow long Click Listener
+ */
+ public OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
+ return mOnInfoWindowLongClickListener;
+ }
+
+ public void setOnInfoWindowCloseListener(@Nullable OnInfoWindowCloseListener listener) {
+ mOnInfoWindowCloseListener = listener;
+ }
+
+ /**
+ * Return the InfoWindow close listener
+ *
+ * @return Current active InfoWindow Close Listener
+ */
+ @UiThread
+ public OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
+ return mOnInfoWindowCloseListener;
+ }
+
//
// User location
//
@@ -874,13 +1246,14 @@ public class MapboxMap {
* or @link android.Manifest.permission#ACCESS_FINE_LOCATION.
*
* @param enabled True to enable; false to disable.
- * @throws SecurityException if no suitable permission is present
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
public void setMyLocationEnabled(boolean enabled) {
+ if (!mMapView.isPermissionsAccepted()) {
+ Log.e(MapboxConstants.TAG, "Could not activate user location tracking: " +
+ "user did not accept the permission or permissions were not requested.");
+ return;
+ }
mMyLocationEnabled = enabled;
mMapView.setMyLocationEnabled(enabled);
}
@@ -909,40 +1282,6 @@ public class MapboxMap {
}
/**
- * <p>
- * Set the current my location tracking mode.
- * </p>
- * <p>
- * Will enable my location if not active.
- * </p>
- * See {@link MyLocationTracking} for different values.
- *
- * @param myLocationTrackingMode The location tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
- * @see MyLocationTracking
- */
- @UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
- public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
- mMapView.setMyLocationTrackingMode(myLocationTrackingMode);
- }
-
- /**
- * Returns the current user location tracking mode.
- *
- * @return The current user location tracking mode.
- * One of the values from {@link MyLocationTracking.Mode}.
- * @see MyLocationTracking.Mode
- */
- @UiThread
- @MyLocationTracking.Mode
- public int getMyLocationTrackingMode() {
- return mMapView.getMyLocationTrackingMode();
- }
-
- /**
* 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.
@@ -959,42 +1298,6 @@ public class MapboxMap {
}
/**
- * <p>
- * Set the current my bearing tracking mode.
- * </p>
- * Shows the direction the user is heading.
- * <p>
- * When location tracking is disabled the direction of {@link UserLocationView} is rotated
- * When location tracking is enabled the {@link MapView} is rotated based on bearing value.
- * </p>
- * See {@link MyBearingTracking} for different values.
- *
- * @param myBearingTrackingMode The bearing tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
- * @see MyBearingTracking
- */
- @UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
- public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
- mMapView.setMyBearingTrackingMode(myBearingTrackingMode);
- }
-
- /**
- * Returns the current user bearing tracking mode.
- * See {@link MyBearingTracking} for possible return values.
- *
- * @return the current user bearing tracking mode.
- * @see MyBearingTracking
- */
- @UiThread
- @MyLocationTracking.Mode
- public int getMyBearingTrackingMode() {
- return mMapView.getMyBearingTrackingMode();
- }
-
- /**
* Sets a callback that's invoked when the bearing tracking mode changes.
*
* @param listener The callback that's invoked when the bearing tracking mode changes.
@@ -1033,9 +1336,17 @@ public class MapboxMap {
return mMapView;
}
-//
-// Interfaces
-//
+ //
+ // Invalidate
+ //
+
+ public void invalidate(){
+ mMapView.update();
+ }
+
+ //
+ // Interfaces
+ //
/**
* Interface definition for a callback to be invoked when the map is flinged.
@@ -1062,6 +1373,20 @@ public class MapboxMap {
}
/**
+ * Interface definition for a callback to be invoked for when the camera changes position.
+ */
+ public interface OnCameraChangeListener {
+ /**
+ * Called after the camera position has changed. During an animation,
+ * this listener may not be notified of intermediate camera positions.
+ * It is always called for the final position in the animation.
+ *
+ * @param position The CameraPosition at the end of the last camera change.
+ */
+ void onCameraChange(CameraPosition position);
+ }
+
+ /**
* Interface definition for a callback to be invoked on every frame rendered to the map view.
*
* @see MapboxMap#setOnFpsChangedListener(OnFpsChangedListener)
@@ -1130,7 +1455,37 @@ public class MapboxMap {
* @param marker The marker of the info window the user clicked on.
* @return If true the listener has consumed the event and the info window will not be closed.
*/
- boolean onMarkerClick(@NonNull Marker marker);
+ boolean onInfoWindowClick(@NonNull Marker marker);
+ }
+
+ /**
+ * Callback interface for when the user long presses on a marker's info window.
+ *
+ * @see MapboxMap#setOnInfoWindowClickListener(OnInfoWindowClickListener)
+ */
+ public interface OnInfoWindowLongClickListener {
+
+ /**
+ * Called when the user makes a long-press gesture on the marker's info window.
+ *
+ * @param marker The marker were the info window is attached to
+ */
+ void onInfoWindowLongClick(Marker marker);
+ }
+
+ /**
+ * Callback interface for close events on a marker's info window.
+ *
+ * @see MapboxMap#setOnInfoWindowCloseListener(OnInfoWindowCloseListener)
+ */
+ public interface OnInfoWindowCloseListener {
+
+ /**
+ * Called when the marker's info window is closed.
+ *
+ * @param marker The marker of the info window that was closed.
+ */
+ void onInfoWindowClose(Marker marker);
}
/**
@@ -1169,7 +1524,7 @@ public class MapboxMap {
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
- * @see MapboxMap#setMyLocationTrackingMode(int)
+ * @see MapView#setMyLocationTrackingMode(int)
*/
public interface OnMyLocationTrackingModeChangeListener {
@@ -1184,7 +1539,7 @@ public class MapboxMap {
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
- * @see MapboxMap#setMyLocationTrackingMode(int)
+ * @see MapView#setMyLocationTrackingMode(int)
*/
public interface OnMyBearingTrackingModeChangeListener {
@@ -1212,13 +1567,20 @@ public class MapboxMap {
}
private class MapChangeCameraPositionListener implements MapView.OnMapChangedListener {
+
+ private static final long UPDATE_RATE_MS = 400;
+ private long mPreviousUpdateTimestamp = 0;
+
@Override
public void onMapChanged(@MapView.MapChange int change) {
- if (!mInvalidCameraPosition && (change == MapView.REGION_DID_CHANGE
- || change == MapView.REGION_DID_CHANGE_ANIMATED
- || change == MapView.REGION_WILL_CHANGE
- || change == MapView.REGION_WILL_CHANGE_ANIMATED)) {
+ if (change >= MapView.REGION_WILL_CHANGE && change <= MapView.REGION_DID_CHANGE_ANIMATED) {
mInvalidCameraPosition = true;
+ long currentTime = SystemClock.elapsedRealtime();
+ if (currentTime < mPreviousUpdateTimestamp) {
+ return;
+ }
+ invalidateCameraPosition();
+ mPreviousUpdateTimestamp = currentTime + UPDATE_RATE_MS;
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
deleted file mode 100644
index cb6407986e..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-
-/**
- * Builder for composing {@link MapboxMap} objects. These options can be used when adding a
- * map to your application programmatically (as opposed to via XML). If you are using a MapFragment,
- * you can pass these options in using the static factory method newInstance(MapboxMapOptions).
- * If you are using a MapView, you can pass these options in using the constructor MapView(Context, MapboxMapOptions).
- */
-public class MapboxMapOptions implements Parcelable {
-
- private MapboxMap mMapboxMap;
- private UiSettings mUiSettings;
-
- public MapboxMapOptions(MapboxMap mapboxMap) {
- mMapboxMap = mapboxMap;
- mUiSettings = mapboxMap.getUiSettings();
- }
-
- public MapboxMapOptions(Parcel in) {
- throw new UnsupportedOperationException();
- }
-
- public MapboxMapOptions camera(CameraPosition camera) {
- mMapboxMap.setCameraPosition(camera);
- return this;
- }
-
- public CameraPosition getCamera() {
- return mMapboxMap.getCameraPosition();
- }
-
- public MapboxMapOptions compassEnabled(boolean enabled) {
- mUiSettings.setCompassEnabled(enabled);
- return this;
- }
-
- public boolean getCompassEnabled() {
- return mUiSettings.isCompassEnabled();
- }
-
- public MapboxMapOptions rotateEnabled(boolean rotateEnabled) {
- mUiSettings.setRotateGesturesEnabled(rotateEnabled);
- return this;
- }
-
- public MapboxMapOptions rotateGesturesEnabled(boolean enabled) {
- mUiSettings.setRotateGesturesEnabled(enabled);
- return this;
- }
-
- public boolean getRotateGesturesEnabled() {
- return mUiSettings.isRotateGesturesEnabled();
- }
-
- public MapboxMapOptions scrollGesturesEnabled(boolean enabled) {
- mUiSettings.setScrollGesturesEnabled(enabled);
- return this;
- }
-
- public boolean getScrollGesturesEnabled() {
- return mUiSettings.isScrollGesturesEnabled();
- }
-
- public MapboxMapOptions tiltGesturesEnabled(boolean enabled) {
- mUiSettings.setTiltGesturesEnabled(enabled);
- return this;
- }
-
- public boolean getTiltGesturesEnabled() {
- return mUiSettings.isTiltGesturesEnabled();
- }
-
- public MapboxMapOptions zoomControlsEnabled(boolean enabled) {
- mUiSettings.setZoomControlsEnabled(enabled);
- return this;
- }
-
- public boolean getZoomControlsEnabled() {
- return mUiSettings.isZoomControlsEnabled();
- }
-
- public boolean getZoomGesturesEnabled() {
- return mUiSettings.isZoomGesturesEnabled();
- }
-
- public MapboxMapOptions createFromAttributes(Context context, AttributeSet attrs) {
- throw new UnsupportedOperationException();
- }
-
- public static final Parcelable.Creator<MapboxMapOptions> CREATOR = new Parcelable.Creator<MapboxMapOptions>() {
- public MapboxMapOptions createFromParcel(Parcel in) {
- return new MapboxMapOptions(in);
- }
-
- public MapboxMapOptions[] newArray(int size) {
- return new MapboxMapOptions[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 6c388d9d8a..b7f583e943 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -395,6 +395,10 @@ final class NativeMapView {
return nativeAddPolygons(mNativeMapViewPtr, polygon);
}
+ public void updateMarker(Marker marker) {
+ nativeUpdateMarker(mNativeMapViewPtr, marker);
+ }
+
public void removeAnnotation(long id) {
nativeRemoveAnnotation(mNativeMapViewPtr, id);
}
@@ -619,6 +623,8 @@ final class NativeMapView {
private native long nativeAddMarker(long nativeMapViewPtr, Marker marker);
+ private native void nativeUpdateMarker(long nativeMapViewPtr, Marker marker);
+
private native long[] nativeAddMarkers(long nativeMapViewPtr, List<Marker> markers);
private native long nativeAddPolyline(long nativeMapViewPtr, Polyline polyline);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
index e53d430b69..0d5745d4c9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.maps;
import android.graphics.PointF;
+import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -21,6 +22,20 @@ public class Projection {
}
/**
+ * <p>
+ * Returns the distance spanned by one pixel at the specified latitude and current zoom level.
+ * </p>
+ * The distance between pixels decreases as the latitude approaches the poles.
+ * This relationship parallels the relationship between longitudinal coordinates at different latitudes.
+ *
+ * @param latitude The latitude for which to return the value.
+ * @return The distance measured in meters.
+ */
+ public double getMetersPerPixelAtLatitude(@FloatRange(from = -180, to = 180) double latitude) {
+ return mMapView.getMetersPerPixelAtLatitude(latitude);
+ }
+
+ /**
* Returns the geographic location that corresponds to a screen location.
* The screen location is specified in screen pixels (not display pixels) relative to the
* top left of the map (not the top left of the whole screen).
@@ -55,7 +70,7 @@ public class Projection {
.include(bottomRight)
.include(bottomLeft);
- return new VisibleRegion(topLeft,topRight,bottomLeft,bottomRight,builder.build());
+ return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
}
/**
@@ -69,4 +84,14 @@ public class Projection {
public PointF toScreenLocation(LatLng location) {
return mMapView.toScreenLocation(location);
}
+
+ /**
+ * Calculates a zoom level based on minimum scale and current scale from MapView
+ *
+ * @param minScale The minimum scale to calculate the zoom level.
+ * @return zoom level that fits the MapView.
+ */
+ public double calculateZoom(float minScale) {
+ return Math.log(mMapView.getScale() * minScale) / Math.log(2);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
index 147cd31b5a..8783712e10 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.maps;
import android.os.Bundle;
+import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
@@ -29,18 +30,10 @@ public class SupportMapFragment extends Fragment {
private MapView mMap;
- public static SupportMapFragment newInstance(){
+ public static SupportMapFragment newInstance() {
return new SupportMapFragment();
}
- public static SupportMapFragment newInstance(MapboxMapOptions mapboxMapOptions) {
- final SupportMapFragment mapFragment = new SupportMapFragment();
- Bundle bundle = new Bundle();
- bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
- mapFragment.setArguments(bundle);
- return mapFragment;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
@@ -94,7 +87,12 @@ public class SupportMapFragment extends Fragment {
}
@NonNull
- public void getMapAsync(@NonNull OnMapReadyCallback onMapReadyCallback){
- mMap.getMapAsync(onMapReadyCallback);
+ public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ mMap.getMapAsync(onMapReadyCallback);
+ }
+ });
}
}
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
new file mode 100644
index 0000000000..543ff19e56
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
@@ -0,0 +1,121 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
+
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+
+public class TrackingSettings {
+
+ private MapView mapView;
+ private UiSettings uiSettings;
+ private boolean dismissTrackingOnGesture = true;
+
+ @MyLocationTracking.Mode
+ private int mMyLocationTrackingMode;
+
+ @MyBearingTracking.Mode
+ private int mMyBearingTrackingMode;
+
+ TrackingSettings(@NonNull MapView mapView, UiSettings uiSettings) {
+ this.mapView = mapView;
+ this.uiSettings = uiSettings;
+ }
+
+ /**
+ * <p>
+ * Set the current my location tracking mode.
+ * </p>
+ * <p>
+ * Will enable my location if not active.
+ * </p>
+ * See {@link MyLocationTracking} for different values.
+ *
+ * @param myLocationTrackingMode The location tracking mode to be used.
+ * @throws SecurityException if no suitable permission is present
+ * @see MyLocationTracking
+ */
+ @UiThread
+ public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
+ mMyLocationTrackingMode = myLocationTrackingMode;
+ mapView.setMyLocationTrackingMode(myLocationTrackingMode);
+ validateGesturesForTrackingModes();
+ }
+
+ /**
+ * Returns the current user location tracking mode.
+ *
+ * @return The current user location tracking mode.
+ * One of the values from {@link MyLocationTracking.Mode}.
+ * @see MyLocationTracking.Mode
+ */
+ @UiThread
+ @MyLocationTracking.Mode
+ public int getMyLocationTrackingMode() {
+ return mMyLocationTrackingMode;
+ }
+
+ /**
+ * <p>
+ * Set the current my bearing tracking mode.
+ * </p>
+ * Shows the direction the user is heading.
+ * <p>
+ * When location tracking is disabled the direction of {@link UserLocationView} is rotated
+ * When location tracking is enabled the {@link MapView} is rotated based on bearing value.
+ * </p>
+ * See {@link MyBearingTracking} for different values.
+ *
+ * @param myBearingTrackingMode The bearing tracking mode to be used.
+ * @throws SecurityException if no suitable permission is present
+ * @see MyBearingTracking
+ */
+ @UiThread
+ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ mMyBearingTrackingMode = myBearingTrackingMode;
+ mapView.setMyBearingTrackingMode(myBearingTrackingMode);
+ }
+
+ /**
+ * Returns the current user bearing tracking mode.
+ * See {@link MyBearingTracking} for possible return values.
+ *
+ * @return the current user bearing tracking mode.
+ * @see MyBearingTracking
+ */
+ @UiThread
+ @MyLocationTracking.Mode
+ public int getMyBearingTrackingMode() {
+ return mMyBearingTrackingMode;
+ }
+
+ public boolean isDismissTrackingOnGesture() {
+ return dismissTrackingOnGesture;
+ }
+
+ public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
+ this.dismissTrackingOnGesture = dismissTrackingOnGesture;
+ validateGesturesForTrackingModes();
+ }
+
+ private void validateGesturesForTrackingModes() {
+ if (!dismissTrackingOnGesture) {
+ int myLocationTrackingMode = getMyLocationTrackingMode();
+ int myBearingTrackingMode = getMyBearingTrackingMode();
+
+ // Enable/disable gestures based on tracking mode
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
+ uiSettings.setScrollGesturesEnabled(true);
+ uiSettings.setRotateGesturesEnabled(true);
+ } else {
+ uiSettings.setScrollGesturesEnabled(false);
+ uiSettings.setRotateGesturesEnabled((myBearingTrackingMode == MyBearingTracking.NONE));
+ }
+ }
+ }
+
+ public boolean isLocationTrackingDisabled(){
+ return mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
index d6cb106054..1538f49d60 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
@@ -1,9 +1,14 @@
package com.mapbox.mapboxsdk.maps;
+import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
+import android.util.Log;
import android.view.Gravity;
import android.view.View;
+import android.widget.VideoView;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
/**
* Settings for the user interface of a MapboxMap. To obtain this interface, call getUiSettings().
@@ -12,17 +17,9 @@ public class UiSettings {
private MapView mapView;
- private boolean compassEnabled;
- private int compassGravity;
- private int[] compassMargins;
-
- private boolean logoEnabled;
- private int logoGravity;
- private int[] logoMargins;
-
- private boolean attributionEnabled;
- private int attributionGravity;
- private int[] attributionMargins;
+ private ViewSettings compassSettings;
+ private ViewSettings logoSettings;
+ private ViewSettings attributionSettings;
private boolean rotateGesturesEnabled;
private boolean tiltGesturesEnabled;
@@ -30,11 +27,78 @@ public class UiSettings {
private boolean zoomControlsEnabled;
private boolean scrollGesturesEnabled;
+ private double maxZoomLevel = -1;
+ private double minZoomLevel = -1;
+
UiSettings(@NonNull MapView mapView) {
this.mapView = mapView;
- this.compassMargins = new int[4];
- this.attributionMargins = new int[4];
- this.logoMargins = new int[4];
+ this.compassSettings = new ViewSettings();
+ this.logoSettings = new ViewSettings();
+ this.attributionSettings = new ViewSettings();
+ }
+
+ /**
+ * <p>
+ * Sets the minimum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @param minZoom The new minimum zoom level.
+ */
+ @UiThread
+ public void setMinZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) {
+ if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
+ Log.e(MapboxConstants.TAG, "Not setting minZoom, value is in unsupported range: " + minZoom);
+ return;
+ }
+ minZoomLevel = minZoom;
+ mapView.setMinZoom(minZoom);
+ }
+
+ /**
+ * <p>
+ * Gets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @return The minimum zoom level.
+ */
+ @UiThread
+ public double getMinZoom() {
+ if (minZoomLevel == -1) {
+ return minZoomLevel = mapView.getMinZoom();
+ }
+ return minZoomLevel;
+ }
+
+ /**
+ * <p>
+ * Sets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @param maxZoom The new maximum zoom level.
+ */
+ @UiThread
+ public void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
+ if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
+ Log.e(MapboxConstants.TAG, "Not setting maxZoom, value is in unsupported range: " + maxZoom);
+ return;
+ }
+ maxZoomLevel = maxZoom;
+ mapView.setMaxZoom(maxZoom);
+ }
+
+ /**
+ * <p>
+ * Gets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @return The maximum zoom level.
+ */
+ @UiThread
+ public double getMaxZoom() {
+ if (maxZoomLevel == -1) {
+ return maxZoomLevel = mapView.getMaxZoom();
+ }
+ return maxZoomLevel;
}
/**
@@ -49,8 +113,8 @@ public class UiSettings {
* @param compassEnabled True to enable the compass; false to disable the compass.
*/
public void setCompassEnabled(boolean compassEnabled) {
- this.compassEnabled = compassEnabled;
- this.mapView.setCompassEnabled(compassEnabled);
+ compassSettings.setEnabled(compassEnabled);
+ mapView.setCompassEnabled(compassEnabled);
}
/**
@@ -59,7 +123,7 @@ public class UiSettings {
* @return True if the compass is enabled; false if the compass is disabled.
*/
public boolean isCompassEnabled() {
- return compassEnabled;
+ return compassSettings.isEnabled();
}
/**
@@ -74,8 +138,8 @@ public class UiSettings {
*/
@UiThread
public void setCompassGravity(int gravity) {
- this.compassGravity = gravity;
- this.mapView.setCompassGravity(gravity);
+ compassSettings.setGravity(gravity);
+ mapView.setCompassGravity(gravity);
}
/**
@@ -84,7 +148,7 @@ public class UiSettings {
* @return The gravity
*/
public int getCompassGravity() {
- return compassGravity;
+ return compassSettings.getGravity();
}
/**
@@ -98,8 +162,8 @@ public class UiSettings {
*/
@UiThread
public void setCompassMargins(int left, int top, int right, int bottom) {
- this.compassMargins = new int[]{left, top, right, bottom};
- this.mapView.setCompassMargins(left, top, right, bottom);
+ compassSettings.setMargins(new int[]{left, top, right, bottom});
+ mapView.setCompassMargins(left, top, right, bottom);
}
/**
@@ -108,7 +172,7 @@ public class UiSettings {
* @return The left margin in pixels
*/
public int getCompassMarginLeft() {
- return compassMargins[0];
+ return compassSettings.getMargins()[0];
}
/**
@@ -117,7 +181,7 @@ public class UiSettings {
* @return The top margin in pixels
*/
public int getCompassMarginTop() {
- return compassMargins[1];
+ return compassSettings.getMargins()[1];
}
/**
@@ -126,7 +190,7 @@ public class UiSettings {
* @return The right margin in pixels
*/
public int getCompassMarginRight() {
- return compassMargins[2];
+ return compassSettings.getMargins()[2];
}
/**
@@ -135,7 +199,7 @@ public class UiSettings {
* @return The bottom margin in pixels
*/
public int getCompassMarginBottom() {
- return compassMargins[3];
+ return compassSettings.getMargins()[3];
}
/**
@@ -147,8 +211,8 @@ public class UiSettings {
* @param enabled True to enable the logo; false to disable the logo.
*/
public void setLogoEnabled(boolean enabled) {
- this.logoEnabled = enabled;
- this.mapView.setLogoVisibility(enabled );
+ logoSettings.setEnabled(enabled);
+ mapView.setLogoVisibility(enabled);
}
/**
@@ -157,7 +221,7 @@ public class UiSettings {
* @return True if the logo is enabled; false if the logo is disabled.
*/
public boolean isLogoEnabled() {
- return logoEnabled;
+ return logoSettings.isEnabled();
}
/**
@@ -171,8 +235,8 @@ public class UiSettings {
* @see Gravity
*/
public void setLogoGravity(int gravity) {
- this.logoGravity = gravity;
- this.mapView.setLogoGravity(gravity);
+ logoSettings.setGravity(gravity);
+ mapView.setLogoGravity(gravity);
}
/**
@@ -181,7 +245,7 @@ public class UiSettings {
* @return The gravity
*/
public int getLogoGravity() {
- return logoGravity;
+ return logoSettings.getGravity();
}
/**
@@ -194,8 +258,8 @@ public class UiSettings {
* @param bottom The bottom margin in pixels.
*/
public void setLogoMargins(int left, int top, int right, int bottom) {
- this.logoMargins = new int[]{left, top, right, bottom};
- this.mapView.setLogoMargins(left, top, right, bottom);
+ logoSettings.setMargins(new int[]{left, top, right, bottom});
+ mapView.setLogoMargins(left, top, right, bottom);
}
/**
@@ -203,8 +267,8 @@ public class UiSettings {
*
* @return The left margin in pixels
*/
- public int getLogoMarginLeft(){
- return logoMargins[0];
+ public int getLogoMarginLeft() {
+ return logoSettings.getMargins()[0];
}
/**
@@ -212,8 +276,8 @@ public class UiSettings {
*
* @return The top margin in pixels
*/
- public int getLogoMarginTop(){
- return logoMargins[1];
+ public int getLogoMarginTop() {
+ return logoSettings.getMargins()[1];
}
/**
@@ -221,8 +285,8 @@ public class UiSettings {
*
* @return The right margin in pixels
*/
- public int getLogoMarginRight(){
- return logoMargins[2];
+ public int getLogoMarginRight() {
+ return logoSettings.getMargins()[2];
}
/**
@@ -230,8 +294,8 @@ public class UiSettings {
*
* @return The bottom margin in pixels
*/
- public int getLogoMarginBottom(){
- return logoMargins[3];
+ public int getLogoMarginBottom() {
+ return logoSettings.getMargins()[3];
}
/**
@@ -243,8 +307,8 @@ public class UiSettings {
* @param enabled True to enable the logo; false to disable the logo.
*/
public void setAttributionEnabled(boolean enabled) {
- this.attributionEnabled = enabled;
- this.mapView.setAttributionVisibility(enabled ? View.VISIBLE : View.GONE);
+ attributionSettings.setEnabled(enabled);
+ mapView.setAttributionVisibility(enabled ? View.VISIBLE : View.GONE);
}
/**
@@ -253,7 +317,7 @@ public class UiSettings {
* @return True if the logo is enabled; false if the logo is disabled.
*/
public boolean isAttributionEnabled() {
- return attributionEnabled;
+ return attributionSettings.isEnabled();
}
/**
@@ -267,8 +331,8 @@ public class UiSettings {
* @see Gravity
*/
public void setAttributionGravity(int gravity) {
- this.attributionGravity = gravity;
- this.mapView.setAttributionGravity(gravity);
+ attributionSettings.setGravity(gravity);
+ mapView.setAttributionGravity(gravity);
}
/**
@@ -277,7 +341,7 @@ public class UiSettings {
* @return The gravity
*/
public int getAttributionGravity() {
- return attributionGravity;
+ return attributionSettings.getGravity();
}
/**
@@ -290,8 +354,8 @@ public class UiSettings {
* @param bottom The bottom margin in pixels.
*/
public void setAttributionMargins(int left, int top, int right, int bottom) {
- this.attributionMargins = new int[]{left, top, right, bottom};
- this.mapView.setAttributionMargins(left, top, right, bottom);
+ attributionSettings.setMargins(new int[]{left, top, right, bottom});
+ mapView.setAttributionMargins(left, top, right, bottom);
}
/**
@@ -299,8 +363,8 @@ public class UiSettings {
*
* @return The left margin in pixels
*/
- public int getAttributionMarginLeft(){
- return attributionMargins[0];
+ public int getAttributionMarginLeft() {
+ return attributionSettings.getMargins()[0];
}
/**
@@ -308,8 +372,8 @@ public class UiSettings {
*
* @return The top margin in pixels
*/
- public int getAttributionMarginTop(){
- return attributionMargins[1];
+ public int getAttributionMarginTop() {
+ return attributionSettings.getMargins()[1];
}
/**
@@ -317,8 +381,8 @@ public class UiSettings {
*
* @return The right margin in pixels
*/
- public int getAttributionMarginRight(){
- return attributionMargins[2];
+ public int getAttributionMarginRight() {
+ return attributionSettings.getMargins()[2];
}
/**
@@ -326,8 +390,8 @@ public class UiSettings {
*
* @return The bottom margin in pixels
*/
- public int getAttributionMarginBottom(){
- return attributionMargins[3];
+ public int getAttributionMarginBottom() {
+ return attributionSettings.getMargins()[3];
}
/**
@@ -477,4 +541,31 @@ public class UiSettings {
setTiltGesturesEnabled(enabled);
setZoomGesturesEnabled(enabled);
}
+
+ /**
+ * Returns the measured height of the MapView
+ *
+ * @return height in pixels
+ */
+ public float getHeight() {
+ return mapView.getMeasuredHeight();
+ }
+
+ /**
+ * Returns the measured width of the MapView
+ *
+ * @return widht in pixels
+ */
+ public float getWidth() {
+ return mapView.getMeasuredWidth();
+ }
+
+ /**
+ * Invalidates the ViewSettings instances shown on top of the MapView
+ */
+ public void invalidate() {
+ mapView.setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom());
+ mapView.setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom());
+ mapView.setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(), getAttributionMarginBottom());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java
new file mode 100644
index 0000000000..a192a1b576
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java
@@ -0,0 +1,36 @@
+package com.mapbox.mapboxsdk.maps;
+
+public class ViewSettings {
+
+ private boolean enabled;
+ private int gravity;
+ private int[]margins;
+
+ public ViewSettings() {
+ margins = new int[4];
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public int getGravity() {
+ return gravity;
+ }
+
+ public void setGravity(int gravity) {
+ this.gravity = gravity;
+ }
+
+ public int[] getMargins() {
+ return margins;
+ }
+
+ public void setMargins(int[] margins) {
+ this.margins = margins;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
index 0d84289332..28afb70de3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.maps.widgets;
import android.content.Context;
import android.support.v4.content.ContextCompat;
@@ -11,6 +11,8 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import com.mapbox.mapboxsdk.R;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
import java.lang.ref.WeakReference;
import java.util.Timer;
@@ -21,7 +23,7 @@ import java.util.TimerTask;
* when it isn't true north (0.0). Tapping the compass resets the bearing to true
* north and hides the compass.
*/
-public class CompassView extends ImageView {
+public final class CompassView extends ImageView {
private Timer mNorthTimer;
private double mDirection = 0.0f;
@@ -46,7 +48,7 @@ public class CompassView extends ImageView {
// View configuration
setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.compass));
- setContentDescription(getResources().getString(R.string.compassContentDescription));
+ setContentDescription(getResources().getString(R.string.mapbox_compassContentDescription));
setEnabled(false);
// Layout params
@@ -139,17 +141,17 @@ public class CompassView extends ImageView {
public static class CompassClickListener implements View.OnClickListener {
- private WeakReference<MapView> mMapView;
+ private WeakReference<MapboxMap> mMapboxMap;
- public CompassClickListener(final MapView mapView) {
- mMapView = new WeakReference<>(mapView);
+ public CompassClickListener(final MapboxMap mapboxMap) {
+ mMapboxMap = new WeakReference<>(mapboxMap);
}
@Override
public void onClick(View v) {
- final MapView mapView = mMapView.get();
- if (mapView != null) {
- mapView.resetNorth();
+ final MapboxMap mapboxMap = mMapboxMap.get();
+ if (mapboxMap != null) {
+ mapboxMap.resetNorth();
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UserLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/UserLocationView.java
index 9f8261a0a7..98d66b9307 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UserLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/UserLocationView.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.maps.widgets;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -27,11 +27,14 @@ import android.view.ViewGroup;
import com.mapbox.mapboxsdk.R;
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.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationService;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.Projection;
import java.lang.ref.WeakReference;
@@ -42,9 +45,8 @@ import java.lang.ref.WeakReference;
public final class UserLocationView extends View {
- private MapView mMapView;
-
- private float mDensity;
+ private MapboxMap mMapboxMap;
+ private Projection mProjection;
private boolean mShowMarker;
private boolean mShowDirection;
@@ -84,7 +86,6 @@ public final class UserLocationView extends View {
private LatLng mCurrentMapViewCoordinate;
private double mCurrentBearing;
-
private boolean mPaused = false;
private Location mUserLocation;
private UserLocationListener mUserLocationListener;
@@ -99,7 +100,6 @@ public final class UserLocationView extends View {
// Compass data
private MyBearingListener mBearingChangeListener;
- private static final long BEARING_DURATION = 100;
public UserLocationView(Context context) {
super(context);
@@ -132,9 +132,9 @@ public final class UserLocationView extends View {
// Setup the custom paint
Resources resources = context.getResources();
- int accuracyColor = resources.getColor(R.color.my_location_ring);
+ int accuracyColor = ContextCompat.getColor(context,R.color.my_location_ring);
- mDensity = resources.getDisplayMetrics().density;
+ float density = resources.getDisplayMetrics().density;
mMarkerCoordinate = new LatLng(0.0, 0.0);
mMarkerScreenPoint = new PointF();
mMarkerScreenMatrix = new Matrix();
@@ -148,7 +148,7 @@ public final class UserLocationView extends View {
mAccuracyPaintStroke = new Paint();
mAccuracyPaintStroke.setAntiAlias(true);
mAccuracyPaintStroke.setStyle(Paint.Style.STROKE);
- mAccuracyPaintStroke.setStrokeWidth(0.5f * mDensity);
+ mAccuracyPaintStroke.setStrokeWidth(0.5f * density);
mAccuracyPaintStroke.setColor(accuracyColor);
mAccuracyPaintStroke.setAlpha((int) (255 * 0.5f));
@@ -195,8 +195,9 @@ public final class UserLocationView extends View {
mUserLocationStaleDrawable.setBounds(mUserLocationStaleDrawableBounds);
}
- public void setMapView(MapView mapView) {
- mMapView = mapView;
+ public void setMapboxMap(MapboxMap mapboxMap) {
+ mMapboxMap = mapboxMap;
+ mProjection = mapboxMap.getProjection();
}
public void onStart() {
@@ -247,21 +248,15 @@ public final class UserLocationView extends View {
if (myLocationTrackingMode != MyLocationTracking.TRACKING_NONE && mUserLocation != null) {
// center map directly if we have a location fix
mMarkerCoordinate = new LatLng(mUserLocation.getLatitude(), mUserLocation.getLongitude());
- mMapView.getMapboxMap().moveCamera(CameraUpdateFactory.newLatLng(new LatLng(mUserLocation)));
+ mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(mUserLocation)));
// center view directly
mMarkerScreenMatrix.reset();
- mMarkerScreenMatrix.setTranslate(
- getMeasuredWidth() / 2,
- getMeasuredHeight() / 2);
+ mMarkerScreenPoint = getMarkerScreenPoint();
+ mMarkerScreenMatrix.setTranslate(mMarkerScreenPoint.x, mMarkerScreenPoint.y);
}
}
- @MyLocationTracking.Mode
- public int getMyLocationTrackingMode() {
- return mMyLocationTrackingMode;
- }
-
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
@@ -278,7 +273,7 @@ public final class UserLocationView extends View {
// compute new marker position
// TODO add JNI method that takes existing pointf
if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
- mMarkerScreenPoint = mMapView.toScreenLocation(mMarkerCoordinate);
+ mMarkerScreenPoint = getMarkerScreenPoint();
mMarkerScreenMatrix.reset();
mMarkerScreenMatrix.setTranslate(
mMarkerScreenPoint.x,
@@ -289,11 +284,11 @@ public final class UserLocationView extends View {
if (mShowDirection) {
bearing = mMyBearingTrackingMode == MyBearingTracking.COMPASS ? mBearingChangeListener.getCompassBearing() : mUserLocation.getBearing();
} else {
- bearing = (float) mMapView.getBearing();
+ bearing = mMapboxMap.getCameraPosition().bearing;
}
if (mCurrentMapViewCoordinate == null) {
- mCurrentMapViewCoordinate = mMapView.getMapboxMap().getCameraPosition().target;
+ mCurrentMapViewCoordinate = mMapboxMap.getCameraPosition().target;
}
// only update if there is an actual change
@@ -302,11 +297,10 @@ public final class UserLocationView extends View {
.target(mMarkerCoordinate)
.bearing(bearing)
.build();
- mMapView.getMapboxMap().animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 300, null);
+ mMapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 300, null);
mMarkerScreenMatrix.reset();
- mMarkerScreenMatrix.setTranslate(
- getMeasuredWidth() / 2,
- getMeasuredHeight() / 2);
+ mMarkerScreenPoint = getMarkerScreenPoint();
+ mMarkerScreenMatrix.setTranslate(mMarkerScreenPoint.x, mMarkerScreenPoint.y);
// set values for next check for actual change
mCurrentMapViewCoordinate = mMarkerCoordinate;
@@ -317,10 +311,10 @@ public final class UserLocationView extends View {
// rotate so arrow in points to bearing
if (mShowDirection) {
if (mMyBearingTrackingMode == MyBearingTracking.COMPASS && mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
- mMarkerScreenMatrix.preRotate(mCompassMarkerDirection + (float) mMapView.getDirection());
+ mMarkerScreenMatrix.preRotate(mCompassMarkerDirection + mMapboxMap.getCameraPosition().bearing);
} else if (mMyBearingTrackingMode == MyBearingTracking.GPS) {
if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
- mMarkerScreenMatrix.preRotate(mGpsMarkerDirection + (float) mMapView.getDirection());
+ mMarkerScreenMatrix.preRotate(mGpsMarkerDirection + mMapboxMap.getCameraPosition().bearing);
} else {
mMarkerScreenMatrix.preRotate(mGpsMarkerDirection);
}
@@ -331,7 +325,7 @@ public final class UserLocationView extends View {
if (mShowAccuracy && !mStaleMarker) {
mAccuracyPath.reset();
mAccuracyPath.addCircle(0.0f, 0.0f,
- (float) (mMarkerAccuracy / mMapView.getMetersPerPixelAtLatitude(
+ (float) (mMarkerAccuracy / mMapboxMap.getProjection().getMetersPerPixelAtLatitude(
mMarkerCoordinate.getLatitude())),
Path.Direction.CW);
@@ -371,11 +365,11 @@ public final class UserLocationView extends View {
*/
private void toggleGps(boolean enableGps) {
- LocationServices locationServices = LocationServices.getLocationServices(getContext());
+ LocationService locationService = LocationService.getInstance(getContext());
if (enableGps) {
// Set an initial location if one available
- Location lastLocation = locationServices.getLastLocation();
+ Location lastLocation = locationService.getLastLocation();
if (lastLocation != null) {
setLocation(lastLocation);
}
@@ -385,16 +379,16 @@ public final class UserLocationView extends View {
}
// Register for Location Updates
- locationServices.addLocationListener(mUserLocationListener);
+ locationService.addLocationListener(mUserLocationListener);
} else {
// Disable location and user dot
setLocation(null);
// Deregister for Location Updates
- locationServices.removeLocationListener(mUserLocationListener);
+ locationService.removeLocationListener(mUserLocationListener);
}
- locationServices.toggleGPS(enableGps);
+ locationService.toggleGPS(enableGps);
}
public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
@@ -415,11 +409,6 @@ public final class UserLocationView extends View {
update();
}
- @MyBearingTracking.Mode
- public int getMyBearingTrackingMode() {
- return mMyBearingTrackingMode;
- }
-
private class MyBearingListener implements SensorEventListener {
private SensorManager mSensorManager;
@@ -483,9 +472,8 @@ public final class UserLocationView extends View {
SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
SensorManager.getOrientation(mR, mOrientation);
float azimuthInRadians = mOrientation[0];
- float azimuthInDegress = (float) (Math.toDegrees(azimuthInRadians) + 360) % 360;
- mCompassBearing = azimuthInDegress;
+ mCompassBearing = (float) (Math.toDegrees(azimuthInRadians) + 360) % 360;
if (mCompassBearing < 0) {
// only allow positive degrees
mCompassBearing += 360;
@@ -515,7 +503,7 @@ public final class UserLocationView extends View {
/**
- * Callback method for receiving location updates from LocationServices.
+ * Callback method for receiving location updates from LocationService.
*
* @param location The new Location data
*/
@@ -670,7 +658,7 @@ public final class UserLocationView extends View {
}
void updateOnNextFrame() {
- mMapView.update();
+ mMapboxMap.invalidate();
}
/**
@@ -770,4 +758,14 @@ public final class UserLocationView extends View {
return mPaused;
}
+ public PointF getMarkerScreenPoint() {
+ if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
+ mMarkerScreenPoint = mProjection.toScreenLocation(mMarkerCoordinate);
+ } else {
+ int[] contentPadding = mMapboxMap.getPadding();
+ mMarkerScreenPoint = new PointF(((getMeasuredWidth() + contentPadding[0] - contentPadding[2]) / 2)
+ , ((getMeasuredHeight() - contentPadding[3] + contentPadding[1]) / 2));
+ }
+ return mMarkerScreenPoint;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
new file mode 100644
index 0000000000..87dfb7ec3c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
@@ -0,0 +1,59 @@
+package com.mapbox.mapboxsdk.telemetry;
+
+import java.io.Serializable;
+
+public class MapboxEvent implements Serializable {
+ public static final int VERSION_NUMBER = 1;
+ public static final String MGLMapboxEventsUserAgent = "MapboxEventsAndroid/1.1";
+ public static final String MAPBOX_EVENTS_BASE_URL = "https://api.mapbox.com";
+
+ // Event Types
+ public static final String TYPE_TURNSTILE = "appUserTurnstile";
+ public static final String TYPE_MAP_LOAD = "map.load";
+ public static final String TYPE_MAP_CLICK = "map.click";
+ public static final String TYPE_MAP_DRAGEND = "map.dragend";
+ public static final String TYPE_LOCATION = "location";
+ public static final String TYPE_VISIT = "visit";
+
+ // Event Keys
+ public static final String KEY_LATITUDE = "lat";
+ public static final String KEY_LONGITUDE = "lng";
+ public static final String KEY_SPEED = "speed";
+ public static final String KEY_COURSE = "course";
+ public static final String KEY_ALTITUDE = "altitude";
+ public static final String KEY_HORIZONTAL_ACCURACY = "horizontalAccuracy";
+ public static final String KEY_ZOOM = "zoom";
+
+ public static final String KEY_PUSH_ENABLED = "enabled.push";
+ public static final String KEY_EMAIL_ENABLED = "enabled.email";
+ public static final String KEY_GESTURE_ID = "gesture";
+ public static final String KEY_ARRIVAL_DATE = "arrivalDate";
+ public static final String KEY_DEPARTURE_DATE = "departureDate";
+
+ public static final String GESTURE_SINGLETAP = "SingleTap";
+ public static final String GESTURE_DOUBLETAP = "DoubleTap";
+ public static final String GESTURE_TWO_FINGER_SINGLETAP = "TwoFingerTap";
+ public static final String GESTURE_QUICK_ZOOM = "QuickZoom";
+ public static final String GESTURE_PAN_START = "Pan";
+ public static final String GESTURE_PINCH_START = "Pinch";
+ public static final String GESTURE_ROTATION_START = "Rotation";
+ public static final String GESTURE_PITCH_START = "Pitch";
+
+ // Event Attributes
+ public static final String ATTRIBUTE_EVENT = "event";
+ public static final String ATTRIBUTE_SESSION_ID = "sessionId";
+ public static final String ATTRIBUTE_VERSION = "version";
+ public static final String ATTRIBUTE_CREATED = "created";
+ public static final String ATTRIBUTE_VENDOR_ID = "vendorId";
+ public static final String ATTRIBUTE_APP_BUNDLE_ID = "appBundleId";
+ public static final String ATTRIBUTE_MODEL = "model";
+ public static final String ATTRIBUTE_OPERATING_SYSTEM= "operatingSystem";
+ public static final String ATTRIBUTE_ORIENTATION = "orientation";
+ public static final String ATTRIBUTE_BATTERY_LEVEL = "batteryLevel";
+ public static final String ATTRIBUTE_APPLICATION_STATE = "applicationState";
+ public static final String ATTRIBUTE_RESOLUTION = "resolution";
+ public static final String ATTRIBUTE_ACCESSIBILITY_FONT_SCALE = "accessibilityFontScale";
+ public static final String ATTRIBUTE_CARRIER = "carrier";
+ public static final String ATTRIBUTE_CELLULAR_NETWORK_TYPE = "cellularNetworkType";
+ public static final String ATTRIBUTE_WIFI = "wifi";
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
new file mode 100644
index 0000000000..a62fdc98c5
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
@@ -0,0 +1,532 @@
+package com.mapbox.mapboxsdk.telemetry;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.location.Location;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.WindowManager;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.location.LocationService;
+import com.mapbox.mapboxsdk.utils.ApiAccess;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Locale;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.UUID;
+import java.util.Vector;
+import okhttp3.CertificatePinner;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+public class MapboxEventManager {
+
+ private static final String TAG = "MapboxEventManager";
+
+ private static MapboxEventManager mapboxEventManager = null;
+
+ private boolean telemetryEnabled;
+
+ private final Vector<Hashtable<String, Object>> events = new Vector<>();
+ private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+ private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
+
+ private Context context = null;
+ private String accessToken = null;
+ private String eventsURL = MapboxEvent.MAPBOX_EVENTS_BASE_URL;
+
+ private String userAgent = MapboxEvent.MGLMapboxEventsUserAgent;
+
+ private Intent batteryStatus = null;
+
+ private DisplayMetrics displayMetrics = null;
+
+ private String mapboxVendorId = null;
+
+ private String mapboxSessionId = null;
+ private long mapboxSessionIdLastSet = 0;
+ private static long hourInMillis = 1000 * 60 * 60;
+ private static long flushDelayInitialInMillis = 1000 * 10; // 10 Seconds
+ private static long flushDelayInMillis = 1000 * 60 * 2; // 2 Minutes
+ private static final int SESSION_ID_ROTATION_HOURS = 24;
+
+ private static MessageDigest messageDigest = null;
+
+ private Timer timer = null;
+
+ private MapboxEventManager(@NonNull Context context) {
+ super();
+ this.accessToken = ApiAccess.getToken(context);
+ this.context = context;
+
+ // Setup Message Digest
+ try {
+ messageDigest = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ Log.w(TAG, "Error getting Encryption Algorithm: " + e);
+ }
+
+ SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE);
+
+ // Determine if Telemetry Should Be Enabled
+ setTelemetryEnabled(prefs.getBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, true));
+
+ // Load / Create Vendor Id
+ if (prefs.contains(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID)) {
+ mapboxVendorId = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, "Default Value");
+ Log.d(TAG, "Found Vendor Id = " + mapboxVendorId);
+ } else {
+ String vendorId = UUID.randomUUID().toString();
+ vendorId = encodeString(vendorId);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, vendorId);
+ editor.apply();
+ editor.commit();
+ Log.d(TAG, "Set New Vendor Id = " + vendorId);
+ }
+
+ // Create Initial Session Id
+ rotateSessionId();
+
+ // Get DisplayMetrics Setup
+ displayMetrics = new DisplayMetrics();
+ ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
+
+ // Check for Staging Server Information
+ try {
+ ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
+ String stagingURL = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_SERVER);
+ String stagingAccessToken = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_ACCESS_TOKEN);
+ String appName = context.getPackageManager().getApplicationLabel(appInfo).toString();
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ String versionName = packageInfo.versionName;
+ int versionCode = packageInfo.versionCode;
+
+ if (!TextUtils.isEmpty(stagingURL)) {
+ eventsURL = stagingURL;
+ }
+
+ if (!TextUtils.isEmpty(stagingAccessToken)) {
+ this.accessToken = stagingAccessToken;
+ }
+
+ // Build User Agent
+ if (!TextUtils.isEmpty(appName) && !TextUtils.isEmpty(versionName)) {
+ userAgent = appName + "/" + versionName + "/" + versionCode + " " + userAgent;
+ }
+
+ } catch (Exception e) {
+ Log.e(TAG, "Error Trying to load Staging Credentials: " + e.toString());
+ }
+
+ // Register for battery updates
+ IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+ batteryStatus = context.registerReceiver(null, iFilter);
+ }
+
+ /**
+ * Primary Access method using Singleton pattern
+ * @param context Application Context
+ * @return MapboxEventManager
+ */
+ public static MapboxEventManager getMapboxEventManager(@NonNull Context context) {
+ if (mapboxEventManager == null) {
+ mapboxEventManager = new MapboxEventManager(context.getApplicationContext());
+ }
+ return mapboxEventManager;
+ }
+
+ public boolean isTelemetryEnabled() {
+ return telemetryEnabled;
+ }
+
+ /**
+ * Enables / Disables Telemetry
+ * @param telemetryEnabled True to start telemetry, false to stop it
+ */
+ public void setTelemetryEnabled(boolean telemetryEnabled) {
+ if (this.telemetryEnabled == telemetryEnabled) {
+ Log.i(TAG, "no need to start / stop telemetry as it's already in that state.");
+ return;
+ }
+
+ if (telemetryEnabled) {
+ Log.i(TAG, "Starting Telemetry Up!");
+ // Start It Up
+ context.startService(new Intent(context, TelemetryService.class));
+
+ // Make sure Ambient Mode is started at a minimum
+ if (LocationService.getInstance(context).isGPSEnabled()) {
+ LocationService.getInstance(context).toggleGPS(false);
+ }
+
+ // Manage Timer Flush
+ timer = new Timer();
+ timer.schedule(new FlushEventsTimerTask(), flushDelayInitialInMillis, flushDelayInMillis);
+ } else {
+ Log.i(TAG, "Shutting Telemetry Down");
+ // Shut It Down
+ events.removeAllElements();
+ context.stopService(new Intent(context, TelemetryService.class));
+
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ }
+
+ // Persist
+ this.telemetryEnabled = telemetryEnabled;
+ SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, telemetryEnabled);
+ editor.apply();
+ editor.commit();
+ }
+
+ /**
+ * Adds a Location Event to the system for processing
+ * @param location Location event
+ */
+ public void addLocationEvent(Location location) {
+ // Add Location even to queue
+ Hashtable<String, Object> event = new Hashtable<>();
+ event.put(MapboxEvent.KEY_LATITUDE, location.getLatitude());
+ event.put(MapboxEvent.KEY_LONGITUDE, location.getLongitude());
+ event.put(MapboxEvent.KEY_SPEED, location.getSpeed());
+ event.put(MapboxEvent.KEY_COURSE, location.getBearing());
+ event.put(MapboxEvent.KEY_ALTITUDE, location.getAltitude());
+ event.put(MapboxEvent.KEY_HORIZONTAL_ACCURACY, location.getAccuracy());
+ event.put(MapboxEvent.ATTRIBUTE_CREATED, dateFormat.format(new Date()));
+ event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_LOCATION);
+
+ events.add(event);
+
+ rotateSessionId();
+ }
+
+ /**
+ * Push Interactive Events to the system for processing
+ * @param eventWithAttributes Event with attributes
+ */
+ public void pushEvent(Hashtable<String, Object> eventWithAttributes) {
+
+ if (eventWithAttributes == null) {
+ return;
+ }
+
+ String eventType = (String)eventWithAttributes.get(MapboxEvent.ATTRIBUTE_EVENT);
+ if (!TextUtils.isEmpty(eventType) && eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_LOAD)) {
+ pushTurnstileEvent();
+ }
+
+ events.add(eventWithAttributes);
+ }
+
+ /**
+ * Pushes turnstile event for internal billing purposes
+ */
+ private void pushTurnstileEvent() {
+
+ Hashtable<String, Object> event = new Hashtable<>();
+ event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_TURNSTILE);
+ event.put(MapboxEvent.ATTRIBUTE_CREATED, dateFormat.format(new Date()));
+/*
+ // Already set by processing
+ event.put(MapboxEvent.ATTRIBUTE_APP_BUNDLE_ID, context.getPackageName());
+ event.put(MapboxEvent.ATTRIBUTE_VERSION, MapboxEvent.VERSION_NUMBER);
+ event.put(MapboxEvent.ATTRIBUTE_VENDOR_ID, mapboxVendorId);
+*/
+
+ events.add(event);
+
+ // Send to Server Immediately
+ new FlushTheEventsTask().execute();
+ Log.d(TAG, "turnstile event pushed.");
+ }
+
+ /**
+ * SHA-1 Encoding for strings
+ * @param string String to encode
+ * @return String encoded if no error, original string if error
+ */
+ private String encodeString(String string) {
+ try {
+ if (messageDigest != null) {
+ messageDigest.reset();
+ messageDigest.update(string.getBytes("UTF-8"));
+ byte[] bytes = messageDigest.digest();
+
+ // Get the Hex version of the digest
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append( String.format("%02X", b) );
+ }
+ String hex = sb.toString();
+ Log.d(TAG, "original = " + string + "; hex = " + hex);
+
+ return hex;
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Error encoding string, will return in original form." + e);
+ }
+ return string;
+ }
+
+ /**
+ * Changes Session Id based on time boundary
+ */
+ private void rotateSessionId() {
+ long now = System.currentTimeMillis();
+ if (now - mapboxSessionIdLastSet > (SESSION_ID_ROTATION_HOURS * hourInMillis)) {
+ mapboxSessionId = UUID.randomUUID().toString();
+ mapboxSessionIdLastSet = System.currentTimeMillis();
+ }
+ }
+
+ private String getOrientation() {
+ switch (context.getResources().getConfiguration().orientation) {
+ case Configuration.ORIENTATION_LANDSCAPE:
+ return "Landscape";
+ case Configuration.ORIENTATION_PORTRAIT:
+ return "Portrait";
+ default:
+ return "Undefined";
+ }
+ }
+
+ private int getBatteryLevel() {
+ int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+ int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+
+ return Math.round((level / (float)scale) * 100);
+ }
+
+ private String getApplicationState() {
+
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
+ if (appProcesses == null) {
+ return "Unknown";
+ }
+ final String packageName = context.getPackageName();
+ for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
+ if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
+ return "Foreground";
+ }
+ }
+ return "Background";
+ }
+
+ private float getAccesibilityFontScaleSize() {
+ // Values
+ // Small = 0.85
+ // Normal = 1.0
+ // Large = 1.15
+ // Huge = 1.3
+
+ return context.getResources().getConfiguration().fontScale;
+ }
+
+ private String getCellularCarrier() {
+ TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
+ String carrierName = manager.getNetworkOperatorName();
+ if (TextUtils.isEmpty(carrierName)) {
+ carrierName = "None";
+ }
+ return carrierName;
+ }
+
+ private String getCellularNetworkType () {
+ TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
+ switch (manager.getNetworkType()) {
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ return "1xRTT";
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ return "CDMA";
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ return "EDGE";
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
+ return "EHRPD";
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ return "EVDO_0";
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ return "EVDO_A";
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ return "EVDO_B";
+ case TelephonyManager.NETWORK_TYPE_GPRS:
+ return "GPRS";
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ return "HSDPA";
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ return "HSPA";
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ return "HSPAP";
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ return "HSUPA";
+ case TelephonyManager.NETWORK_TYPE_IDEN:
+ return "IDEN";
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ return "LTE";
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ return "UMTS";
+ case TelephonyManager.NETWORK_TYPE_UNKNOWN:
+ return "Unknown";
+ default:
+ return "Default Unknown";
+ }
+ }
+
+
+ public String getConnectedToWifi() {
+
+ String status = "No";
+ WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ if (wifiMgr.isWifiEnabled()) {
+ try {
+ WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
+ if( wifiInfo.getNetworkId() != -1 ){
+ status = "Yes";
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Error getting Wifi Connection Status: " + e);
+ status = "Unknown";
+ }
+ }
+
+ return status;
+ }
+
+ /**
+ * Task responsible for converting stored events and sending them to the server
+ */
+ private class FlushTheEventsTask extends AsyncTask<Void, Void, Void> {
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+
+ if (events.size() < 1) {
+ Log.i(TAG, "No events in the queue to send so returning.");
+ return null;
+ }
+
+ // Check for NetworkConnectivity
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = cm.getActiveNetworkInfo();
+ if (networkInfo == null || !networkInfo.isConnected()) {
+ Log.w(TAG, "Not connected to network, so returning without attempting to send events");
+ return null;
+ }
+
+ try {
+ // Send data
+ // =========
+ JSONArray jsonArray = new JSONArray();
+
+ for (Hashtable<String, Object> evt : events) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MapboxEvent.KEY_LATITUDE, evt.get(MapboxEvent.KEY_LATITUDE));
+ jsonObject.put(MapboxEvent.KEY_LONGITUDE, evt.get(MapboxEvent.KEY_LONGITUDE));
+ jsonObject.put(MapboxEvent.KEY_SPEED, evt.get(MapboxEvent.KEY_SPEED));
+ jsonObject.put(MapboxEvent.KEY_COURSE, evt.get(MapboxEvent.KEY_COURSE));
+ jsonObject.put(MapboxEvent.KEY_ALTITUDE, evt.get(MapboxEvent.KEY_ALTITUDE));
+ jsonObject.put(MapboxEvent.KEY_HORIZONTAL_ACCURACY, evt.get(MapboxEvent.KEY_HORIZONTAL_ACCURACY));
+ jsonObject.put(MapboxEvent.KEY_ZOOM, evt.get(MapboxEvent.KEY_ZOOM));
+
+ // Basic Event Meta Data
+ jsonObject.put(MapboxEvent.ATTRIBUTE_EVENT, evt.get(MapboxEvent.ATTRIBUTE_EVENT));
+ jsonObject.put(MapboxEvent.ATTRIBUTE_CREATED, evt.get(MapboxEvent.ATTRIBUTE_CREATED));
+ jsonObject.put(MapboxEvent.ATTRIBUTE_SESSION_ID, encodeString(mapboxSessionId));
+ jsonObject.put(MapboxEvent.ATTRIBUTE_VERSION, MapboxEvent.VERSION_NUMBER);
+ jsonObject.put(MapboxEvent.ATTRIBUTE_VENDOR_ID, mapboxVendorId);
+ jsonObject.put(MapboxEvent.ATTRIBUTE_APP_BUNDLE_ID, context.getPackageName());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_MODEL, Build.MODEL);
+ jsonObject.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, Build.VERSION.RELEASE);
+ jsonObject.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, getApplicationState());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_RESOLUTION, displayMetrics.density);
+ jsonObject.put(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, getAccesibilityFontScaleSize());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
+ jsonObject.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
+
+ jsonArray.put(jsonObject);
+ }
+
+ // Based on http://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
+ CertificatePinner certificatePinner = new CertificatePinner.Builder()
+ .add("cloudfront-staging.tilestream.net", "sha1/KcdiTca54HxWTV8VuAd67x8I=")
+ .add("cloudfront-staging.tilestream.net", "sha1//KDE76PP0DQBDcTnMFBv+efp4eg=")
+ .add("api.mapbox.com", "sha1/Uv71ooi32pyba+oLD7egnXm7/GQ=")
+ .add("api.mapbox.com", "sha1/hOP0d37/ZTSGgCSseE3DIZ1uSg0=")
+ .build();
+
+ OkHttpClient client = new OkHttpClient.Builder().certificatePinner(certificatePinner).build();
+ RequestBody body = RequestBody.create(JSON, jsonArray.toString());
+
+ String url = eventsURL + "/events/v1?access_token=" + accessToken;
+ Log.d(TAG, "url = " + url);
+
+ Request request = new Request.Builder()
+ .url(url)
+ .header("User-Agent", userAgent)
+ .post(body)
+ .build();
+ Response response = client.newCall(request).execute();
+ Log.d(TAG, "Response Code from Mapbox Events Server: " + response.code() + " for " + events.size() + " events sent in.");
+
+ // Reset Events
+ // ============
+ events.removeAllElements();
+ } catch (Exception e) {
+ Log.e(TAG, "FlushTheEventsTask borked: " + e);
+ }
+
+ return null;
+ }
+
+ }
+
+
+ /**
+ * TimerTask responsible for sending event data to server
+ */
+ private class FlushEventsTimerTask extends TimerTask {
+ /**
+ * The task to run should be specified in the implementation of the {@code run()}
+ * method.
+ */
+ @Override
+ public void run() {
+ new FlushTheEventsTask().execute();
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
new file mode 100644
index 0000000000..088d41be54
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
@@ -0,0 +1,71 @@
+package com.mapbox.mapboxsdk.telemetry;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.location.Location;
+import android.location.LocationManager;
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.os.Handler;
+import android.util.Log;
+
+public class TelemetryLocationReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "TelemLocationReceiver";
+
+ public static final String INTENT_STRING = "com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver";
+
+ /**
+ * Default Constructor
+ */
+ public TelemetryLocationReceiver() {
+ super();
+ }
+
+ /**
+ * This method is called when the BroadcastReceiver is receiving an Intent
+ * broadcast. During this time you can use the other methods on
+ * BroadcastReceiver to view/modify the current result values. This method
+ * is always called within the main thread of its process, unless you
+ * explicitly asked for it to be scheduled on a different thread using
+ * {@link Context#registerReceiver(BroadcastReceiver,
+ * IntentFilter, String, Handler)}. When it runs on the main
+ * thread you should
+ * never perform long-running operations in it (there is a timeout of
+ * 10 seconds that the system allows before considering the receiver to
+ * be blocked and a candidate to be killed). You cannot launch a popup dialog
+ * in your implementation of onReceive().
+ * <p/>
+ * <p><b>If this BroadcastReceiver was launched through a &lt;receiver&gt; tag,
+ * then the object is no longer alive after returning from this
+ * function.</b> This means you should not perform any operations that
+ * return a result to you asynchronously -- in particular, for interacting
+ * with services, you should use
+ * {@link Context#startService(Intent)} instead of
+ * {@link Context#bindService(Intent, ServiceConnection, int)}. If you wish
+ * to interact with a service that is already running, you can use
+ * {@link #peekService}.
+ * <p/>
+ * <p>The Intent filters used in {@link Context#registerReceiver}
+ * and in application manifests are <em>not</em> guaranteed to be exclusive. They
+ * are hints to the operating system about how to find suitable recipients. It is
+ * possible for senders to force delivery to specific recipients, bypassing filter
+ * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()}
+ * implementations should respond only to known actions, ignoring any unexpected
+ * Intents that they may receive.
+ *
+ * @param context The Context in which the receiver is running.
+ * @param intent The Intent being received.
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Location location = (Location)intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);
+ if (location != null) {
+ Log.d(TAG, "location received = " + location);
+ MapboxEventManager.getMapboxEventManager(context).addLocationEvent(location);
+ } else {
+ Log.d(TAG, "location NOT received");
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
new file mode 100644
index 0000000000..56006dadf6
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
@@ -0,0 +1,145 @@
+package com.mapbox.mapboxsdk.telemetry;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+public class TelemetryService extends Service {
+
+ private static final String TAG = "TelemetryService";
+
+ private TelemetryLocationReceiver telemetryLocationReceiver = null;
+ private PowerManager.WakeLock telemetryWakeLock;
+
+ /**
+ * Return the communication channel to the service. May return null if
+ * clients can not bind to the service. The returned
+ * {@link IBinder} is usually for a complex interface
+ * that has been <a href="{@docRoot}guide/components/aidl.html">described using
+ * aidl</a>.
+ * <p/>
+ * <p><em>Note that unlike other application components, calls on to the
+ * IBinder interface returned here may not happen on the main thread
+ * of the process</em>. More information about the main thread can be found in
+ * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
+ * Threads</a>.</p>
+ *
+ * @param intent The Intent that was used to bind to this service,
+ * as given to {@link Context#bindService
+ * Context.bindService}. Note that any extras that were included with
+ * the Intent at that point will <em>not</em> be seen here.
+ * @return Return an IBinder through which clients can call on to the
+ * service.
+ */
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+
+ /**
+ * Called by the system when the service is first created. Do not call this method directly.
+ */
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Log.i(TAG, "onCreate() called");
+
+ // Enable Location Listening for lifecycle of app
+ IntentFilter filter = new IntentFilter(TelemetryLocationReceiver.INTENT_STRING);
+ telemetryLocationReceiver = new TelemetryLocationReceiver();
+ registerReceiver(telemetryLocationReceiver, filter);
+ }
+
+ /**
+ * Called by the system to notify a Service that it is no longer used and is being removed. The
+ * service should clean up any resources it holds (threads, registered
+ * receivers, etc) at this point. Upon return, there will be no more calls
+ * in to this Service object and it is effectively dead. Do not call this method directly.
+ */
+ @Override
+ public void onDestroy() {
+ shutdownTelemetry();
+ super.onDestroy();
+ }
+
+ /**
+ * This is called if the service is currently running and the user has
+ * removed a task that comes from the service's application. If you have
+ * set {@link ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK}
+ * then you will not receive this callback; instead, the service will simply
+ * be stopped.
+ *
+ * @param rootIntent The original root Intent that was used to launch
+ * the task that is being removed.
+ */
+ @Override
+ public void onTaskRemoved(Intent rootIntent) {
+ shutdownTelemetry();
+ super.onTaskRemoved(rootIntent);
+ }
+
+ /**
+ * Called by the system every time a client explicitly starts the service by calling
+ * {@link Context#startService}, providing the arguments it supplied and a
+ * unique integer token representing the start request. Do not call this method directly.
+ * <p/>
+ * <p>For backwards compatibility, the default implementation calls
+ * {@link #onStart} and returns either {@link #START_STICKY}
+ * or {@link #START_STICKY_COMPATIBILITY}.
+ * <p/>
+ * <p>If you need your application to run on platform versions prior to API
+ * level 5, you can use the following model to handle the older {@link #onStart}
+ * callback in that case. The <code>handleCommand</code> method is implemented by
+ * you as appropriate:
+ * <p/>
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+ * start_compatibility}
+ * <p/>
+ * <p class="caution">Note that the system calls this on your
+ * service's main thread. A service's main thread is the same
+ * thread where UI operations take place for Activities running in the
+ * same process. You should always avoid stalling the main
+ * thread's event loop. When doing long-running operations,
+ * network calls, or heavy disk I/O, you should kick off a new
+ * thread, or use {@link AsyncTask}.</p>
+ *
+ * @param intent The Intent supplied to {@link Context#startService},
+ * as given. This may be null if the service is being restarted after
+ * its process has gone away, and it had previously returned anything
+ * except {@link #START_STICKY_COMPATIBILITY}.
+ * @param flags Additional data about this start request. Currently either
+ * 0, {@link #START_FLAG_REDELIVERY}, or {@link #START_FLAG_RETRY}.
+ * @param startId A unique integer representing this specific request to
+ * start. Use with {@link #stopSelfResult(int)}.
+ * @return The return value indicates what semantics the system should
+ * use for the service's current started state. It may be one of the
+ * constants associated with the {@link #START_CONTINUATION_MASK} bits.
+ * @see #stopSelfResult(int)
+ */
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+
+ Log.i(TAG, "onStartCommand() called");
+
+ // Start WakeLock to keep Location Data working when device sleeps
+ PowerManager mgr = (PowerManager)getSystemService(Context.POWER_SERVICE);
+ telemetryWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TelemetryWakeLock");
+ telemetryWakeLock.acquire();
+
+ return START_NOT_STICKY;
+ }
+
+ private void shutdownTelemetry() {
+ unregisterReceiver(telemetryLocationReceiver);
+ telemetryWakeLock.release();
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java
new file mode 100644
index 0000000000..d6cb1ca852
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * This package contains the classes that manage the SDK's Telemetry services.
+ */
+package com.mapbox.mapboxsdk.telemetry;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ApiAccess.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ApiAccess.java
index 137d0730c3..4f968c3a13 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ApiAccess.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ApiAccess.java
@@ -37,7 +37,7 @@ public final class ApiAccess {
return token;
} catch (Exception e) {
// use fallback on string resource, used for development
- int tokenResId = context.getResources().getIdentifier("access_token", "string", context.getPackageName());
+ int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
return tokenResId != 0 ? context.getString(tokenResId) : null;
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
index 777d879d48..be0038e8b8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
@@ -3,12 +3,12 @@
<!--Add references to exposed resources-->
<public name="AttributionAlertDialogStyle" type="style" />
- <public name="style_mapbox_streets" type="string" />
- <public name="style_emerald" type="string" />
- <public name="style_light" type="string" />
- <public name="style_dark" type="string" />
- <public name="style_satellite" type="string" />
- <public name="style_satellite_streets" type="string" />
+ <public name="mapbox_style_mapbox_streets" type="string" />
+ <public name="mapbox_style_emerald" type="string" />
+ <public name="mapbox_style_light" type="string" />
+ <public name="mapbox_style_dark" type="string" />
+ <public name="mapbox_style_satellite" type="string" />
+ <public name="mapbox_style_satellite_streets" type="string" />
<public name="center_longitude" type="attr" />
<public name="center_latitude" type="attr" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_telemetry_view.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_telemetry_view.xml
new file mode 100644
index 0000000000..04c47af90d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_telemetry_view.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ >
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/mapbox_attributionTelemetryMessage"
+ android:gravity="center_horizontal"/>
+
+ <ListView
+ android:id="@+id/telemetryOptionsList"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+
+</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml
index 3e36cbf91a..a4fcc80681 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml
@@ -18,7 +18,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:maxEms="17"
- android:text="@string/infoWindowTitle"
+ android:text="@string/mapbox_infoWindowTitle"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold" />
@@ -31,7 +31,7 @@
android:layout_marginTop="2dp"
android:lineSpacingExtra="1dp"
android:maxEms="17"
- android:text="@string/infoWindowDescription"
+ android:text="@string/mapbox_infoWindowDescription"
android:textColor="@color/gray"
android:textSize="14sp" />
@@ -40,7 +40,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxEms="17"
- android:text="@string/infoWindowAddress"
+ android:text="@string/mapbox_infoWindowAddress"
android:textColor="@color/black"
android:textSize="12sp"
android:visibility="gone" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
index d62fd9cfba..288fb441ad 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <com.mapbox.mapboxsdk.maps.CompassView
+ <com.mapbox.mapboxsdk.maps.widgets.CompassView
android:id="@+id/compassView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
@@ -15,7 +15,7 @@
android:id="@+id/logoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:contentDescription="@string/mapboxIconContentDescription"
+ android:contentDescription="@string/mapbox_mapboxIconContentDescription"
android:src="@drawable/attribution_logo" />
<ImageView
@@ -24,12 +24,12 @@
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:clickable="true"
- android:contentDescription="@string/attributionsIconContentDescription"
+ android:contentDescription="@string/mapbox_attributionsIconContentDescription"
android:padding="7dp"
android:src="@drawable/ic_info_outline_24dp_selector"
android:background="@drawable/bg_default_selector"/>
- <com.mapbox.mapboxsdk.maps.UserLocationView
+ <com.mapbox.mapboxsdk.maps.widgets.UserLocationView
android:id="@+id/userLocationView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml
index 2c1fdf8d13..d5d26d09d2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml
@@ -4,11 +4,23 @@
<item>&#169; Mapbox</item>
<item>&#169; OpenStreetMap</item>
<item>Improve this map</item>
+ <item>Telemetry Settings</item>
+ </array>
+ <array name="attribution_telemetry_options">
+ <item>Tell Me More</item>
+ <item>Don\'t Participate</item>
+ <item>Participate</item>
+ </array>
+ <array name="attribution_telemetry_options_already_participating">
+ <item>Tell Me More</item>
+ <item>Stop Participating</item>
+ <item>Keep Participating</item>
</array>
<!-- If editing this array update MapView.ATTRIBUTION_INDEX_IMPROVE_THIS_MAP -->
<array name="attribution_links" formatted="false" translatable="false">
<item>https://www.mapbox.com/about/maps/</item>
<item>http://www.openstreetmap.org/about/</item>
<item>https://www.mapbox.com/map-feedback/#/%1$f/%2$f/%3$d</item>
+ <item>https://www.mapbox.com/telemetry/</item>
</array>
-</resources> \ No newline at end of file
+</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
index 63547247f3..f516e98dd8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
@@ -4,6 +4,8 @@
<attr name="center_longitude" format="float" />
<attr name="center_latitude" format="float" />
<attr name="zoom" format="float" />
+ <attr name="zoom_max" format="float" />
+ <attr name="zoom_min" format="float" />
<attr name="direction" format="float" />
<attr name="tilt" format="float" />
<attr name="zoom_enabled" format="boolean" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
index fd612d511c..5167ecf936 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
@@ -5,7 +5,8 @@
<dimen name="infowindow_offset">-2dp</dimen>
<dimen name="infowindow_line_width">1.5dp</dimen>
<dimen name="seven_dp">7dp</dimen>
+ <dimen name="eight_dp">8dp</dimen>
<dimen name="ten_dp">10dp</dimen>
<dimen name="sixteen_dp">16dp</dimen>
<dimen name="seventy_six_dp">76dp</dimen>
-</resources> \ No newline at end of file
+</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
index eadcdcc043..f852c305b2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
@@ -1,18 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
- <string name="attributionsIconContentDescription">Attribution icon. Click to show attribution dialog.</string>
- <string name="attributionsDialogTitle">Mapbox Android SDK</string>
- <string name="mapboxIconContentDescription">The Mapbox logo.</string>
- <string name="infoWindowTitle">Title</string>
- <string name="infoWindowDescription">Description</string>
- <string name="infoWindowAddress">Address</string>
+ <string name="mapbox_compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
+ <string name="mapbox_attributionsIconContentDescription">Attribution icon. Click to show attribution dialog.</string>
+ <string name="mapbox_attributionsDialogTitle">Mapbox Android SDK</string>
+ <string name="mapbox_attributionTelemetryTitle">Make Mapbox Maps Better</string>
+ <string name="mapbox_attributionTelemetryMessage">You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data.</string>
+ <string name="mapbox_mapboxIconContentDescription">The Mapbox logo.</string>
+ <string name="mapbox_infoWindowTitle">Title</string>
+ <string name="mapbox_infoWindowDescription">Description</string>
+ <string name="mapbox_infoWindowAddress">Address</string>
<!-- these are public -->
- <string name="style_mapbox_streets">mapbox://styles/mapbox/streets-v8</string>
- <string name="style_emerald">mapbox://styles/mapbox/emerald-v8</string>
- <string name="style_light">mapbox://styles/mapbox/light-v8</string>
- <string name="style_dark">mapbox://styles/mapbox/dark-v8</string>
- <string name="style_satellite">mapbox://styles/mapbox/satellite-v8</string>
- <string name="style_satellite_streets">mapbox://styles/mapbox/satellite-hybrid-v8</string>
+ <string name="mapbox_style_mapbox_streets">mapbox://styles/mapbox/streets-v8</string>
+ <string name="mapbox_style_emerald">mapbox://styles/mapbox/emerald-v8</string>
+ <string name="mapbox_style_light">mapbox://styles/mapbox/light-v8</string>
+ <string name="mapbox_style_dark">mapbox://styles/mapbox/dark-v8</string>
+ <string name="mapbox_style_satellite">mapbox://styles/mapbox/satellite-v8</string>
+ <string name="mapbox_style_satellite_streets">mapbox://styles/mapbox/satellite-hybrid-v8</string>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index 7d18fabe32..76dd07b7d6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -7,7 +7,7 @@ task accessToken {
if (!tokenFile.exists()) {
String tokenFileContents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<resources>\n" +
- " <string name=\"access_token\">" + "$System.env.MAPBOX_ACCESS_TOKEN" + "</string>\n" +
+ " <string name=\"mapbox_access_token\">" + "$System.env.MAPBOX_ACCESS_TOKEN" + "</string>\n" +
"</resources>"
if (tokenFileContents == null) {
@@ -33,8 +33,8 @@ android {
applicationId "com.mapbox.mapboxsdk.testapp"
minSdkVersion 15
targetSdkVersion 23
- versionCode 7
- versionName "3.1.0"
+ versionCode 8
+ versionName "4.0.0"
// Specify AndroidJUnitRunner as the default test instrumentation runner
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
index c6445ac6a4..255a724744 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
+++ b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
@@ -1,8 +1,6 @@
# Mapbox ProGuard configuration is handled in the SDK
-
-keep class android.support.** { *; }
-
--dontwarn retrofit.**
--keep class retrofit.** { *; }
--keepattributes Signature
--keepattributes Exceptions \ No newline at end of file
+-dontwarn com.squareup.**
+-dontwarn com.retrofit.**
+-dontwarn java.lang.**
+-dontwarn org.codehaus.** \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CameraActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CameraActivityTest.java
new file mode 100644
index 0000000000..1f176af879
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CameraActivityTest.java
@@ -0,0 +1,35 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on CameraActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CameraActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<CameraActivity> mActivityRule = new ActivityTestRule<>(CameraActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.cameraMapView);
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivityTest.java
new file mode 100644
index 0000000000..68633547ed
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on CameraActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CoordinateChangeActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<CoordinateChangeActivity> mActivityRule = new ActivityTestRule<>(CoordinateChangeActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DirectionsActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DirectionsActivityTest.java
new file mode 100644
index 0000000000..3ce8d00aa0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DirectionsActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on DirectionsActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DirectionsActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<DirectionsActivity> mActivityRule = new ActivityTestRule<>(DirectionsActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivityTest.java
new file mode 100644
index 0000000000..db014b69ac
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivityTest.java
@@ -0,0 +1,35 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on DoubleMapActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DoubleMapActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<DoubleMapActivity> mActivityRule = new ActivityTestRule<>(DoubleMapActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ checkViewIsDisplayed(R.id.mini_map);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivityTest.java
new file mode 100644
index 0000000000..b6feb8f1be
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivityTest.java
@@ -0,0 +1,33 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on DynamicMarkerChange
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DynamicMarkerChangeActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<DynamicMarkerChangeActivity> mActivityRule = new ActivityTestRule<>(
+ DynamicMarkerChangeActivity.class);
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+
+ @Test
+ public void testFabClick() {
+ ViewUtils.clickView(R.id.fab);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/GeocoderActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/GeocoderActivityTest.java
new file mode 100644
index 0000000000..c1ca7413c2
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/GeocoderActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on GeocoderActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class GeocoderActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<GeocoderActivity> mActivityRule = new ActivityTestRule<>(GeocoderActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/InfoWindowConcurrentActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/InfoWindowConcurrentActivityTest.java
new file mode 100644
index 0000000000..e507c6cd61
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/InfoWindowConcurrentActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on InfoWindowConcurrentActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class InfoWindowConcurrentActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<InfoWindowConcurrentActivity> mActivityRule = new ActivityTestRule<>(InfoWindowConcurrentActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.infoWindowConcurrentMapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/VisibleCoordinateBoundsActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivityTest.java
index ad74ea21c8..057979aeb8 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/VisibleCoordinateBoundsActivityTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivityTest.java
@@ -14,7 +14,7 @@ import org.junit.runner.RunWith;
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
-public class VisibleCoordinateBoundsActivityTest extends BaseTest {
+public class LatLngBoundsActivityTest extends BaseTest {
@Rule
public ActivityTestRule<LatLngBoundsActivity> mActivityRule = new ActivityTestRule<>(
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityScreenTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityScreenTest.java
index bbfa4ec73a..7c56f4c874 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityScreenTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityScreenTest.java
@@ -4,17 +4,18 @@ import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
+import com.mapbox.mapboxsdk.testapp.utils.DrawerUtils;
+import com.mapbox.mapboxsdk.testapp.utils.GestureUtils;
+import com.mapbox.mapboxsdk.testapp.utils.ScreenshotUtil;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.doubleClick;
-import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
/**
* Tests on MainActivity with screenshots
@@ -23,8 +24,6 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText;
@LargeTest
public class MainActivityScreenTest extends BaseTest {
- private final static String HOME_BUTTON_STRING = "Navigate up";
-
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
MainActivity.class);
@@ -41,26 +40,49 @@ public class MainActivityScreenTest extends BaseTest {
checkViewIsDisplayed(R.id.mainMapView);
}
- /*
- * Take a screenshot of Mapbox Streets to monitor #1649
- */
+ @Test
+ public void testStyleEmerald() {
+ DrawerUtils.openDrawer();
+ DrawerUtils.clickItem(R.string.styleEmerald);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ takeNamedScreenshot(mActivity, "testEmeraldStyle");
+ }
@Test
- public void testMapboxStreetsBlackAndWhite() {
- // Click home and switch to Mapbox streets
- onView(withContentDescription(HOME_BUTTON_STRING))
- .perform(click());
- onView(withText(R.string.styleMapboxStreets))
- .perform(click());
+ public void testStyleStreets() {
+ DrawerUtils.openDrawer();
+ DrawerUtils.clickItem(R.string.styleMapboxStreets);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ takeNamedScreenshot(mActivity, "testStreetsStyle");
+ }
- // Zoom in
- onView(withId(R.id.mainMapView))
- .perform(doubleClick());
- onView(withId(R.id.mainMapView))
- .perform(doubleClick());
+ @Test
+ public void testStyleDark() {
+ DrawerUtils.openDrawer();
+ DrawerUtils.clickItem(R.string.styleDark);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ takeNamedScreenshot(mActivity, "testDarkStyle");
+ }
- // Standard screenshot
- takeNamedScreenshot(mActivity, "testMapboxStreetsBlackAndWhite");
+ @Test
+ public void testStyleLight() {
+ DrawerUtils.openDrawer();
+ DrawerUtils.clickItem(R.string.styleLight);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ takeNamedScreenshot(mActivity, "testLightStyle");
+ }
+
+ @Test
+ public void testStyleSatellite() {
+ DrawerUtils.openDrawer();
+ DrawerUtils.clickItem(R.string.styleSatellite);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ GestureUtils.doubleClickGesture(R.id.mainMapView);
+ takeNamedScreenshot(mActivity, "testSatelliteStyle");
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityTest.java
index c545bc118b..a5f3a2e791 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MainActivityTest.java
@@ -129,34 +129,6 @@ public class MainActivityTest extends BaseTest {
.check(matches(isDisplayed()));
}
- @Test
- public void testSwipeLeftMap() {
- onView(withId(R.id.mainMapView))
- .perform(swipeLeft())
- .check(matches(isDisplayed()));
- }
-
- @Test
- public void testSwipeRightMap() {
- onView(withId(R.id.mainMapView))
- .perform(swipeRight())
- .check(matches(isDisplayed()));
- }
-
- @Test
- public void testSwipeDownMap() {
- onView(withId(R.id.mainMapView))
- .perform(swipeDown())
- .check(matches(isDisplayed()));
- }
-
- @Test
- public void testSwipeUpMap() {
- onView(withId(R.id.mainMapView))
- .perform(swipeUp())
- .check(matches(isDisplayed()));
- }
-
/*
* Test the main drawer options
*/
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivityTest.java
new file mode 100644
index 0000000000..8ce8498d64
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on ManualZoomActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ManualZoomActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<ManualZoomActivity> mActivityRule = new ActivityTestRule<>(ManualZoomActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.manualZoomMapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivityTest.java
new file mode 100644
index 0000000000..c252077856
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on MapPaddingActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class MapPaddingActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<MapPaddingActivity> mActivityRule = new ActivityTestRule<>(MapPaddingActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivityTest.java
new file mode 100644
index 0000000000..eaa1584a3f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on MapboxMapActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class MapboxMapActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<MapboxMapActivity> mActivityRule = new ActivityTestRule<>(MapboxMapActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivityTest.java
new file mode 100644
index 0000000000..e93a7675f0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivityTest.java
@@ -0,0 +1,34 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on MaxMinZoomActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class MaxMinZoomActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<MaxMinZoomActivity> mActivityRule = new ActivityTestRule<>(MaxMinZoomActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.manualZoomMapView);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ScrollByActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ScrollByActivityTest.java
new file mode 100644
index 0000000000..05386b089e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/ScrollByActivityTest.java
@@ -0,0 +1,26 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on ScrollByActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class ScrollByActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<ScrollByActivity> mActivityRule = new ActivityTestRule<>(ScrollByActivity.class);
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.mapView);
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivityTest.java
new file mode 100644
index 0000000000..7ae03e0d07
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivityTest.java
@@ -0,0 +1,35 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests on SupportMapFragmentActivity
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SupportMapFragmentActivityTest extends BaseTest {
+
+ @Rule
+ public ActivityTestRule<SupportMapFragmentActivity> mActivityRule = new ActivityTestRule<>(SupportMapFragmentActivity.class);
+
+ private Activity mActivity = null;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ public void testSanity() {
+ checkViewIsDisplayed(R.id.fragment_container);
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java
new file mode 100644
index 0000000000..8d8905fdf4
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java
@@ -0,0 +1,29 @@
+package com.mapbox.mapboxsdk.testapp.utils;
+
+import android.support.annotation.StringRes;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.action.ViewActions;
+import android.support.test.espresso.matcher.ViewMatchers;
+
+import com.mapbox.mapboxsdk.testapp.R;
+
+import org.hamcrest.Matchers;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
+
+public class DrawerUtils {
+
+ private final static String HOME_BUTTON_STRING = "Navigate up";
+
+ public static void openDrawer(){
+ onView(withContentDescription(HOME_BUTTON_STRING)).perform(click());
+ }
+
+ public static void clickItem(@StringRes int txtId){
+ Espresso.onView(Matchers.allOf(ViewMatchers.withId(R.id.design_menu_item_text),
+ ViewMatchers.hasSibling(ViewMatchers.withText(txtId)))).perform(ViewActions.click());
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java
new file mode 100644
index 0000000000..37c18399e4
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java
@@ -0,0 +1,17 @@
+package com.mapbox.mapboxsdk.testapp.utils;
+
+import android.support.annotation.IdRes;
+
+import com.mapbox.mapboxsdk.testapp.R;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.doubleClick;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+public class GestureUtils {
+
+ public static void doubleClickGesture(@IdRes int id){
+ onView(withId(id)).perform(doubleClick());
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java
new file mode 100644
index 0000000000..01ee3e9b9f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java
@@ -0,0 +1,15 @@
+package com.mapbox.mapboxsdk.testapp.utils;
+
+import android.support.annotation.IdRes;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+public class ViewUtils {
+
+ public static void clickView(@IdRes int viewRes) {
+ onView(withId(viewRes))
+ .perform(click());
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index e331884224..4b44efdfe5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -5,6 +5,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:name=".MapboxApplication"
@@ -84,10 +86,27 @@
<activity
android:name=".ScrollByActivity"
android:label="@string/activity_scroll_by" />
+ <activity
+ android:name=".DynamicMarkerChangeActivity"
+ android:label="@string/activity_dynamic_marker" />
+ <activity
+ android:name=".MapPaddingActivity"
+ android:screenOrientation="portrait"
+ android:label="@string/activity_map_padding" />
<meta-data
android:name="com.mapbox.AccessToken"
android:value="" />
+
+ <meta-data
+ android:name="com.mapbox.TestEventsServer"
+ android:value="https://cloudfront-staging.tilestream.net" />
+
+ <meta-data
+ android:name="com.mapbox.TestEventsAccessToken"
+ android:value="sk.eyJ1IjoiYmxlZWdlIiwiYSI6InNpcml1c2x5In0.KyT-boMyC_xZYTYojTc8zg" />
+
+ <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService" />
</application>
</manifest>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java
index 3c5e53a0ad..e85f0dda63 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/BulkMarkerActivity.java
@@ -17,7 +17,7 @@ import android.widget.Spinner;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -150,7 +150,7 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
public LoadBulkMarkerTask(Context context, MapboxMap mapboxMap, int amount) {
mMapboxMap = mapboxMap;
- mapboxMap.removeAllAnnotations();
+ mapboxMap.removeAnnotations();
mProgressDialog = ProgressDialog.show(context, "Loading", "Fetching markers", false);
mAppContext = context.getApplicationContext();
mAmount = amount;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java
index 9ccbc34c3d..50c3c3e42e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java
@@ -10,9 +10,10 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -47,6 +48,12 @@ public class CameraActivity extends AppCompatActivity {
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
// set a style
mapboxMap.setStyle(Style.MAPBOX_STREETS);
+ mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ @Override
+ public void onCameraChange(CameraPosition position) {
+ Log.v(MapboxConstants.TAG, position.toString());
+ }
+ });
// handle move button clicks
findViewById(R.id.cameraMoveButton).setOnClickListener(new View.OnClickListener() {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivity.java
index 25c3896be2..615b3388c3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CoordinateChangeActivity.java
@@ -10,7 +10,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DirectionsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DirectionsActivity.java
index 7c37fc9540..6045eeadfd 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DirectionsActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DirectionsActivity.java
@@ -17,7 +17,7 @@ import com.mapbox.directions.service.models.Waypoint;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivity.java
index 9bf168ee75..7af3790443 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DoubleMapActivity.java
@@ -12,12 +12,13 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
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;
public class DoubleMapActivity extends AppCompatActivity {
@@ -63,7 +64,7 @@ public class DoubleMapActivity extends AppCompatActivity {
super.onViewCreated(view, savedInstanceState);
// MapView large
- mMapView = (MapView) view.findViewById(R.id.mapview);
+ mMapView = (MapView) view.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
@@ -72,7 +73,8 @@ public class DoubleMapActivity extends AppCompatActivity {
mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(18));
try {
- mapboxMap.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ TrackingSettings settings = mapboxMap.getTrackingSettings();
+ settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
} catch (SecurityException e) {
// permission is handled in MainActivity
getActivity().finish();
@@ -96,7 +98,8 @@ public class DoubleMapActivity extends AppCompatActivity {
uiSettings.setLogoEnabled(false);
try {
- mapboxMap.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ TrackingSettings settings = mapboxMap.getTrackingSettings();
+ settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
}catch (SecurityException e){
// permission is handled in MainActivity
getActivity().finish();
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivity.java
new file mode 100644
index 0000000000..6bd7596ea1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/DynamicMarkerChangeActivity.java
@@ -0,0 +1,145 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.MenuItem;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.annotations.IconFactory;
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.utils.ApiAccess;
+
+public class DynamicMarkerChangeActivity extends AppCompatActivity {
+
+ private static final LatLng LAT_LNG_CHELSEA = new LatLng(51.481670, -0.190849);
+ private static final LatLng LAT_LNG_ARSENAL = new LatLng(51.555062, -0.108417);
+
+ private MapView mMapView;
+ private MapboxMap mMapboxMap;
+ private IconFactory mIconFactory;
+ private Marker mMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_dynamic_marker);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mIconFactory = IconFactory.getInstance(this);
+
+ mMapView = (MapView) findViewById(R.id.mapView);
+ mMapView.setTag(true);
+ mMapView.setAccessToken(ApiAccess.getToken(this));
+ mMapView.onCreate(savedInstanceState);
+ mMapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ mMapboxMap = mapboxMap;
+ mapboxMap.setStyle(Style.MAPBOX_STREETS);
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.506675, -0.128699), 10));
+
+ // Create marker
+ MarkerOptions markerOptions = new MarkerOptions()
+ .position(LAT_LNG_CHELSEA)
+ .icon(mIconFactory.fromResource(R.drawable.ic_chelsea));
+ mMarker = mapboxMap.addMarker(markerOptions);
+ }
+ });
+
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mMapboxMap != null) {
+ updateMarker();
+ }
+ }
+ });
+ }
+
+ private void updateMarker() {
+ // update model
+ boolean first = (boolean) mMapView.getTag();
+ mMapView.setTag(!first);
+
+ // update marker
+ mMarker.setPosition(first ? LAT_LNG_CHELSEA : LAT_LNG_ARSENAL);
+ mMarker.setIcon(mIconFactory.fromResource(first ? R.drawable.ic_chelsea : R.drawable.ic_arsenal));
+ }
+
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mMapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mMapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mMapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mMapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mMapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mMapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mMapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java
index b87812277c..5594348be7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/GeocoderActivity.java
@@ -78,7 +78,7 @@ public class GeocoderActivity extends AppCompatActivity {
@Override
public void onMapClick(@NonNull LatLng point) {
setMessage("Geocoding...");
- mapboxMap.removeAllAnnotations();
+ mapboxMap.removeAnnotations();
mapboxMap.addMarker(new MarkerOptions()
.position(point)
.title("Your finger is here"));
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowActivity.java
index e34bff9eed..f12a183563 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowActivity.java
@@ -6,6 +6,7 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
+import android.widget.Toast;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.annotations.Marker;
@@ -46,21 +47,24 @@ public class InfoWindowActivity extends AppCompatActivity {
mapboxMap.addMarker(new MarkerOptions()
.title("Intersection")
.snippet("H St NW with 15th St NW")
- .icon(IconFactory.getInstance(InfoWindowActivity.this)
- .fromAsset("london-underground-24.png"))
.position(new LatLng(38.9002073, -77.03364419)));
mapboxMap.addMarker(new MarkerOptions()
.title("White House")
.snippet("The official residence and principal workplace of the President of the United States, located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every U.S. president since John Adams in 1800.")
- .icon(IconFactory.getInstance(InfoWindowActivity.this).fromAsset("town-hall-24.png"))
.position(new LatLng(38.897705003219784, -77.03655168667463)));
mapboxMap.addMarker(new MarkerOptions().title("Intersection")
.snippet("E St NW with 17th St NW")
- .icon(IconFactory.getInstance(InfoWindowActivity.this).fromAsset("commercial-24.png"))
.position(new LatLng(38.8954236, -77.0394623)));
+ mapboxMap.setOnInfoWindowCloseListener(new MapboxMap.OnInfoWindowCloseListener() {
+ @Override
+ public void onInfoWindowClose(Marker marker) {
+ Toast.makeText(getApplicationContext(),"OnClose: "+marker.getTitle(),Toast.LENGTH_LONG).show();
+ }
+ });
+
final DecimalFormat formatter = new DecimalFormat("#.#####");
mapboxMap.setOnMapLongClickListener(new MapboxMap.OnMapLongClickListener() {
@Override
@@ -78,6 +82,25 @@ public class InfoWindowActivity extends AppCompatActivity {
.position(point));
}
});
+
+
+ mapboxMap.setOnInfoWindowClickListener(new MapboxMap.OnInfoWindowClickListener() {
+ @Override
+ public boolean onInfoWindowClick(@NonNull Marker marker) {
+ Toast.makeText(getApplicationContext(), "OnClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
+ // return false to close the info window
+ // return true to leave the info window open
+ return false;
+ }
+ });
+
+ mapboxMap.setOnInfoWindowLongClickListener(new MapboxMap.OnInfoWindowLongClickListener() {
+ @Override
+ public void onInfoWindowLongClick(Marker marker) {
+ Toast.makeText(getApplicationContext(),"OnLongClick: "+marker.getTitle(),Toast.LENGTH_LONG).show();
+ }
+ });
+
}
});
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowAdapterActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowAdapterActivity.java
index 52f0bddc28..02380e59f2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowAdapterActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/InfoWindowAdapterActivity.java
@@ -16,10 +16,11 @@ import android.widget.TextView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.testapp.annotations.CityStateMarker;
+import com.mapbox.mapboxsdk.testapp.annotations.CityStateMarkerOptions;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -54,12 +55,12 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
// add markers
- mapboxMap.addMarker(generateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
- mapboxMap.addMarker(generateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
- mapboxMap.addMarker(generateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
- mapboxMap.addMarker(generateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
- mapboxMap.addMarker(generateMarker("San Marino", 43.942360, 12.457777, "#795548"));
- mapboxMap.addMarker(generateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
+ mapboxMap.addMarker(generateCityStateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
+ mapboxMap.addMarker(generateCityStateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
+ mapboxMap.addMarker(generateCityStateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
+ mapboxMap.addMarker(generateCityStateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
+ mapboxMap.addMarker(generateCityStateMarker("San Marino", 43.942360, 12.457777, "#795548"));
+ mapboxMap.addMarker(generateCityStateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
// add custom window adapter
mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
@@ -71,7 +72,12 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
TextView textView = new TextView(InfoWindowAdapterActivity.this);
textView.setText(marker.getTitle());
textView.setTextColor(Color.WHITE);
- textView.setBackgroundColor(Color.parseColor(marker.getSnippet()));
+
+ if(marker instanceof CityStateMarker){
+ CityStateMarker cityStateMarker = (CityStateMarker)marker;
+ textView.setBackgroundColor(Color.parseColor(cityStateMarker.getInfoWindowBackgroundColor()));
+ }
+
textView.setPadding(tenDp, tenDp, tenDp, tenDp);
return textView;
}
@@ -80,13 +86,13 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
});
}
- private MarkerOptions generateMarker(String title, double lat, double lng, String color) {
- MarkerOptions marker = new MarkerOptions();
+ private CityStateMarkerOptions generateCityStateMarker(String title, double lat, double lng, String color) {
+ CityStateMarkerOptions marker = new CityStateMarkerOptions();
marker.title(title);
- marker.snippet(color);
marker.position(new LatLng(lat, lng));
+ marker.infoWindowBackground(color);
- mIconDrawable.setColorFilter(Color.parseColor(marker.getSnippet()), PorterDuff.Mode.SRC_IN);
+ mIconDrawable.setColorFilter(Color.parseColor(color), PorterDuff.Mode.SRC_IN);
Icon icon = mIconFactory.fromDrawable(mIconDrawable);
marker.icon(icon);
return marker;
@@ -144,4 +150,5 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item);
}
}
+
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivity.java
index ee39beb04a..3246807f89 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/LatLngBoundsActivity.java
@@ -10,7 +10,7 @@ import android.view.MenuItem;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
index 3a473f63c5..d1ac656cd0 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
@@ -38,6 +38,7 @@ import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.layers.CustomLayer;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.maps.TrackingSettings;
import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.testapp.layers.ExampleCustomLayer;
import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil;
@@ -213,13 +214,21 @@ public class MainActivity extends AppCompatActivity {
mMapboxMap.setOnInfoWindowClickListener(new MapboxMap.OnInfoWindowClickListener() {
@Override
- public boolean onMarkerClick(@NonNull Marker marker) {
+ public boolean onInfoWindowClick(@NonNull Marker marker) {
Snackbar.make(mCoordinatorLayout, "InfoWindow Click Listener for " + marker.getTitle(), Snackbar.LENGTH_SHORT).show();
marker.hideInfoWindow();
return true;
}
});
+
+ mMapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ @Override
+ public void onCameraChange(CameraPosition position) {
+ Log.v(TAG, "OnCameraChange : " + position);
+ }
+ });
+
changeMapStyle(mSelectedStyle);
}
});
@@ -455,6 +464,14 @@ public class MainActivity extends AppCompatActivity {
startActivity(new Intent(getApplicationContext(), ScrollByActivity.class));
return true;
+ case R.id.action_dynamic_marker:
+ startActivity(new Intent(getApplicationContext(), DynamicMarkerChangeActivity.class));
+ return true;
+
+ case R.id.action_map_padding:
+ startActivity(new Intent(getApplicationContext(),MapPaddingActivity.class));
+ return true;
+
default:
return changeMapStyle(menuItem.getItemId());
}
@@ -539,12 +556,20 @@ public class MainActivity extends AppCompatActivity {
}
});
mMapboxMap.setMyLocationEnabled(true);
- mMapboxMap.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
- mMapboxMap.setMyBearingTrackingMode(MyBearingTracking.GPS);
+
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS);
+
mLocationFAB.setColorFilter(ContextCompat.getColor(this, R.color.primary));
}
} else {
- mMapboxMap.setMyLocationEnabled(false);
+ if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED) ||
+ (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED)) {
+ mMapboxMap.setMyLocationEnabled(false);
+ }
mLocationFAB.setColorFilter(Color.TRANSPARENT);
}
}
@@ -630,7 +655,7 @@ public class MainActivity extends AppCompatActivity {
private void removeAnnotations() {
mMarkerList.clear();
- mMapboxMap.removeAllAnnotations();
+ mMapboxMap.removeAnnotations();
}
private void addCustomLayer() {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivity.java
index 83f50f7e61..1f74d1e7f8 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ManualZoomActivity.java
@@ -10,7 +10,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapFragmentActivity.java
index e8750b66d7..4615d35e33 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapFragmentActivity.java
@@ -9,7 +9,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.maps.MapFragment;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivity.java
new file mode 100644
index 0000000000..524925d51b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapPaddingActivity.java
@@ -0,0 +1,162 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+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.utils.ApiAccess;
+
+public class MapPaddingActivity extends AppCompatActivity {
+
+ private MapView mMapView;
+ private MapboxMap mMapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_padding);
+
+ final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mMapView = (MapView) findViewById(R.id.mapView);
+ mMapView.setTag(true);
+ mMapView.setAccessToken(ApiAccess.getToken(this));
+ mMapView.onCreate(savedInstanceState);
+ mMapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ mMapboxMap = mapboxMap;
+ mapboxMap.setStyle(Style.MAPBOX_STREETS);
+
+ moveToBangalore();
+
+ int paddingLeft = (int) getResources().getDimension(R.dimen.map_padding_left);
+ int paddingBottom = (int) getResources().getDimension(R.dimen.map_padding_bottom);
+ int paddingRight = (int) getResources().getDimension(R.dimen.map_padding_right);
+ mapboxMap.setPadding(paddingLeft, toolbar.getHeight(), paddingRight, paddingBottom);
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mMapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mMapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mMapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mMapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mMapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mMapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mMapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_padding, menu);
+ return true;
+ }
+
+ private void toggleGps(boolean enable) {
+ try {
+ // Enable user location
+ mMapboxMap.setMyLocationEnabled(enable);
+
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+ trackingSettings.setDismissTrackingOnGesture(false);
+ trackingSettings.setMyLocationTrackingMode(enable ? MyLocationTracking.TRACKING_FOLLOW : MyLocationTracking.TRACKING_NONE);
+ } catch (SecurityException e) {
+ // permission not granted is handled in MainActivity
+ finish();
+ }
+ }
+
+ private void moveToBangalore() {
+ toggleGps(false);
+ LatLng bangalore = new LatLng(12.9810816, 77.6368034);
+ mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .zoom(16)
+ .target(bangalore)
+ .bearing(40)
+ .tilt(45)
+ .build()));
+ mMapboxMap.addMarker(new MarkerOptions().title("Center map").position(bangalore));
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+
+ case R.id.action_user_tracking:
+ if (mMapboxMap != null) {
+ toggleGps(true);
+ }
+ return true;
+
+ case R.id.action_bangalore:
+ if (mMapboxMap != null) {
+ moveToBangalore();
+ }
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivity.java
index 89ae1150ea..16160a2fc6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxMapActivity.java
@@ -9,7 +9,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivity.java
index 3ace776e02..19c2578db2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MaxMinZoomActivity.java
@@ -9,12 +9,13 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
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.UiSettings;
import com.mapbox.mapboxsdk.utils.ApiAccess;
public class MaxMinZoomActivity extends AppCompatActivity {
@@ -44,8 +45,11 @@ public class MaxMinZoomActivity extends AppCompatActivity {
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
mMapboxMap = mapboxMap;
mMapboxMap.setStyle(Style.SATELLITE_STREETS);
- mMapboxMap.setMinZoom(3);
- mMapboxMap.setMaxZoom(5);
+
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ uiSettings.setMinZoom(3);
+ uiSettings.setMaxZoom(5);
+
mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(-1.063510, 32.895425)));
}
});
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java
index 411ca36316..2f3f744e71 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java
@@ -15,12 +15,13 @@ import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.maps.TrackingSettings;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -39,25 +40,13 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
+ final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
}
- 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);
- mLocationSpinner = (Spinner) findViewById(R.id.spinner_location);
- mLocationSpinner.setAdapter(locationTrackingAdapter);
- mLocationSpinner.setOnItemSelectedListener(this);
-
- 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);
- mBearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
- mBearingSpinner.setAdapter(bearingTrackingAdapter);
- mBearingSpinner.setOnItemSelectedListener(this);
-
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.setAccessToken(ApiAccess.getToken(this));
mMapView.onCreate(savedInstanceState);
@@ -68,6 +57,18 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this);
+ 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);
+ mLocationSpinner = (Spinner) findViewById(R.id.spinner_location);
+ mLocationSpinner.setAdapter(locationTrackingAdapter);
+ mLocationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
+
+ 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);
+ mBearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
+ mBearingSpinner.setAdapter(bearingTrackingAdapter);
+ mBearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
+
try {
mapboxMap.setMyLocationEnabled(true);
} catch (SecurityException e) {
@@ -135,28 +136,29 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) throws SecurityException {
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
if (parent.getId() == R.id.spinner_location) {
switch (position) {
case 0:
- mMapboxMap.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
break;
case 1:
- mMapboxMap.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
break;
}
} else if (parent.getId() == R.id.spinner_bearing) {
switch (position) {
case 0:
- mMapboxMap.setMyBearingTrackingMode(MyBearingTracking.NONE);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
break;
case 1:
- mMapboxMap.setMyBearingTrackingMode(MyBearingTracking.GPS);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS);
break;
case 2:
- mMapboxMap.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
break;
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java
index eaf2b240b0..313eb6722b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/PolylineActivity.java
@@ -169,7 +169,7 @@ public class PolylineActivity extends AppCompatActivity {
case R.id.action_id_remove:
// test to remove all annotations
mPolylineOptions.clear();
- mMapboxMap.removeAllAnnotations();
+ mMapboxMap.removeAnnotations();
return true;
case android.R.id.home:
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java
index 47b81d35a8..2e0e741677 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/ScrollByActivity.java
@@ -15,7 +15,7 @@ import android.widget.TextView;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivity.java
index 67d329d0d6..bf690b7943 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/SupportMapFragmentActivity.java
@@ -9,7 +9,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TiltActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TiltActivity.java
index 75c1eae191..1713673129 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TiltActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/TiltActivity.java
@@ -8,7 +8,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarker.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarker.java
new file mode 100644
index 0000000000..1ec5aa9c76
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarker.java
@@ -0,0 +1,18 @@
+package com.mapbox.mapboxsdk.testapp.annotations;
+
+import com.mapbox.mapboxsdk.annotations.Marker;
+
+public class CityStateMarker extends Marker {
+
+ private String mInfoWindowBackgroundColor;
+
+ public CityStateMarker(CityStateMarkerOptions cityStateOptions, String color) {
+ super(cityStateOptions);
+ mInfoWindowBackgroundColor = color;
+ }
+
+ public String getInfoWindowBackgroundColor() {
+ return mInfoWindowBackgroundColor;
+ }
+
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarkerOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarkerOptions.java
new file mode 100644
index 0000000000..379a9210e5
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/annotations/CityStateMarkerOptions.java
@@ -0,0 +1,68 @@
+package com.mapbox.mapboxsdk.testapp.annotations;
+
+import android.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+public class CityStateMarkerOptions extends BaseMarkerOptions<CityStateMarker, CityStateMarkerOptions> {
+
+ private String mInfoWindowBackgroundColor;
+
+ public CityStateMarkerOptions infoWindowBackground(String color) {
+ mInfoWindowBackgroundColor = color;
+ return getThis();
+ }
+
+ public CityStateMarkerOptions() {
+ }
+
+ private CityStateMarkerOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
+ title(in.readString());
+ }
+
+ @Override
+ public CityStateMarkerOptions getThis() {
+ return this;
+ }
+
+ @Override
+ public CityStateMarker getMarker() {
+ return new CityStateMarker(this, mInfoWindowBackgroundColor);
+ }
+
+ public static final Parcelable.Creator<CityStateMarkerOptions> CREATOR
+ = new Parcelable.Creator<CityStateMarkerOptions>() {
+ public CityStateMarkerOptions createFromParcel(Parcel in) {
+ return new CityStateMarkerOptions(in);
+ }
+
+ public CityStateMarkerOptions[] newArray(int size) {
+ return new CityStateMarkerOptions[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(position, flags);
+ out.writeString(snippet);
+ out.writeString(icon.getId());
+ out.writeParcelable(icon.getBitmap(), flags);
+ out.writeString(title);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_arsenal.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_arsenal.png
new file mode 100644
index 0000000000..6fdac4ef09
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_arsenal.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_chelsea.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_chelsea.png
new file mode 100644
index 0000000000..6cd376b281
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_chelsea.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_dynamic_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_dynamic_marker.xml
new file mode 100644
index 0000000000..e16f6b317d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_dynamic_marker.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M7,7h10v3l4,-4 -4,-4v3H5v6h2V7zm10,10H7v-3l-4,4 4,4v-3h12v-6h-2v4zm-4,-2V9h-1l-2,1v1h1.5v4H13z"/>
+</vector>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_map_padding.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_map_padding.xml
new file mode 100644
index 0000000000..60b75a5493
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_map_padding.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,19H5V5h7V3H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2v7zM14,3v2h3.59l-9.83,9.83 1.41,1.41L19,6.41V10h2V3h-7z"/>
+</vector>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml
index 5de3651272..21684ccadb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml
@@ -16,6 +16,6 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets" />
+ app:style_url="@string/mapbox_style_mapbox_streets" />
</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml
new file mode 100644
index 0000000000..73592448b2
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+ <FrameLayout
+ android:id="@+id/content_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@+id/toolbar">
+
+ <android.support.design.widget.CoordinatorLayout
+ 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" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/fab"
+ 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_animate_coordinates"
+ app:backgroundTint="@color/white" />
+
+ </android.support.design.widget.CoordinatorLayout>
+
+ </FrameLayout>
+
+</RelativeLayout>
+
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml
index eccd3ea8eb..f9e0145356 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml
@@ -16,7 +16,7 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:center_latitude="38.897705003219784"
app:center_longitude="-77.03655168667463"
app:zoom="15" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml
index ccced6bbff..8cf30a4475 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml
@@ -16,7 +16,7 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:center_latitude="47.798202"
app:center_longitude="7.573781"
app:zoom="4" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_concurrent.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_concurrent.xml
index 062726fcb2..69276ad491 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_concurrent.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_concurrent.xml
@@ -16,7 +16,7 @@
android:id="@+id/infoWindowConcurrentMapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:center_latitude="38.897705003219784"
app:center_longitude="-77.03655168667463"
app:zoom="15" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_padding.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_padding.xml
new file mode 100644
index 0000000000..aa3c50d65c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_padding.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@+id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <View
+ android:layout_width="@dimen/map_padding_left"
+ android:layout_height="match_parent"
+ android:layout_marginTop="?attr/actionBarSize"
+ android:alpha="0.5"
+ android:background="@color/mapbox_blue" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/map_padding_bottom"
+ android:layout_gravity="bottom"
+ android:layout_marginEnd="@dimen/map_padding_right"
+ android:layout_marginLeft="@dimen/map_padding_left"
+ android:layout_marginRight="@dimen/map_padding_right"
+ android:layout_marginStart="@dimen/map_padding_left"
+ android:alpha="0.5"
+ android:background="@color/mapbox_blue" />
+
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:alpha="0.5"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+ <View
+ android:layout_width="@dimen/map_padding_right"
+ android:layout_height="match_parent"
+ android:layout_gravity="end"
+ android:layout_marginLeft="@dimen/map_padding_left"
+ android:layout_marginStart="@dimen/map_padding_left"
+ android:alpha="0.5"
+ android:layout_marginTop="?attr/actionBarSize"
+ android:background="@color/mapbox_blue" />
+
+</FrameLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_mapboxmap.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_mapboxmap.xml
index eccd3ea8eb..f9e0145356 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_mapboxmap.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_mapboxmap.xml
@@ -16,7 +16,7 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:center_latitude="38.897705003219784"
app:center_longitude="-77.03655168667463"
app:zoom="15" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml
index ce108ba129..5e9b8e62d7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml
@@ -25,7 +25,7 @@
android:layout_height="match_parent"
app:center_latitude="38.897705003219784"
app:center_longitude="-77.03655168667463"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:zoom="15" />
</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
index 699fa4be6b..7b16910953 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
@@ -42,7 +42,7 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:zoom="15" />
</LinearLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml
index 7875fc2021..7f4012f74e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml
@@ -19,7 +19,7 @@
android:layout_below="@+id/toolbar"
app:center_latitude="47.798202"
app:center_longitude="7.573781"
- app:style_url="@string/style_mapbox_streets"
+ app:style_url="@string/mapbox_style_mapbox_streets"
app:zoom="4" />
<android.support.design.widget.FloatingActionButton
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml
index 230a0a308e..88788fc429 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_double_map.xml
@@ -5,10 +5,10 @@
android:layout_height="fill_parent">
<com.mapbox.mapboxsdk.maps.MapView
- android:id="@+id/mapview"
+ android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- mapbox:access_token="@string/access_token" />
+ mapbox:access_token="@string/mapbox_access_token" />
<FrameLayout
android:id="@+id/map_card"
@@ -22,6 +22,6 @@
android:id="@+id/mini_map"
android:layout_width="100dp"
android:layout_height="100dp"
- mapbox:access_token="@string/access_token" />
+ mapbox:access_token="@string/mapbox_access_token" />
</FrameLayout>
</RelativeLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
index b008a4f636..512d195593 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
@@ -192,7 +192,18 @@
android:icon="@drawable/ic_input_24dp"
android:title="@string/activity_scroll_by" />
+ <item
+ android:id="@+id/action_dynamic_marker"
+ android:checkable="false"
+ android:icon="@drawable/ic_dynamic_marker"
+ android:title="@string/action_dynamic_marker" />
+
+ <item
+ android:id="@+id/action_map_padding"
+ android:checkable="false"
+ android:icon="@drawable/ic_map_padding"
+ android:title="@string/action_map_padding" />
+
</menu>
</item>
-
</menu>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_padding.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_padding.xml
new file mode 100644
index 0000000000..0db887c4e7
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_padding.xml
@@ -0,0 +1,12 @@
+<?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_user_tracking"
+ android:title="My Location Tracking"
+ mapbox:showAsAction="never" />
+ <item
+ android:id="@+id/action_bangalore"
+ android:title="Bangalore"
+ mapbox:showAsAction="never" />
+</menu> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/dimens.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/dimens.xml
index 87cfebffd6..c852ed0e7a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/dimens.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/dimens.xml
@@ -3,4 +3,8 @@
<dimen name="fab_margin">16dp</dimen>
<dimen name="attr_margin">10dp</dimen>
<dimen name="coordinatebounds_margin">32dp</dimen>
+ <dimen name="map_padding_left">96dp</dimen>
+ <dimen name="map_padding_bottom">256dp</dimen>
+ <dimen name="map_padding_right">32dp</dimen>
+
</resources>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 773642f291..ea346674b5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -25,6 +25,8 @@
<string name="activity_geocoder">Geocoder Activity</string>
<string name="activity_double_map">Double Map Activity</string>
<string name="activity_scroll_by">Scroll By Activity</string>
+ <string name="activity_dynamic_marker">Dynamic Marker Activity</string>
+ <string name="activity_map_padding">Map Padding Activity</string>
<string name="navdrawer_menu_title_mainactivity_controls">Main Activity Controls</string>
<string name="navdrawer_menu_title_mainactivity_styles">Main Activity Styles</string>
@@ -52,6 +54,8 @@
<string name="action_visible_bounds_explanation">Center map around 2 markers</string>
<string name="action_remove_polylines">Remove polylines</string>
<string name="action_double_mapview">Double MapView</string>
+ <string name="action_dynamic_marker">Dynamic Marker</string>
+ <string name="action_map_padding">Map Padding</string>
<string name="button_camera_move">Move</string>
<string name="button_camera_ease">Ease</string>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java
new file mode 100644
index 0000000000..9e95451cb1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java
@@ -0,0 +1,55 @@
+package com.mapbox.mapboxsdk.annotations;
+
+import android.graphics.Bitmap;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotSame;
+
+public class IconTest {
+
+ @Mock
+ Bitmap mBitmap;
+
+ @Before
+ public void beforeTest() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testId() {
+ String id = "test";
+ Icon icon = IconFactory.recreate(id, Bitmap.createBitmap(0, 0, Bitmap.Config.ALPHA_8));
+ assertEquals("id should match", id, icon.getId());
+ }
+
+ @Test
+ public void testBitmap() {
+ Icon icon = IconFactory.recreate("test", mBitmap);
+ assertEquals("bitmap should match", mBitmap, icon.getBitmap());
+ }
+
+ @Test
+ public void testEquals() {
+ Icon icon1 = IconFactory.recreate("test", mBitmap);
+ Icon icon2 = IconFactory.recreate("test", mBitmap);
+ assertEquals("icons should not match", icon1, icon2);
+ }
+
+ @Test
+ public void testEqualsObject() {
+ Icon icon = IconFactory.recreate("test", Bitmap.createBitmap(0, 0, Bitmap.Config.ALPHA_8));
+ assertNotSame("icon should not match", new Object(), icon);
+ }
+
+ @Test
+ public void testHashcode() {
+ Icon icon = IconFactory.recreate("test", mBitmap);
+ long expectedHashcode = 31 * mBitmap.hashCode() + "test".hashCode();
+ assertEquals("hashcode should match", expectedHashcode, icon.hashCode());
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java
new file mode 100644
index 0000000000..11ab8173fd
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java
@@ -0,0 +1,86 @@
+package com.mapbox.mapboxsdk.annotations;
+
+import android.graphics.PointF;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.Projection;
+
+import org.junit.Test;
+import org.mockito.InjectMocks;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class InfoWindowTest {
+
+ @InjectMocks
+ MapView mMapView = mock(MapView.class);
+
+ @InjectMocks
+ MapboxMap mMapboxMap = mock(MapboxMap.class);
+
+ @Test
+ public void testSanity() {
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ assertNotNull("infoWindow should exist", infoWindow);
+ }
+
+ @Test
+ public void testBoundMarker() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = markerOptions.getMarker();
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap).setBoundMarker(marker);
+ assertEquals("marker should match", marker, infoWindow.getBoundMarker());
+ }
+
+ @Test
+ public void testClose() {
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.close();
+ assertEquals("infowindow should not be visible", false, infoWindow.isVisible());
+ }
+
+
+ @Test
+ public void testOpen() {
+ LatLng latLng = new LatLng(0, 0);
+ Projection projection = mock(Projection.class);
+ when(mMapboxMap.getProjection()).thenReturn(projection);
+ when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
+
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.open(mMapView, new MarkerOptions().getMarker(), latLng, 0, 0);
+ assertEquals("infowindow should not be visible", true, infoWindow.isVisible());
+ }
+
+ @Test
+ public void testOpenClose() {
+ LatLng latLng = new LatLng(0, 0);
+ Projection projection = mock(Projection.class);
+ when(mMapboxMap.getProjection()).thenReturn(projection);
+ when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
+
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.open(mMapView, new MarkerOptions().getMarker(), latLng, 0, 0);
+ infoWindow.close();
+ assertEquals("infowindow should not be visible", false, infoWindow.isVisible());
+ }
+
+
+ @Test
+ public void testUpdate() {
+ LatLng latLng = new LatLng(0, 0);
+ Projection projection = mock(Projection.class);
+ when(mMapboxMap.getProjection()).thenReturn(projection);
+ when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
+
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.open(mMapView, new MarkerOptions().position(latLng).getMarker(), latLng, 0, 0);
+ infoWindow.update();
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java
new file mode 100644
index 0000000000..76e29c208b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java
@@ -0,0 +1,119 @@
+package com.mapbox.mapboxsdk.annotations;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class MarkerTest {
+
+ @Test
+ public void testSanity() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ assertNotNull("markerOptions should not be null", markerOptions);
+ }
+
+ @Test
+ public void testMarker() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ assertNotNull("marker should not be null", markerOptions.getMarker());
+ }
+
+ @Test
+ public void testPosition() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(10, 12));
+ Marker marker = markerOptions.getMarker();
+ assertEquals(marker.getPosition(), new LatLng(10, 12));
+ assertEquals(markerOptions.getPosition(), new LatLng(10, 12));
+ }
+
+ @Test
+ public void testTitle() {
+ MarkerOptions markerOptions = new MarkerOptions().title("Mapbox");
+ Marker marker = markerOptions.getMarker();
+ assertEquals(marker.getTitle(), "Mapbox");
+ assertEquals(markerOptions.getTitle(), "Mapbox");
+ }
+
+ @Test
+ public void testSnippet() {
+ MarkerOptions markerOptions = new MarkerOptions().snippet("Mapbox");
+ Marker marker = markerOptions.getMarker();
+ assertEquals(marker.getSnippet(), "Mapbox");
+ }
+
+ @Test
+ public void testBuilder() {
+ Marker marker = new MarkerOptions().title("title").snippet("snippet").position(new LatLng(10, 12)).getMarker();
+ assertEquals(marker.getSnippet(), "snippet");
+
+ assertEquals(marker.getPosition(), new LatLng(10, 12));
+ }
+
+ @Test
+ public void testIcon() {
+ Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_4444);
+ Icon icon = IconFactory.recreate("test", bitmap);
+ MarkerOptions markerOptions = new MarkerOptions().icon(icon);
+ Marker marker = markerOptions.getMarker();
+ assertEquals("Icon should match", icon, marker.getIcon());
+ assertEquals("Icon should match", icon, markerOptions.getIcon());
+ }
+
+ @Test
+ public void testHashCode() {
+ Marker marker = new MarkerOptions().position(new LatLng(10, 12)).getMarker();
+ assertEquals("hash code should match", marker.hashCode(), -1946419200);
+ }
+
+ @Test
+ public void testHashCodeBuilder() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(10, 12));
+ assertEquals("hash code should match", markerOptions.hashCode(), 579999617);
+ }
+
+ @Test
+ public void testEquals() {
+ Marker markerOne = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
+ Marker markerTwo = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
+ assertEquals(markerOne, markerTwo);
+ }
+
+ @Test
+ public void testEqualsItself() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(0, 0));
+ Marker marker = markerOptions.getMarker();
+ assertEquals("Marker should match", marker, marker);
+ assertEquals("MarkerOptions should match", markerOptions, markerOptions);
+ }
+
+ @Test
+ public void testNotEquals() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(0, 0));
+ Marker marker = markerOptions.getMarker();
+ assertNotEquals("MarkerOptions should match", markerOptions, new Object());
+ assertNotEquals("Marker should match", marker, new Object());
+ }
+
+ @Test
+ public void testEqualityBuilder() {
+ MarkerOptions markerOne = new MarkerOptions().position(new LatLng(0, 0));
+ MarkerOptions markerTwo = new MarkerOptions().position(new LatLng(0, 0));
+ assertEquals(markerOne, markerTwo);
+ }
+
+ @Test
+ public void testToString() {
+ Marker marker = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
+ assertEquals(marker.toString(), "Marker [position[" + "LatLng [longitude=0.0, latitude=0.0, altitude=0.0]" + "]]");
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/PolygonTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java
index 281277692f..744bf55c07 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/PolygonTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.annotations;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/PolylineTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java
index 78af961e02..b95c9dba2a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/PolylineTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.annotations;
import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java
new file mode 100644
index 0000000000..e2109adf47
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java
@@ -0,0 +1,77 @@
+package com.mapbox.mapboxsdk.camera;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.constants.MathConstants;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.utils.MathUtils;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CameraPositionTest {
+
+ @Test
+ public void testSanity() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertNotNull("cameraPosition should not be null", cameraPosition);
+ }
+
+ @Test
+ public void testToString() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertEquals("toString should match", "Target: LatLng [longitude=2.0, latitude=1.0, altitude=0.0], Zoom:3.0, Bearing:5.0, Tilt:4.0", cameraPosition.toString());
+ }
+
+ @Test
+ public void testHashcode() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertEquals("toString should match", -1007681505, cameraPosition.hashCode());
+ }
+
+ @Test
+ public void testRadiantBuilder() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition.Builder builder = new CameraPosition.Builder(true);
+ builder.target(latLng);
+ builder.zoom(3);
+ builder.tilt(4);
+ builder.bearing(5);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertEquals("CameraPosition should match", cameraPosition, builder.build());
+ }
+
+ @Test
+ public void testDegreesRadiantBuilder() {
+ LatLng latLng = new LatLng(1, 2);
+ float tilt = 4;
+ float bearing = 5;
+ float bearingRadiant = (float) (-bearing * MathConstants.DEG2RAD);
+ float tiltRadiant = (float) (MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT) * MathConstants.DEG2RAD);
+
+ CameraPosition.Builder degreeBuilder = new CameraPosition.Builder(false);
+ degreeBuilder.target(latLng);
+ degreeBuilder.zoom(3);
+ degreeBuilder.tilt(tilt);
+ degreeBuilder.bearing(bearing);
+
+ CameraPosition.Builder radiantBuilder = new CameraPosition.Builder(true);
+ radiantBuilder.target(latLng);
+ radiantBuilder.zoom(3);
+ radiantBuilder.tilt(tiltRadiant);
+ radiantBuilder.bearing(bearingRadiant);
+ assertEquals("CameraPosition should match", radiantBuilder.build(), degreeBuilder.build());
+ }
+
+ @Test
+ public void testZoomUpdateBuilder() {
+ float zoomLevel = 5;
+ CameraPosition.Builder builder = new CameraPosition.Builder(
+ (CameraUpdateFactory.ZoomUpdate) CameraUpdateFactory.zoomTo(zoomLevel));
+ assertEquals("zoom should match", zoomLevel, builder.build().zoom, 0);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
index 451d774a78..e3870b63e2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
@@ -2,9 +2,11 @@ package com.mapbox.mapboxsdk.geometry;
import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -85,6 +87,18 @@ public class LatLngBoundsTest {
}
@Test
+ public void testToLatLngs() {
+ mLatLngBounds = new LatLngBounds.Builder()
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .include(LAT_LNG_NULL_ISLAND)
+ .build();
+
+ assertArrayEquals("LatLngs should match",
+ new LatLng[]{LAT_LNG_NOT_NULL_ISLAND, LAT_LNG_NULL_ISLAND},
+ mLatLngBounds.toLatLngs());
+ }
+
+ @Test
public void testIncluding() {
assertTrue("LatLng should be included", mLatLngBounds.including(new LatLng(1, 1)));
}
@@ -106,6 +120,7 @@ public class LatLngBoundsTest {
.include(LAT_LNG_NOT_NULL_ISLAND)
.build();
assertEquals("equality should match", mLatLngBounds, latLngBounds);
+ assertEquals("not equal to a different object type", mLatLngBounds.equals(LAT_LNG_NOT_NULL_ISLAND), false);
}
@Test
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java
index 452046082e..7bf164166c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java
@@ -10,6 +10,7 @@ import static org.junit.Assert.assertNotNull;
public class LatLngSpanTest {
private static final double DELTA = 1e-15;
+ private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
@Test
public void testSanity() {
@@ -18,6 +19,12 @@ public class LatLngSpanTest {
}
@Test
+ public void testEquality() {
+ LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
+ assertEquals("latLngSpan is not equal to a LatLng", latLngSpan.equals(LAT_LNG_NULL_ISLAND), false);
+ }
+
+ @Test
public void testLatitudeConstructor() {
double latitude = 1.23;
LatLngSpan latLngSpan = new LatLngSpan(latitude, 0.0);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java
index 057cbaed56..bd40221706 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java
@@ -1,17 +1,55 @@
package com.mapbox.mapboxsdk.geometry;
-import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
-
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class ProjectedMetersTest {
+ private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
+
@Test
public void testSanity() {
ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 0.0);
assertNotNull("projectedMeters should not be null", projectedMeters);
}
+ @Test
+ public void testEquality() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 0.0);
+ assertEquals("projectedMeters is not equal to a LatLng", projectedMeters.equals(LAT_LNG_NULL_ISLAND), false);
+ assertEquals("projectedMeters is equal to itself", projectedMeters.equals(projectedMeters), true);
+ }
+
+ @Test
+ public void testNorthing() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(1.0, 0.0);
+ assertEquals("northing should be 1", 1, projectedMeters.getNorthing(), 0);
+ }
+
+ @Test
+ public void testEasting() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 1.0);
+ assertEquals("easting should be 1", 1, projectedMeters.getEasting(), 0);
+ }
+
+ @Test
+ public void testConstructor() {
+ ProjectedMeters projectedMeters1 = new ProjectedMeters(1, 2);
+ ProjectedMeters projectedMeters2 = new ProjectedMeters(projectedMeters1);
+ assertEquals("projectedmeters should match", projectedMeters1, projectedMeters2);
+ }
+
+ @Test
+ public void testHashcode() {
+ ProjectedMeters meters = new ProjectedMeters(1, 2);
+ assertEquals("hashcode should match", -1048576, meters.hashCode());
+ }
+
+ @Test
+ public void testToString(){
+ ProjectedMeters meters = new ProjectedMeters(1, 1);
+ assertEquals("toString should match","ProjectedMeters [northing=1.0, easting=1.0]",meters.toString());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java
index 9423108214..83cfa37841 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java
@@ -20,6 +20,13 @@ public class VisibleRegionTest {
}
@Test
+ public void testEquality() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("visibleRegion is not equal to a LatLng", region.equals(FAR_LEFT), false);
+ assertEquals("visibleRegion is equal to itself", region.equals(region), true);
+ }
+
+ @Test
public void testFarLeftConstructor() {
VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
assertEquals("LatLng should match", region.farLeft, FAR_LEFT);
@@ -57,6 +64,12 @@ public class VisibleRegionTest {
}
@Test
+ public void testHashcode() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("hashcode should match", -923534102, region.hashCode());
+ }
+
+ @Test
public void testToString() {
VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
assertEquals("string should match",
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
index 0f75655dc9..2fac586da1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
@@ -1,11 +1,17 @@
package com.mapbox.mapboxsdk.maps;
+import android.graphics.Color;
import android.graphics.Point;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.annotations.Polygon;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.annotations.Polyline;
+import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -15,9 +21,13 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.matches;
import static org.mockito.Mockito.mock;
import static org.junit.Assert.assertNotNull;
@@ -35,6 +45,39 @@ public class MapboxMapTest {
@Mock
MapboxMap.OnMarkerClickListener mOnMarkerClickListener;
+ @Mock
+ MapboxMap.OnCameraChangeListener mOnCameraChangeListener;
+
+ @Mock
+ MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
+
+ @Mock
+ MapboxMap.OnScrollListener mScrollListener;
+
+ @Mock
+ MapboxMap.OnFlingListener mFlingListener;
+
+ @Mock
+ MapboxMap.OnFpsChangedListener mFpsChangedListener;
+
+ @Mock
+ MapboxMap.OnInfoWindowClickListener mWindowClickListener;
+
+ @Mock
+ MapboxMap.OnInfoWindowCloseListener mWindowCloseListener;
+
+ @Mock
+ MapboxMap.OnInfoWindowLongClickListener mWindowLongClickListener;
+
+ @Mock
+ MapboxMap.OnMyLocationChangeListener mLocationChangeListener;
+
+ @Mock
+ MapboxMap.OnMyLocationTrackingModeChangeListener mMyLocationTrackingModeChangeListener;
+
+ @Mock
+ MapboxMap.OnMyBearingTrackingModeChangeListener mMyBearingTrackingModeChangeListener;
+
@Before
public void beforeTest() {
MockitoAnnotations.initMocks(this);
@@ -46,6 +89,16 @@ public class MapboxMapTest {
assertNotNull("mMapboxMap should not be null", mMapboxMap);
}
+ @Test
+ public void testMock() {
+ assertNotNull("mMapView should be mocked", mMapView);
+ }
+
+ @Test
+ public void testGetMapView() {
+ assertNotNull("MapView should be non null", mMapboxMap.getMapView());
+ }
+
//
// UiSettings
//
@@ -56,15 +109,22 @@ public class MapboxMapTest {
}
//
- // Projection
+ // TrackingSettings
//
@Test
- public void testProjection(){
- assertNotNull("Projection should not be null",mMapboxMap.getProjection());
+ public void testTrackingSettings() {
+ assertNotNull("TrackingSettings should not be null", mMapboxMap.getTrackingSettings());
}
+ //
+ // Projection
+ //
+ @Test
+ public void testProjection() {
+ assertNotNull("Projection should not be null", mMapboxMap.getProjection());
+ }
//
// InfoWindow
@@ -82,31 +142,97 @@ public class MapboxMapTest {
assertFalse("ConcurrentWindows should be false", mMapboxMap.isAllowConcurrentMultipleOpenInfoWindows());
}
+ @Test
+ public void testInfoWindowAdapter() {
+ mMapboxMap.setInfoWindowAdapter(mInfoWindowAdapter);
+ assertEquals("InfoWindowAdpter should be the same", mInfoWindowAdapter, mMapboxMap.getInfoWindowAdapter());
+ }
+
//
// Location
//
@Test
public void testMyLocationEnabled() {
- try {
- mMapboxMap.setMyLocationEnabled(true);
- assertTrue("MyLocationEnabled should be true", mMapboxMap.isMyLocationEnabled());
- } catch (SecurityException e) {
- assertTrue(false);
- }
+ when(mMapView.isPermissionsAccepted()).thenReturn(true);
+ mMapboxMap.setMyLocationEnabled(true);
+ assertTrue("MyLocationEnabled should be true", mMapboxMap.isMyLocationEnabled());
+
}
@Test
public void testMyLocationDisabled() {
- try {
- mMapboxMap.setMyLocationEnabled(false);
- assertFalse("MyLocationEnabled should be false", mMapboxMap.isMyLocationEnabled());
- } catch (SecurityException e) {
- assertTrue(false);
- }
+ when(mMapView.isPermissionsAccepted()).thenReturn(true);
+ mMapboxMap.setMyLocationEnabled(false);
+ assertFalse("MyLocationEnabled should be false", mMapboxMap.isMyLocationEnabled());
+ }
+
+ //
+ // padding
+ //
+
+ @Test
+ public void testPadding() {
+ mMapboxMap.setOnCameraChangeListener(mOnCameraChangeListener);
+ CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
+ mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
+ mMapboxMap.setPadding(0, 0, 0, 0);
+ verify(mOnCameraChangeListener, times(2)).onCameraChange(position);
}
//
+ // setters/getters interfaces
+ //
+
+ @Test
+ public void testScrollListener() {
+ mMapboxMap.setOnScrollListener(mScrollListener);
+ assertEquals("ScrollListener should match", mScrollListener, mMapboxMap.getOnScrollListener());
+ }
+
+ @Test
+ public void testFlingListener() {
+ mMapboxMap.setOnFlingListener(mFlingListener);
+ assertEquals("FlingListener should match", mFlingListener, mMapboxMap.getOnFlingListener());
+ }
+
+ @Test
+ public void testFpsListener() {
+ mMapboxMap.setOnFpsChangedListener(mFpsChangedListener);
+ assertEquals("FpsListener should match", mFpsChangedListener, mMapboxMap.getOnFpsChangedListener());
+ }
+
+ @Test
+ public void testInfoWindowClickListener() {
+ mMapboxMap.setOnInfoWindowClickListener(mWindowClickListener);
+ assertEquals("InfoWidowClickListener should match", mWindowClickListener, mMapboxMap.getOnInfoWindowClickListener());
+ }
+
+ @Test
+ public void testInfoWindowCloseListener() {
+ mMapboxMap.setOnInfoWindowCloseListener(mWindowCloseListener);
+ assertEquals("InfoWindowCloseListener should match", mWindowCloseListener, mMapboxMap.getOnInfoWindowCloseListener());
+ }
+
+ @Test
+ public void testInfoWindowLongClickListener() {
+ mMapboxMap.setOnInfoWindowLongClickListener(mWindowLongClickListener);
+ assertEquals("InfoWindowLongClickListener should match", mWindowLongClickListener, mMapboxMap.getOnInfoWindowLongClickListener());
+ }
+
+ @Test
+ public void testOnBearingTrackingModeChangeListener(){
+ mMapboxMap.setOnMyBearingTrackingModeChangeListener(mMyBearingTrackingModeChangeListener);
+ assertEquals("MyBearingTrackingChangeListerner should match",mMyBearingTrackingModeChangeListener, mMapboxMap.getOnMyBearingTrackingModeChangeListener());
+ }
+
+ @Test
+ public void testOnLocationTrackingModeChangeListener(){
+ mMapboxMap.setOnMyLocationTrackingModeChangeListener(mMyLocationTrackingModeChangeListener);
+ assertEquals("MyLocationTrackigChangeListener should match",mMyLocationTrackingModeChangeListener, mMapboxMap.getOnMyLocationTrackingModeChangeListener());
+ }
+
+ //
// Style
//
@@ -183,7 +309,7 @@ public class MapboxMapTest {
@Test
public void testNewCameraPositionEaseCamera() {
CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(position), 1000);
+ mMapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(position));
assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
}
@@ -369,6 +495,238 @@ public class MapboxMapTest {
}
//
+ // OnCameraChangeListener
+ //
+
+ @Test
+ public void testOnCameraChangeListener() {
+ CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
+ mMapboxMap.setOnCameraChangeListener(mOnCameraChangeListener);
+ mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
+ verify(mOnCameraChangeListener, times(1)).onCameraChange(position);
+ }
+
+ //
+ // Annotations
+ //
+
+ @Test
+ public void testAddMarker() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = mMapboxMap.addMarker(markerOptions);
+ assertTrue("Marker should be contained", mMapboxMap.getMarkers().contains(marker));
+ }
+
+ @Test
+ public void testAddMarkers() {
+ List<MarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().title("a");
+ MarkerOptions markerOptions2 = new MarkerOptions().title("b");
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ mMapboxMap.addMarkers(markerList);
+ assertEquals("Markers size should be 2", 2, mMapboxMap.getMarkers().size());
+ assertTrue(mMapboxMap.getMarkers().contains(markerOptions1.getMarker()));
+ assertTrue(mMapboxMap.getMarkers().contains(markerOptions2.getMarker()));
+ }
+
+ @Test
+ public void testAddPolygon() {
+ PolygonOptions polygonOptions = new PolygonOptions().add(new LatLng());
+ Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
+ assertTrue("Polygon should be contained", mMapboxMap.getPolygons().contains(polygon));
+ }
+
+ @Test
+ public void testAddEmptyPolygon() {
+ PolygonOptions polygonOptions = new PolygonOptions();
+ Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
+ assertTrue("Polygon should be ignored", !mMapboxMap.getPolygons().contains(polygon));
+ }
+
+ @Test
+ public void testAddPolygons() {
+ List<PolygonOptions> polygonList = new ArrayList<>();
+ PolygonOptions polygonOptions1 = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng());
+ PolygonOptions polygonOptions2 = new PolygonOptions().fillColor(Color.WHITE).add(new LatLng());
+ PolygonOptions polygonOptions3 = new PolygonOptions();
+ polygonList.add(polygonOptions1);
+ polygonList.add(polygonOptions2);
+ polygonList.add(polygonOptions3);
+ mMapboxMap.addPolygons(polygonList);
+ assertEquals("Polygons size should be 2", 2, mMapboxMap.getPolygons().size());
+ assertTrue(mMapboxMap.getPolygons().contains(polygonOptions1.getPolygon()));
+ assertTrue(mMapboxMap.getPolygons().contains(polygonOptions2.getPolygon()));
+ assertTrue("Polygon should be ignored", !mMapboxMap.getPolygons().contains(polygonOptions3.getPolygon()));
+ }
+
+ @Test
+ public void testAddPolyline() {
+ PolylineOptions polylineOptions = new PolylineOptions().add(new LatLng());
+ Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
+ assertTrue("Polyline should be contained", mMapboxMap.getPolylines().contains(polyline));
+ }
+
+ @Test
+ public void testAddEmptyPolyline() {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
+ assertTrue("Polyline should be ignored", !mMapboxMap.getPolylines().contains(polyline));
+ }
+
+ @Test
+ public void testAddPolylines() {
+ List<PolylineOptions> polylineList = new ArrayList<>();
+ PolylineOptions polygonOptions1 = new PolylineOptions().color(Color.BLACK).add(new LatLng());
+ PolylineOptions polygonOptions2 = new PolylineOptions().color(Color.WHITE).add(new LatLng());
+ PolylineOptions polygonOptions3 = new PolylineOptions();
+ polylineList.add(polygonOptions1);
+ polylineList.add(polygonOptions2);
+ polylineList.add(polygonOptions3);
+ mMapboxMap.addPolylines(polylineList);
+ assertEquals("Polygons size should be 2", 2, mMapboxMap.getPolylines().size());
+ assertTrue(mMapboxMap.getPolylines().contains(polygonOptions1.getPolyline()));
+ assertTrue(mMapboxMap.getPolylines().contains(polygonOptions2.getPolyline()));
+ assertTrue("Polyline should be ignored", !mMapboxMap.getPolylines().contains(polygonOptions3.getPolyline()));
+ }
+
+ @Test
+ public void testRemoveMarker() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = mMapboxMap.addMarker(markerOptions);
+ mMapboxMap.removeMarker(marker);
+ assertTrue("Markers should be empty", mMapboxMap.getMarkers().isEmpty());
+ }
+
+ @Test
+ public void testRemovePolygon() {
+ PolygonOptions polygonOptions = new PolygonOptions();
+ Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
+ mMapboxMap.removePolygon(polygon);
+ assertTrue("Polygons should be empty", mMapboxMap.getPolylines().isEmpty());
+ }
+
+ @Test
+ public void testRemovePolyline() {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
+ mMapboxMap.removePolyline(polyline);
+ assertTrue("Polylines should be empty", mMapboxMap.getPolylines().isEmpty());
+ }
+
+ @Test
+ public void testRemoveAnnotation() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = mMapboxMap.addMarker(markerOptions);
+ mMapboxMap.removeAnnotation(marker);
+ assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
+ }
+
+ @Test
+ public void testRemoveAnnotationById() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ mMapboxMap.addMarker(markerOptions);
+ // id will always be 0 in unit tests
+ mMapboxMap.removeAnnotation(0);
+ assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
+ }
+
+ @Test
+ public void testRemoveAnnotations() {
+ List<MarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().title("a");
+ MarkerOptions markerOptions2 = new MarkerOptions().title("b");
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ mMapboxMap.addMarkers(markerList);
+ mMapboxMap.removeAnnotations();
+ assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
+ }
+
+ @Test
+ public void testRemoveAnnotationsByList() {
+ List<MarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().title("a");
+ MarkerOptions markerOptions2 = new MarkerOptions().title("b");
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ List<Marker> markers = mMapboxMap.addMarkers(markerList);
+ Marker marker = mMapboxMap.addMarker(new MarkerOptions().title("c"));
+ mMapboxMap.removeAnnotations(markers);
+ assertTrue("Annotations should not be empty", mMapboxMap.getAnnotations().size() == 1);
+ assertTrue("Marker should be contained", mMapboxMap.getAnnotations().contains(marker));
+ }
+
+ @Test
+ public void testGetAnnotationById() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker initialMarker = mMapboxMap.addMarker(markerOptions);
+ Marker retrievedMarker = (Marker) mMapboxMap.getAnnotation(0);
+ assertEquals("Markers should match", initialMarker, retrievedMarker);
+ }
+
+ @Test
+ public void testGetAnnotations() {
+ assertNotNull("Annotations should be non null", mMapboxMap.getAnnotations());
+ }
+
+ @Test
+ public void testGetMarkers() {
+ assertNotNull("Markers should be non null", mMapboxMap.getMarkers());
+ }
+
+ @Test
+ public void testGetPolygons() {
+ assertNotNull("Polygons should be non null", mMapboxMap.getPolygons());
+ }
+
+ @Test
+ public void testGetPolylines() {
+ assertNotNull("Polylines should be non null", mMapboxMap.getPolylines());
+ }
+
+ @Test
+ public void testGetSelectedMarkers() {
+ assertNotNull("Selected markers should be non null", mMapboxMap.getSelectedMarkers());
+ }
+
+ @Test
+ public void testSelectMarker() {
+ mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = mMapboxMap.addMarker(markerOptions);
+ when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
+ mMapboxMap.selectMarker(marker);
+ assertTrue("Marker should be contained", mMapboxMap.getSelectedMarkers().contains(marker));
+ }
+
+ @Test
+ public void testDeselectMarker() {
+ mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = mMapboxMap.addMarker(markerOptions);
+ when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
+ mMapboxMap.selectMarker(marker);
+ mMapboxMap.deselectMarker(marker);
+ assertTrue("Selected markers should be empty", mMapboxMap.getSelectedMarkers().isEmpty());
+ }
+
+ @Test
+ public void testDeselectMarkers() {
+ mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker1 = mMapboxMap.addMarker(markerOptions);
+ Marker marker2 = mMapboxMap.addMarker(markerOptions);
+ when(mOnMarkerClickListener.onMarkerClick(marker1)).thenReturn(true);
+ when(mOnMarkerClickListener.onMarkerClick(marker2)).thenReturn(true);
+ mMapboxMap.selectMarker(marker1);
+ mMapboxMap.selectMarker(marker2);
+ mMapboxMap.deselectMarkers();
+ assertTrue("Selected markers should be empty", mMapboxMap.getSelectedMarkers().isEmpty());
+ }
+
+
+ //
// OnMarkerClick interface
//
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MarkerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MarkerTest.java
deleted file mode 100644
index efe94e5396..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MarkerTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-public class MarkerTest {
-
- @Test
- public void testSanity() {
- MarkerOptions markerOptions = new MarkerOptions();
- assertNotNull("markerOptions should not be null", markerOptions);
- }
-
- @Test
- public void testMarker() {
- MarkerOptions markerOptions = new MarkerOptions();
- assertNotNull("marker should not be null", markerOptions.getMarker());
- }
-
- @Test
- public void testPosition() {
- Marker marker = new MarkerOptions().position(new LatLng(10, 12)).getMarker();
- assertEquals(marker.getPosition(), new LatLng(10, 12));
- }
-
- @Test
- public void testTitle() {
- Marker marker = new MarkerOptions().title("Mapbox").getMarker();
- assertEquals(marker.getTitle(), "Mapbox");
- }
-
- @Test
- public void testSnippet() {
- Marker marker = new MarkerOptions().snippet("Mapbox").getMarker();
- assertEquals(marker.getSnippet(), "Mapbox");
- }
-
- @Test
- public void testBuilder() {
- Marker marker = new MarkerOptions().title("title").snippet("snippet").position(new LatLng(10, 12)).getMarker();
- assertEquals(marker.getTitle(), "title");
- assertEquals(marker.getSnippet(), "snippet");
- assertEquals(marker.getPosition(), new LatLng(10, 12));
- }
-
- @Test
- public void testIcon() {
- // find a way to test Icon
- }
-
- @Test
- public void testHashCode() {
- Marker marker = new MarkerOptions().position(new LatLng(10, 12)).getMarker();
- assertEquals("hash code should match", marker.hashCode(), -1946419200);
- }
-
- @Test
- public void testEquality() {
- Marker markerOne = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
- Marker markerTwo = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
- assertEquals(markerOne, markerTwo);
- }
-
- @Test
- public void testToString() {
- Marker marker = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
- assertEquals(marker.toString(), "Marker [position[" + "LatLng [longitude=0.0, latitude=0.0, altitude=0.0]" + "]]");
- }
-
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java
new file mode 100644
index 0000000000..266bbadd95
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java
@@ -0,0 +1,53 @@
+package com.mapbox.mapboxsdk.maps;
+
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+
+import org.junit.Test;
+import org.mockito.InjectMocks;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+
+public class TrackingSettingsTest {
+
+ @InjectMocks
+ MapView mMapView = mock(MapView.class);
+
+ @Test
+ public void testSanity() {
+ TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
+ assertNotNull("trackingsettings should not be null", trackingSettings);
+ }
+
+ @Test
+ public void testMyLocationTrackingMode() {
+ TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ assertEquals("MyLocationTrackingMode should match", MyLocationTracking.TRACKING_FOLLOW, trackingSettings.getMyLocationTrackingMode());
+ }
+
+ @Test
+ public void testMyBearingTrackingMode() {
+ TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
+ assertEquals("MyLocationTrackingMode should match", MyBearingTracking.COMPASS, trackingSettings.getMyBearingTrackingMode());
+ }
+
+ @Test
+ public void testDismissTrackingModesOnGesture() {
+ TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
+ trackingSettings.setDismissTrackingOnGesture(false);
+ assertFalse("DismissTrackingOnGesture should be false", trackingSettings.isDismissTrackingOnGesture());
+ }
+
+ @Test
+ public void testValidateGesturesForTrackingModes(){
+ TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
+ trackingSettings.setDismissTrackingOnGesture(false);
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ assertFalse("DismissTrackingOnGesture should be false", trackingSettings.isDismissTrackingOnGesture());
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
index 9c867bf776..cb9031c66e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
@@ -22,6 +22,30 @@ public class UiSettingsTest {
}
@Test
+ public void testMinZoom() {
+ double zoom = 10;
+ UiSettings uiSettings = new UiSettings(mMapView);
+ uiSettings.setMinZoom(zoom);
+ assertEquals("MinZoom should match", zoom, uiSettings.getMinZoom(), 0);
+ }
+
+ @Test
+ public void testMaxZoom() {
+ double zoom = 10;
+ UiSettings uiSettings = new UiSettings(mMapView);
+ uiSettings.setMaxZoom(zoom);
+ assertEquals("MaxZoom should match", zoom, uiSettings.getMaxZoom(), 0);
+ }
+
+ @Test
+ public void testInitialZoomLevels() {
+ //we are mocking MapView we expect a value of 0 to be returned
+ UiSettings uiSettings = new UiSettings(mMapView);
+ assertEquals("MaxZoom should match", 0, uiSettings.getMaxZoom(), 0);
+ assertEquals("MinZoom should match", 0, uiSettings.getMinZoom(), 0);
+ }
+
+ @Test
public void testCompassEnabled() {
UiSettings uiSettings = new UiSettings(mMapView);
uiSettings.setCompassEnabled(true);
@@ -204,4 +228,10 @@ public class UiSettingsTest {
assertEquals("Scroll gesture should be disabled", false, uiSettings.isScrollGesturesEnabled());
}
+ @Test
+ public void testInvalidate() {
+ UiSettings uiSettings = new UiSettings(mMapView);
+ uiSettings.invalidate();
+ }
+
} \ No newline at end of file
diff --git a/platform/android/mapboxgl-app.gypi b/platform/android/mapboxgl-app.gypi
index 0945fc1be2..ecc5ceff04 100644
--- a/platform/android/mapboxgl-app.gypi
+++ b/platform/android/mapboxgl-app.gypi
@@ -26,6 +26,7 @@
'cflags_cc': [
'<@(boost_cflags)',
+ '<@(variant_cflags)',
],
'libraries': [
'<@(libpng_static_libs)',
@@ -113,6 +114,9 @@
{
'files': [
'../../common/ca-bundle.crt',
+ '../../platform/default/resources/api_mapbox_com-digicert.der',
+ '../../platform/default/resources/api_mapbox_com-geotrust.der',
+ '../../platform/default/resources/star_tilestream_net.der',
],
'destination': '<(pwd)/../platform/android/MapboxGLAndroidSDK/src/main/assets'
},
diff --git a/platform/android/src/asset_file_source.cpp b/platform/android/src/asset_file_source.cpp
index 7eb2007778..d2aab30a52 100644
--- a/platform/android/src/asset_file_source.cpp
+++ b/platform/android/src/asset_file_source.cpp
@@ -2,6 +2,7 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/thread.hpp>
+#include <mbgl/util/url.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
@@ -59,7 +60,8 @@ public:
struct zip_stat stat;
::zip_stat_init(&stat);
- std::string path = std::string("assets/") + url.substr(8);
+ std::string path = std::string("assets/") + mbgl::util::percentDecode(url.substr(8));
+
int ret = ::zip_stat(archive.archive, path.c_str(), 0, &stat);
if (ret < 0 || !(stat.valid & ZIP_STAT_SIZE)) {
reportError(Response::Error::Reason::NotFound, "Could not stat file in zip archive", callback);
diff --git a/platform/android/src/http_request_android.cpp b/platform/android/src/http_request_android.cpp
index 390334627a..2e2fd6408d 100644
--- a/platform/android/src/http_request_android.cpp
+++ b/platform/android/src/http_request_android.cpp
@@ -199,17 +199,18 @@ void HTTPAndroidRequest::onResponse(JNIEnv* env, int code, jstring /* message */
response->expires = util::parseTimePoint(mbgl::android::std_string_from_jstring(env, expires).c_str());
}
- if (body != nullptr) {
- jbyte* bodyData = env->GetByteArrayElements(body, nullptr);
- response->data = std::make_shared<std::string>(reinterpret_cast<char*>(bodyData), env->GetArrayLength(body));
- env->ReleaseByteArrayElements(body, bodyData, JNI_ABORT);
- }
-
if (code == 200) {
- // Nothing to do; this is what we want
+ if (body != nullptr) {
+ jbyte* bodyData = env->GetByteArrayElements(body, nullptr);
+ response->data = std::make_shared<std::string>(reinterpret_cast<char*>(bodyData), env->GetArrayLength(body));
+ env->ReleaseByteArrayElements(body, bodyData, JNI_ABORT);
+ } else {
+ response->data = std::make_shared<std::string>();
+ }
+ } else if (code == 204 || (code == 404 && resource.kind == Resource::Kind::Tile)) {
+ response->noContent = true;
} else if (code == 304) {
response->notModified = true;
- response->data.reset();
} else if (code == 404) {
response->error = std::make_unique<Error>(Error::Reason::NotFound, "HTTP status code 404");
} else if (code >= 500 && code < 600) {
@@ -248,6 +249,10 @@ std::unique_ptr<HTTPContextBase> HTTPContextBase::createContext() {
return std::make_unique<HTTPAndroidContext>();
}
+uint32_t HTTPContextBase::maximumConcurrentRequests() {
+ return 20;
+}
+
void JNICALL nativeOnFailure(JNIEnv* env, jobject, jlong nativePtr, jint type, jstring message) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnFailure");
assert(nativePtr != 0);
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 00148562bb..db6bc73726 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -60,6 +60,7 @@ jfieldID iconIdId = nullptr;
jclass markerClass = nullptr;
jfieldID markerPositionId = nullptr;
jfieldID markerIconId = nullptr;
+jfieldID markerIdId = nullptr;
jclass polylineClass = nullptr;
jfieldID polylineAlphaId = nullptr;
@@ -834,6 +835,47 @@ jlong JNICALL nativeAddMarker(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
return nativeMapView->getMap().addPointAnnotation(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id));
}
+void JNICALL nativeUpdateMarker(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject marker) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdateMarker");
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+
+ jlong markerId = env->GetLongField(marker, markerIdId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ if (markerId == -1) {
+ return;
+ }
+
+ jobject position = env->GetObjectField(marker, markerPositionId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ jobject icon = env->GetObjectField(marker, markerIconId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ jstring jid = reinterpret_cast<jstring>(env->GetObjectField(icon, iconIdId));
+ std::string iconId = std_string_from_jstring(env, jid);
+
+ jdouble latitude = env->GetDoubleField(position, latLngLatitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ jdouble longitude = env->GetDoubleField(position, latLngLongitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ }
+
+ // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long.
+ nativeMapView->getMap().updatePointAnnotation(markerId, mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), iconId));
+}
+
jlongArray JNICALL nativeAddMarkers(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarkers");
assert(nativeMapViewPtr != 0);
@@ -1685,6 +1727,12 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_ERR;
}
+ markerIdId = env->GetFieldID(markerClass, "id", "J");
+ if (markerIdId == nullptr) {
+ env->ExceptionDescribe();
+ return JNI_ERR;
+ }
+
polylineClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Polyline");
if (polylineClass == nullptr) {
env->ExceptionDescribe();
@@ -2044,6 +2092,8 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
reinterpret_cast<void *>(&nativeAddPolygon)},
{"nativeAddPolygons", "(JLjava/util/List;)[J",
reinterpret_cast<void *>(&nativeAddPolygons)},
+ {"nativeUpdateMarker", "(JLcom/mapbox/mapboxsdk/annotations/Marker;)V",
+ reinterpret_cast<void *>(&nativeUpdateMarker)} ,
{"nativeRemoveAnnotation", "(JJ)V", reinterpret_cast<void *>(&nativeRemoveAnnotation)},
{"nativeRemoveAnnotations", "(J[J)V", reinterpret_cast<void *>(&nativeRemoveAnnotations)},
{"nativeGetAnnotationsInBounds", "(JLcom/mapbox/mapboxsdk/geometry/LatLngBounds;)[J",
@@ -2304,6 +2354,7 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
markerClass = nullptr;
markerPositionId = nullptr;
markerIconId = nullptr;
+ markerIdId = nullptr;
env->DeleteGlobalRef(polylineClass);
polylineClass = nullptr;
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 8c7115a1e4..d32f3c81cb 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -15,7 +15,7 @@
#include <mbgl/platform/platform.hpp>
#include <mbgl/platform/event.hpp>
#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/gl.hpp>
+#include <mbgl/gl/gl.hpp>
#include <mbgl/util/constants.hpp>
namespace mbgl {