How to smoothly move and rotate a marker in google map
Posted By : Akash Tomer | 26-Dec-2017
This tutorial basically deals with the smooth movement and rotation of marker in google map. Lot's of developers face problem when they develop shuttle type of application where they have to show the live tracking of the vehicle . Even when I develop such type of app, I also face this problem. So this tutorial will definitely help you to overcome this problem. First of all, you should have the good knowledge of google map and Fused location provider API. In this tutorial, I will on discuss only about the fused location API .
What is fused location provider api .
Basically if we want to fetch the location of any android user we explicitly choose either GPS or Network Location Provider .But this api automatically switches itself to provide the best possible location of android user either through GPS or Network Location Provider.The main benefit of this provider it utilizes low power and provides high accuracy of over other options.
Gradle
Add this dependecy in your build gradle .
com. google. android. gms:play-services-location:11. 8. 0
Android Manifest
To access location we have to request access fine location and access coarse location in your android manifest file .
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
GoogleApiClient
It requries the google api client object . So we have to instantiate the object
googleApiClient = new GoogleApiClient.Builder(locationActivity)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Instialization of this object should be done in onCreate() methode of activity. When the google api client get connected it's onConnected method will called and when the connection is break it's on disconnected method is called . When the google api onConnected() method is called we have to register location listener . Below there is a complete code of location tracking .
public class LocationActivity extends BaseActivity implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, Constants, OnUpdateResponse {
private static final int REQUEST_CHECK_SETTINGS = 25;
private boolean PRE_ALERT_FLAG =true ;
private GoogleMap mMap;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mCurrentLocation;
private static final String TAG = "MapsActivity";
private static final long INTERVAL = 1;
private static final long FASTEST_INTERVAL = 1;
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
public void onStart() {
super.onStart();
Log.e(TAG, "onStart fired ..............");
mGoogleApiClient.connect();
}
@Override
public void onStop() {
super.onStop();
Log.e(TAG, "onStop fired ..............");
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.e(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.e(TAG, "Location update started ..............: ");
}
@Override
public void onConnectionSuspended(int i) {
if (i == 1) {
mGoogleApiClient.connect();
}
}
@Override
public void onLocationChanged(Location location) {
//Toast.makeText(HopOffActivity.this,"Firing onLocationChanged",
moveVechile(currentMArkerPos, location);
rotateMarker(currentMArkerPos, location.getBearing(), start_rotation);
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
mGoogleApiClient.connect();
}
@Override
protected void onPause() {
super.onPause();
Log.e(TAG, "On Pause call...............................");
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.e(TAG, "Location update stopped .......................");
}
@Override
public void onResume() {
super.onResume();
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
}
}
public void moveVechile(final Marker myMarker, final Location finalPosition) {
final LatLng startPosition = myMarker.getPosition();
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final Interpolator interpolator = new AccelerateDecelerateInterpolator();
final float durationInMs = 3000;
final boolean hideMarker = false;
handler.post(new Runnable() {
long elapsed;
float t;
float v;
@Override
public void run() {
// Calculate progress using interpolator
elapsed = SystemClock.uptimeMillis() - start;
t = elapsed / durationInMs;
v = interpolator.getInterpolation(t);
LatLng currentPosition = new LatLng(
startPosition.latitude * (1 - t) + (finalPosition.getLatitude()) * t,
startPosition.longitude * (1 - t) + (finalPosition.getLongitude()) * t);
myMarker.setPosition(currentPosition);
// myMarker.setRotation(finalPosition.getBearing());
// Repeat till progress is completeelse
if (t < 1) {
// Post again 16ms later.
handler.postDelayed(this, 16);
// handler.postDelayed(this, 100);
} else {
if (hideMarker) {
myMarker.setVisible(false);
} else {
myMarker.setVisible(true);
}
}
}
});
}
public void rotateMarker(final Marker marker, final float toRotation, final float st) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = st;
final long duration = 1555;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
@Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
float rot = t * toRotation + (1 - t) * startRotation;
marker.setRotation(-rot > 180 ? rot / 2 : rot);
start_rotation = -rot > 180 ? rot / 2 : rot;
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
}
public void makeMarker(int color, String title, LatLng latLng) {
mMap.addMarker(new MarkerOptions()
.icon((BitmapDescriptorFactory
.fromResource(color)))
.title(title)
.position(latLng));
}
}
In onlcationchange() method you have to provide the marker position. For this you have to ovveride the onMapReady() method of google map api and create the instances. There is a method makeMarker() you just need to call from onMapReady() method . There is two method rotateMarker() and moveVechile() to rotate and move marker.
Hope this will help you.
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Akash Tomer
Akash is an Android Developer at Oodles Technology.