I try to use new simplified Location APIs on Android (introduced in GPS 11.0). I wrote a Service that implements location APIs. But it only triggers and send location for a few seconds (only 2 times).
public class LocationService extends Service {
public static final String TAG = makeLogTag("LocationService");
private static final float LOCATION_TRACKING_MIN_DISTANCE = 15f;
private static final float ACCEPTED_ACCURACY = 50f;
private final IBinder mBinder = new LocalBinder();
// fused location api
private FusedLocationProviderClient mFusedLocationClient;
private LocationRequest mLocationRequest;
private LocationCallback mLocationCallback;
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
createLocationCallback();
createLocationRequest();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
stopSelf();
return START_NOT_STICKY;
}
getLastKnownLocation();
startPeriodicLocationUpdate();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
stopPeriodicLocationUpdate();
Log.i(TAG, "onDestroy - Estou sendo destruido ");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private void getLastKnownLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(task -> {
if (task.isSuccessful() && task.getResult() != null) {
Location lastLocation = task.getResult();
storeLocation(lastLocation);
}
});
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest()
.setInterval(TimeUnit.SECONDS.toMillis(Params.getAgentLocationTrackingUpdateInterval()))
.setFastestInterval(TimeUnit.SECONDS.toMillis(Params.getAgentLocationTrackingUpdateInterval()))
.setExpirationDuration(TimeUnit.SECONDS.toMillis(10))
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void createLocationCallback() {
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Location location = locationResult.getLastLocation();
if (location != null) {
storeLocation(location);
}
Log.i(TAG, "locationResult start");
for (Location location1 : locationResult.getLocations()) {
Log.i(TAG, "locationResult location " + location1.getLatitude() + " " + location1.getLongitude() + " " + location1.getAccuracy() + " " + location1.getProvider());
}
Log.i(TAG, "locationResult stop");
}
};
}
private void startPeriodicLocationUpdate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Log.i(TAG, "periodic update");
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
}
private void stopPeriodicLocationUpdate() {
mFusedLocationClient.removeLocationUpdates(mLocationCallback)
.addOnCompleteListener(task -> LOGI(TAG, "removed location updates!"));
}
private void storeLocation(Location location) {
Log.i(TAG, "periodic location " + location.getLatitude() + " " + location.getLongitude() + " " + location.getAccuracy() + " " + location.getProvider());
if (location.getAccuracy() <= ACCEPTED_ACCURACY) {
Log.i(TAG, "storeLocation: " + "saved!");
AgentLocationVo agentLocation = new AgentLocationVo();
agentLocation.setDate(DateHelper.getDate(location.getTime()));
agentLocation.setLatitude(location.getLatitude());
agentLocation.setLongitude(location.getLongitude());
agentLocation.setAccuracy(location.getAccuracy());
agentLocation.setSyncState(SyncState.NOTUPLOADED);
if (!AgentLocationDao.isAgentLocationExist(agentLocation))
AgentLocationDao.insert(agentLocation);
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Log.i(TAG, "onTaskRemoved: ");
stopSelf();
JobDispatcher.stopSendLocationJob(getApplicationContext()); // TODO: 04/07/17 not the best place for it
}
public static void start(Context context) {
context.startService(new Intent(context, LocationService.class));
}
public static void stop(Context context) {
context.stopService(new Intent(context, LocationService.class));
}
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
public LocationService getService() {
// Return this instance of LocationService so clients can call public methods
return LocationService.this;
}
}
}
Here are the resource that I used to create the service: https://android-developers.googleblog.com/2017/06/reduce-friction-with-new-location-apis.html
https://github.com/googlesamples/android-play-location/blob/master/LocationUpdates/app/src/main/java/com/google/android/gms/location/sample/locationupdates/MainActivity.java
https://blog.stylingandroid.com/locationservices/
I have even tried using version of method with Pending intent, but get the same result. Even when app is in foreground.
The reason is this line
.setExpirationDuration(TimeUnit.SECONDS.toMillis(10))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With