'How to move Google Map marker automatically as driver is moving
I'm trying to figure out how we can track driver position on Google map as he is moving.
Here's my code:
public class TrackDriverActivity extends AppCompatActivity implements OnMapReadyCallback {
GoogleMap mGoogleMap;
LatLng myPos, driverPos;
MarkerOptions myMarker, driverMarker;
Polyline directionLine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_track_rongsok_pickup);
// both LatLng (ours and driver) are initially hardcoded, for testing purpose
myPos = new LatLng(-6.25, 106.83);
driverPos = new LatLng(-6.27, 106.81);
myMarker = new MarkerOptions().position(myPos).title("You");
driverMarker = new MarkerOptions().position(driverPos).title("Driver");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map_track_driver);
mapFragment.getMapAsync(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver(driverPositionReceiver, new IntentFilter("DriverPosition"));
}
@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this).unregisterReceiver(driverPositionReceiver);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
// Every 5 seconds, driver broadcasts his current position to us via FCM
private BroadcastReceiver driverPositionReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
DecimalFormat df = new DecimalFormat("0.00");
double driverLat = Double.parseDouble(intent.getStringExtra("driver_lat"));
double driverLon = Double.parseDouble(intent.getStringExtra("driver_lon"));
Log.i("NEW_DRIVER_POSITION", "("+driverLat+","+driverLon+")");
new Thread()
{
public void run()
{
TrackDriverActivity.this.runOnUiThread(new Runnable()
{
public void run()
{
driverPos = new LatLng(driverLat, driverLon);
requestRoute();
}
});
}
}.start();
}
};
private void updateLineDestination(String json) {
Directions directions = new Directions(TrackDriverActivity.this);
try {
List<Route> routes = directions.parse(json);
if (directionLine != null) directionLine.remove();
if (routes.size() > 0) {
directionLine = mGoogleMap.addPolyline((new PolylineOptions())
.addAll(routes.get(0).getOverviewPolyLine())
.color(ContextCompat.getColor(TrackRongsokPickupActivity.this, R.color.colorgradient))
.width(8));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private okhttp3.Callback updateRouteCallback = new okhttp3.Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()){
String json = Objects.requireNonNull(response.body()).string();
long distance = MapDirectionAPI.getDistance(getApplicationContext(), json);
if (distance >= 0){
TrackDriverActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
updateLineDestination(json);
}
});
}
}
}
};
private void requestRoute() {
if (customerPos != null && merchantPos != null) {
MapDirectionAPI.getDirection(customerPos, merchantPos).enqueue(updateRouteCallback);
}
}
@Override
public void onMapReady(GoogleMap gmap) {
mGoogleMap = gmap;
mGoogleMap.addMarker(myMarker);
mGoogleMap.addMarker(driverMarker);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(driverMarker, 15.0f));
requestRoute();
}
}
Directions is our class that implements Directions API (https://developers.google.com/maps/documentation/directions/overview), which do stuffs like decoding polylines into list of LatLng, parsing JSON route format, etc.
MapDirectionAPI is our class which complements Directions, e.g for retrieving the route between 2 LatLngs, geocoding, etc.
When running the code:
- Both markers are displayed on their initial positions correctly
- A route line between us and driver is drawn correctly (initial position)
- As the driver is moving, his location change can be seen in logcat
The problem is his marker is still stuck at the starting position. How to fix this?
Solution 1:[1]
Changing the value of driverPos
will NOT move the marker that was created with its previous value. You need to move driverMarker
in updateLineDestination
. Add
driverMarker.setPosition( driverPos );
after
directionLine = mGoogleMap.addPolyline(...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | KaHa6uc |