Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,21 @@ class PickerLauncherActivity : AppCompatActivity() {
else getString(R.string.reverse_geocoding_disabled)
}

userLocationSwitch.text = getString(R.string.user_location_button_disabled)
userLocationSwitch.setOnCheckedChangeListener { compoundButton, checked ->
userLocationSwitch.text = if (checked)
getString(R.string.user_location_button_enabled)
else getString(R.string.user_location_button_disabled)
}

fabLocationPicker.setOnClickListener { _ ->
Mapbox.getAccessToken()?.let {
startActivityForResult(
PlacePicker.IntentBuilder()
.accessToken(it)
.placeOptions(PlacePickerOptions.builder()
.includeReverseGeocode(reverseGeocodingSwitch.isChecked)
.includeDeviceLocationButton(userLocationSwitch.isChecked)
.statingCameraPosition(CameraPosition.Builder()
.target(LatLng(40.7544, -73.9862))
.zoom(16.0)
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/res/layout/activity_picker_launcher.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"/>

<Switch
android:id="@+id/userLocationSwitch"
android:layout_width="wrap_content"
android:layout_height="22dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/reverseGeocodingSwitch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />

<TextView
android:id="@+id/textView"
android:layout_width="0dp"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
<string name="detailed_description_place_picker">Example shows how to launch the Place Picker using the Floating action button and receiving a result in onActivityResult.</string>
<string name="reverse_geocoding_enabled">Reverse geocoding enabled</string>
<string name="reverse_geocoding_disabled">Reverse geocoding disabled</string>
<string name="user_location_button_enabled">User location button enabled</string>
<string name="user_location_button_disabled">User location button disabled</string>

<!-- Misc -->
<string name="min_zoom_textview">Min zoom: %1$d</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@ public abstract class PlacePickerOptions implements BasePlaceOptions, Parcelable

public abstract boolean includeReverseGeocode();

public abstract boolean includeDeviceLocationButton();

public static Builder builder() {
return new AutoValue_PlacePickerOptions.Builder()
.includeReverseGeocode(true);
.includeReverseGeocode(true)
.includeDeviceLocationButton(false);
}

@AutoValue.Builder
Expand All @@ -59,6 +62,10 @@ public Builder geocodingTypes(@NonNull @GeocodingTypeCriteria String... geocodin
public abstract Builder statingCameraPosition(@NonNull CameraPosition cameraPosition);

/**
* Determine whether to include a bottom sheet in the PlacePickerActivity to display
* geocoding information associated with coordinates at the center of the map. A new
* geocoding call is made every time the map is moved when true is passed through
* includeReverseGeocode().
*
* @param includeReverseGeocode whether or not to make a reverse geocoding call to
* retrieve and display information associated with
Expand All @@ -68,6 +75,18 @@ public Builder geocodingTypes(@NonNull @GeocodingTypeCriteria String... geocodin
*/
public abstract Builder includeReverseGeocode(boolean includeReverseGeocode);

/**
* Determine whether an Android-system Floating Action Button is included in
* the PlacePickerActivity UI. Clicking on this Floating Action Button will
* move the map camera to the device's location. False is the default if
* this method isn't used in building the PlacePickerOptions object.
*
* @param includeDeviceLocationButton
*
* @return this builder instance for chaining options together
*/
public abstract Builder includeDeviceLocationButton(boolean includeDeviceLocationButton);

public abstract PlacePickerOptions build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
Expand All @@ -15,12 +16,20 @@
import android.view.Window;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.gson.JsonObject;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.api.geocoding.v5.models.CarmenFeature;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
Expand All @@ -33,6 +42,7 @@
import com.mapbox.mapboxsdk.plugins.places.picker.model.PlacePickerOptions;
import com.mapbox.mapboxsdk.plugins.places.picker.viewmodel.PlacePickerViewModel;

import java.util.List;
import java.util.Locale;

import timber.log.Timber;
Expand All @@ -46,8 +56,10 @@
* @since 0.2.0
*/
public class PlacePickerActivity extends AppCompatActivity implements OnMapReadyCallback,
MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraIdleListener, Observer<CarmenFeature> {
MapboxMap.OnCameraMoveStartedListener, MapboxMap.OnCameraIdleListener, Observer<CarmenFeature>,
PermissionsListener {

private PermissionsManager permissionsManager;
CurrentPlaceSelectionBottomSheet bottomSheet;
CarmenFeature carmenFeature;
private PlacePickerViewModel viewModel;
Expand All @@ -56,6 +68,7 @@ public class PlacePickerActivity extends AppCompatActivity implements OnMapReady
private MapboxMap mapboxMap;
private String accessToken;
private MapView mapView;
private FloatingActionButton userLocationButton;
private boolean includeReverseGeocode;

@Override
Expand Down Expand Up @@ -105,6 +118,12 @@ private void bindViews() {
mapView = findViewById(R.id.map_view);
bottomSheet = findViewById(R.id.mapbox_plugins_picker_bottom_sheet);
markerImage = findViewById(R.id.mapbox_plugins_image_view_marker);
userLocationButton = findViewById(R.id.user_location_button);
}

private void bindListeners() {
PlacePickerActivity.this.mapboxMap.addOnCameraMoveStartedListener(PlacePickerActivity.this);
PlacePickerActivity.this.mapboxMap.addOnCameraIdleListener(PlacePickerActivity.this);
}

private void customizeViews() {
Expand All @@ -123,25 +142,85 @@ public void onMapReady(final MapboxMap mapboxMap) {
mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
if (options != null) {
if (options.startingBounds() != null) {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(options.startingBounds(), 0));
} else if (options.statingCameraPosition() != null) {
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(options.statingCameraPosition()));
}
}

adjustCameraBasedOnOptions();
if (includeReverseGeocode) {
// Initialize with the markers current location information.
// Initialize with the marker's current coordinates.
makeReverseGeocodingSearch();
}
bindListeners();

PlacePickerActivity.this.mapboxMap.addOnCameraMoveStartedListener(PlacePickerActivity.this);
PlacePickerActivity.this.mapboxMap.addOnCameraIdleListener(PlacePickerActivity.this);
if (options != null && options.includeDeviceLocationButton()) {
enableLocationComponent(style);
} else {
userLocationButton.hide();
}
}
});
}

private void adjustCameraBasedOnOptions() {
if (options != null) {
if (options.startingBounds() != null) {
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(options.startingBounds(), 0));
} else if (options.statingCameraPosition() != null) {
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(options.statingCameraPosition()));
}
}
}

@SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent(@NonNull Style loadedMapStyle) {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {

// Get an instance of the component
LocationComponent locationComponent = mapboxMap.getLocationComponent();

// Activate with options
locationComponent.activateLocationComponent(
LocationComponentActivationOptions.builder(this, loadedMapStyle).build());

// Enable to make component visible
locationComponent.setLocationComponentEnabled(true);

// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.NONE);

// Set the component's render mode
locationComponent.setRenderMode(RenderMode.NORMAL);

addUserLocationButton();
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, R.string.mapbox_plugins_place_picker_user_location_permission_explanation,
Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
if (granted) {
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
if (options != null && options.includeDeviceLocationButton()) {
enableLocationComponent(style);
}
}
});
}
}

@Override
public void onCameraMoveStarted(int reason) {
Timber.v("Map camera has begun moving.");
Expand Down Expand Up @@ -185,8 +264,8 @@ private void makeReverseGeocodingSearch() {
LatLng latLng = mapboxMap.getCameraPosition().target;
if (latLng != null) {
viewModel.reverseGeocode(
Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()),
accessToken, options
Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()),
accessToken, options
);
}
}
Expand All @@ -207,6 +286,32 @@ public void onClick(View view) {
});
}

/**
* Bind the device location Floating Action Button to this activity's UI and move the
* map camera if the button's clicked.
*/
private void addUserLocationButton() {
userLocationButton.show();
userLocationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mapboxMap.getLocationComponent().getLastKnownLocation() != null) {
Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(
new CameraPosition.Builder()
.target(new LatLng(lastKnownLocation.getLatitude(),
lastKnownLocation.getLongitude()))
.zoom(17.5)
.build()
),1400);
} else {
Toast.makeText(PlacePickerActivity.this,
getString(R.string.mapbox_plugins_place_picker_user_location_not_found), Toast.LENGTH_SHORT).show();
}
}
});
}

void placeSelected() {
Intent returningIntent = new Intent();
if (includeReverseGeocode) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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="#606060"
android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>
Loading