Reputation: 49
I am working on a vehicle tracking application, and im trying to get the moving animation of the car smooth, with no "jumps" and a continous movement of the map with the current location. GPS location is provided every second, which is obviously not sufficient for smooth experience. Ive figured I could interpolate between the last two given locations and update the marker location and move the map every 16ms to create a transition in 60fps from each given location which would result in a smooth movement. The problem is that this is unbareably battery consuming, taking in an emulator 70% of the pc cpu. i've trying changing it to 20 and even 10 fps but no big difference. Waze application provides exactly what I aim for while taking 30 - 40% cpu any ideas how to achive this without overwhelming the phone? this is my current code that takes alot of cpu :
if(fusedLocationClient != null && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
{
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
Location location = locationResult.getLastLocation();
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
if(mLastLocation == null)
{
mLastLocation = latLng;
mCurrLocationMarker = Helper.setCustomMarker(MapsActivity.this, latLng, mMap);
locationUpdater = new LocationUpdater(mMap, MapsActivity.this, mCurrLocationMarker);
}
mCurrLocationMarker.setRotation(calculateBearing(mLastLocation, latLng));
//mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,18), ANIMATION_TIME, null);
animateMarker(mLastLocation, latLng);
mLastLocation = latLng;
//move map camera
}
};
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(ANIMATION_TIME);
locationRequest.setFastestInterval(ANIMATION_TIME/2);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
public void animateMarker(final LatLng startPosition, final LatLng toPosition) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long duration = ANIMATION_TIME;
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);
double lng = t * toPosition.longitude + (1 - t)
* startPosition.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startPosition.latitude;
LatLng latLng = new LatLng(lat, lng);
mCurrLocationMarker.setPosition(latLng);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,18));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
}
}
});
}```
Upvotes: 0
Views: 67
Reputation: 1041
I have not attempted to achieve true real-time tracking with Android devices, but I have worked on an app where we have a configurable tracking option. I have found through testing that asking for GPS updates less frequently will certainly help battery life.
If you could sacrifice even a little of the real-time accuracy of your tracking, you might be able to use interpolation to make up the difference (I suspect this is what Google Maps and other apps do) and still get down to a more reasonable battery consumption level. The app I've worked with has user configurable values, but our default values seem to have pretty good results with regard to battery consumption:
new LocationRequest()
.setSmallestDisplacement(float) // Default: 1000f
.setInterval(int) // Default: 10
.setFastestInterval(int) // Default: 10
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
Upvotes: 0