Tracking / Follow me
Contents
Track a vehicle or other assets on the map.
activity_sample_follow_me.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent">
<com.trimblemaps.mapsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:visibility="invisible"
android:onClick="onButtonRecenterClick"
android:id="@+id/btn_recenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center"
android:text="Recenter" />
</com.trimblemaps.mapsdk.maps.MapView>
</FrameLayout>
SampleFollowMeActivity.java
public class SampleFollowMeActivity extends AppCompatActivity implements OnMapReadyCallback, LocationEngineCallback<LocationEngineResult>, TrimbleMapsMap.OnMoveListener {
private static final long DEFAULT_INTERVAL_IN_MILLISECONDS = 900L;
private static final long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 5;
private static final int ANIMATION_TIME = 400;
private MapView mapView;
private TrimbleMapsMap map;
private LocationComponent locationComponent;
private LocationEngine locationEngine;
private Button recenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Authorize the api key for the session.
// .apiKey() requires your Trimble Maps API key
TrimbleMapsAccount trimbleMapsAccount = TrimbleMapsAccount.builder()
.apiKey(getString(R.string.API_KEY))
.addLicensedFeature(LicensedFeature.MAPS_SDK)
.build();
// Initialize the session
TrimbleMapsAccountManager.initialize(trimbleMapsAccount);
TrimbleMapsAccountManager.awaitInitialization();
// Get an instance of the map, done before the layout is set.
TrimbleMaps.getInstance(this);
setContentView(R.layout.activity_sample_follow_me);
// Find the recenter button
recenter = (Button) findViewById(R.id.btn_recenter);
// Set up the MapView from the layout
mapView = (MapView) findViewById(R.id.mapView);
// Implementing OnMapReadyCallback into the activity
mapView.getMapAsync(this);
}
@Override
public void onMapReady(TrimbleMapsMap trimbleMapsMap) {
// The TrimbleMapsMap object is created, now a style can be applied to render a map.
map = trimbleMapsMap;
map.addOnMoveListener(this);
map.setStyle(Style.MOBILE_DEFAULT, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Not setting the start location here, as that will be tracked by the user's
// location. Instead, just defining the initial zoom.
map.setCameraPosition(new CameraPosition.Builder().zoom(15).build());
setupLocationComponent();
}
});
;
}
// Before a user's location can be used, location permissions will need to
// be given to the app. This code assumes those permissions have already been granted by this
// point. For more information on how to grant location permissions to your app,
// see: https://developer.android.com/training/location/permissions
@SuppressLint("MissingPermission")
public void setupLocationComponent() {
// Create the location component
locationComponent = map.getLocationComponent();
// Set the style to attach it to, in this case the current style on the map
locationComponent.activateLocationComponent(LocationComponentActivationOptions.builder(this, map.getStyle()).build());
// Turn it on
locationComponent.setLocationComponentEnabled(true);
// Set the tracking and render modes
// Tracking with the compass allows bearing to rotate the map as needed.
locationComponent.setCameraMode(CameraMode.TRACKING_COMPASS);
locationComponent.setRenderMode(RenderMode.COMPASS);
// Set the location engine
locationEngine = LocationEngineProvider.getBestLocationEngine(this);
startTracking();
}
@SuppressLint("MissingPermission")
public void startTracking() {
// Create the location engine request to track any changes to a user's location.
LocationEngineRequest locationEngineRequest = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setMaxWaitTime(DEFAULT_MAX_WAIT_TIME)
.build();
// Start listening for changes to location, then fire the callback with the result
locationEngine.requestLocationUpdates(locationEngineRequest, this, getMainLooper());
// Start with the last current location
locationEngine.getLastLocation(this);
}
@Override
public void onSuccess(LocationEngineResult result) {
// We have a successful callback, check the location isn't null and update as needed.
Location currentLocation = result.getLastLocation();
if(currentLocation != null) {
LocationUpdate locationUpdate = new LocationUpdate.Builder()
.location((result.getLastLocation())) // Set the location from the result
.animationDuration(Long.valueOf(ANIMATION_TIME))
.build();
map.getLocationComponent().forceLocationUpdate(locationUpdate);
}
}
@SuppressLint("MissingPermission")
public void onButtonRecenterClick(View view) {
// When Recenter is tapped, use the tracking mode
locationComponent.setCameraMode(CameraMode.TRACKING_COMPASS);
// Force an update
locationEngine.getLastLocation(this);
// Hide the button
recenter.setVisibility(View.INVISIBLE);
}
@Override
public void onFailure(Exception exception) {
// The request failed
}
@Override
public void onMoveBegin(MoveGestureDetector moveGestureDetector) {
// when the user begins to move the map
// Display the recenter button since panning has happened
recenter.setVisibility(View.VISIBLE);
}
@Override
public void onMove(MoveGestureDetector moveGestureDetector) {
// the user is moving the map
}
@Override
public void onMoveEnd(MoveGestureDetector moveGestureDetector) {
// the user has stopped moving the map
}
}