I have a Service that tracks the location of user, in a time I get the location of user though of GoogleApiClient.
It Happen some times Service stop, depend of internet or model phone the Service stop sending location to webservice. It seems like it was destroyed.
How can I prevent this?
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "LocationService";
public long UPDATE_MILLISECONDS_DEFAULT = 180000;
private boolean currentlyProcessingLocation = false;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
#Override
public void onCreate() {
Log.d(TAG,"Location service create");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// if we are currently trying to get a location and the alarm manager has called this again,
// no need to start processing a new location.
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
startTracking();
}
return START_NOT_STICKY;
}
private void startTracking() {
Log.d(TAG, "startTracking");
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
protected void sendLocationToServer(Location location) {
// here I call my webservice and send location
Log.d(TAG, "Update to Server location");
}
#Override
public void onDestroy() {
Log.d(TAG,"Destroy service");
stopLocationUpdates();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
sendLocationToServer(location);
}
public void stopLocationUpdates() {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
/**
* Called by Location Services when the request to connect the
* client finishes successfully. At this point, you can
* request the current location or start periodic updates
*/
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
locationRequest = LocationRequest.create();
locationRequest.setInterval(UPDATE_MILLISECONDS_DEFAULT); // milliseconds for default
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates
LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, locationRequest, this);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
stopLocationUpdates();
stopSelf();
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection has been suspend");
}
}
You're returning START_NOT_STICKY from onStartCommand().
Because of this, whenever the OS kills your Service (to reclaim memory, for example) it will not get re-created.
Change the following line:
return START_NOT_STICKY;
To this:
return START_STICKY;
From the documentation of START_STICKY:
Constant to return from onStartCommand(Intent, int, int): if this
service's process is killed while it is started (after returning from
onStartCommand(Intent, int, int)), then leave it in the started state
but don't retain this delivered intent. Later the system will try to
re-create the service. Because it is in the started state, it will
guarantee to call onStartCommand(Intent, int, int) after creating the
new service instance; if there are not any pending start commands to
be delivered to the service, it will be called with a null intent
object, so you must take care to check for this.
NOTE: START_STICKY does not prevent your Service from being killed. It just tells the OS to restart it as soon as possible (depending on the available resources). To make your Service less likely to be killed, you can
make it run in the foreground by calling startForeground().
you simply need to change this line of code
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// if we are currently trying to get a location and the alarm manager has called this again,
// no need to start processing a new location.
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
startTracking();
}
return START_STICKY;
}
Related
I am working on application which requires to fetch location updates continuously in background service. I have used background sticky service with which it is working. But service is not starting after boot complete even though I have added boot broadcast and have started the service there. Service starts and immediately gets killed.
Also, this is not working on Oreo. Service stops after few minutes of application gets closed and never restarts till app is relaunched.
I have gone through lot of links, blogs which suggest to use AlarmManager/JobScheduler/JobIntentService but didn't get satisfactory solution.
So please suggest the working strategy/solution that can be used to continuously fetch location in background even after boot and should work on Oreo.
Using notification, you can make your service alive. It works up to android 8.1.
Below is code for background service
Note:
1) Use startForegroundService for above Build.VERSION_CODES.O
2) Use targetSdkVersion 25
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
mainActivity.startService(new Intent(getContext(), GpsServices.class));
} else {
mainActivity.startForegroundService(new Intent(getContext(), GpsServices.class));
}
BackgroundGpsServices Class
public class BackgroundGpsServices extends Service implements LocationListener {
private LocationManager mLocationManager;
public final long UPDATE_INTERVAL = 500; /* 0.5 sec */
public static final int NOTIFICATION_ID = 200;
#Override
public void onCreate() {
sendNotification(this, false);
startLocationUpdates();
}
private void startLocationUpdates() {
if (!isLocationUpdateRunning) {
isLocationUpdateRunning = true;
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mLocationManager != null) {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, UPDATE_INTERVAL, 0, this);
}
}
}
#Override
public void onLocationChanged(Location location) {
sendNotification(BackgroundGpsServices.this, true);
System.out.println("onLocationChanged ----- location=" + location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
public static void sendNotification(Service service, boolean isUpdate) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(service, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(service, 0, intent, PendingIntent.FLAG_NO_CREATE);
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(service)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("INFO_NOTIFICATION_TITLE")
.setOngoing(true)
.setAutoCancel(false)
.setContentText("INFO_NOTIFICATION_MESSAGE")
.setContentIntent(pendingIntent);
Notification notification = mNotifyBuilder.build();
if (isUpdate) {
NotificationManager notificationManager = (NotificationManager) service.getSystemService(NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.notify(NOTIFICATION_ID, notification);
}
} else {
service.startForeground(NOTIFICATION_ID, notification);
}
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
/* Remove the locationlistener updates when Services is stopped */
#Override
public void onDestroy() {
try {
stopLocationUpdates();
stopForeground(true);
} catch (Exception e) {
e.printStackTrace();
}
}
private void stopLocationUpdates() {
isLocationUpdateRunning = false;
if (mLocationManager != null) {
mLocationManager.removeUpdates(this);
}
}
}
You can use fused location provider to get the location of the device at regular intervals. There is a direct approach to request periodic updates from the fused location provider. The accuracy of the location is determined by the providers, the location permissions you've requested, and the options you set in the location request.
Request location updates
Before requesting location updates, your app must connect to location services and make a location request. The lesson on Changing Location Settings shows you how to do this. Once a location request is in place you can start the regular updates by calling requestLocationUpdates().
Depending on the form of the request, the fused location provider
either invokes the LocationCallback.onLocationChanged() callback
method and passes it a list of Location objects, or issues a
PendingIntent that contains the location in its extended data. The
accuracy and frequency of the updates are affected by the location
permissions you've requested and the options you set in the location
request object.
This lesson shows you how to get the update using the LocationCallback
callback approach. Call requestLocationUpdates(), passing it your
instance of the LocationRequest object, and a LocationCallback. Define
a startLocationUpdates() method as shown in the following code sample:
#Override
protected void onResume() {
super.onResume();
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
private void startLocationUpdates() {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback,
null /* Looper */);
}
Read Official Documentation here for detailed description.
I am new to Xamarin development. I have created one background service which is used to track user location. It's working properly till the time application is running/open. As application is closed/destroyed, my background service stops working. I have already spent so much time to find out the reason behind this issue. But bad luck.
[Service]
public class LocationTrackingService : Service, GoogleApiClient.IConnectionCallbacks,
GoogleApiClient.IOnConnectionFailedListener, Android.Gms.Location.ILocationListener
{
protected const string TAG = "Attendance Frag";
protected const int REQUEST_CHECK_SETTINGS = 0x1;
public const long UPDATE_INTERVAL_IN_MILLISECONDS = 20 * 1000;
public const long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
protected const string KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
protected const string KEY_LOCATION = "location";
protected const string KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected LocationSettingsRequest mLocationSettingsRequest;
public override void OnCreate()
{
base.OnCreate();
BuildGoogleApiClient();
CreateLocationRequest();
Toast.MakeText(this, "OnCreate", ToastLength.Short).Show();
}
protected void BuildGoogleApiClient()
{
Log.Info("AttendanceFrag", "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(LocationServices.API)
.Build();
}
protected void CreateLocationRequest()
{
mLocationRequest = new LocationRequest();
mLocationRequest.SetInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.SetFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);
}
protected void BuildLocationSettingsRequest()
{
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.AddLocationRequest(mLocationRequest);
builder.SetAlwaysShow(true);
mLocationSettingsRequest = builder.Build();
}
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
base.OnStartCommand(intent, flags, startId);
if (mGoogleApiClient != null && !mGoogleApiClient.IsConnected)
mGoogleApiClient.Connect();
return StartCommandResult.Sticky;
}
protected async Task StartLocationUpdates()
{
await LocationServices.FusedLocationApi.RequestLocationUpdates(
mGoogleApiClient,
mLocationRequest,
this
);
}
protected async Task StopLocationUpdates()
{
await LocationServices.FusedLocationApi.RemoveLocationUpdates(
mGoogleApiClient,
this
);
}
public async void OnConnected(Bundle connectionHint)
{
Log.Info(TAG, "Connected to GoogleApiClient");
await StartLocationUpdates();
}
public void OnConnectionSuspended(int cause)
{
Log.Info(TAG, "Connection suspended");
}
public void OnConnectionFailed(Android.Gms.Common.ConnectionResult result)
{
Log.Info(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.ErrorCode);
}
public void OnLocationChanged(Location location)
{
Toast.MakeText(this, "OnLocationChanged", ToastLength.Short).Show();
}
public override async void OnDestroy()
{
base.OnDestroy();
Toast.MakeText(this, "OnDestroy", ToastLength.Short).Show();
if (mGoogleApiClient != null
&& mGoogleApiClient.IsConnected)
{
await StopLocationUpdates();
}
//Start GeoLocation Tracking Service again
Intent i = new Intent(this, typeof(RestartServiceReceiver));
i.SetAction(RestartServiceReceiver.START_TRACKING);
SendBroadcast(i);
}
}
Please, help me
Start your service in a private process like this
[Service(Name = "com.xamarin.TimestampService",
Process=":timestampservice_process",
Exported=true)]
more info on running service in process here.
you can also register it as foreground service in that way they won't be stop by android and will show up in notification bar
Sorry for the late answer but I think it can help others. I would like to make something clear for you that you are writing this service as a background service. Background service can not run for long. There are some limitation of background services in Android after Android 8.0 onwards. Android automatically kills background service of an app after some time.
See this https://developer.android.com/about/versions/oreo/background
If you want to run a service for a long time then make the service Foreground Service. Please follow https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/services/foreground-services for detailed knowledge of foreground service in Xamarin Forms.
i am making an android application. I want to stop location updates if the device is still and if it moves a distance of 300 or 400m then get it's location again. I don't want to check continuously for location updates and measure distance between previous location and current location because it consumes battery.
My Location service class code:
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
}
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
public void buildGoogleApiClient() {
createLocationRequest();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(500);
}
public void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
buildGoogleApiClient();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
// The service is no longer used and is being destroyed
stopLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
System.out.println("Latitude: " + location.getLatitude());
System.out.println("Longitude: " + location.getLongitude());
}
#Override
public void onConnected(#Nullable Bundle bundle) {
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
I am using locationRequest.setSmallestDisplacement(500) but it continuously receives location updates only the onLocationChanged method is not called if the distance between previous and current location is less than 500m e.g.
Should i use geofencing for this purpose?
What is the best possible way to achieve this using FusedLocationApi with minimum battery consumption?
There are a few things to note here:
When your device isn't moving, Location Services optimizes for battery and does not necessarily do expensive new location lookups. So, you don't really have to try to optimize for this yourself.
Consider passing a smaller value to LocationRequest#setSmallestDisplacement.
To optimize for battery, consider using batched location updates, where location is computed for you in at the interval described in LocationRequest#setInterval, but delivered to your device based on the value in LocationRequest#setMaxWaitTime. This greatly helps with battery.
Not part of your question, but I should note that I would structure the code for requesting and removing location updates a little differently. I would connect GoogleApiClient in onStart(), and disconnect it in onStop(). I would call requestLocationUpdates() in onResume() of in onConnected(), and call removeLocationUpdates() in onPause() or onStop(), but not as late as onDestroy().
I am working on a Location-App which should begin to track some statistic data based on longitude and latitude when the user presses a Button. All this stuff works very well but when it comes to lock the screen or put the app in the background the service does not work anymore !
I have read a lot about background services and Broadcast receivers but I don't know how to implement the Google API Location listener in a Service and where to implement this class in the MainActivity. Can anyone tell me with a short code example how to implement such a service or a link where this is explained ?
Use fuse location service and save updated location every time
public class LocationNotifyService extends Service implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
public static Location mCurrentLocation;
.............................
#Override
public void onCreate() {
//show error dialog if GoolglePlayServices not available
if (isGooglePlayServicesAvailable()) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(BACKGROUND_INTERVAL);
mLocationRequest.setFastestInterval(BACKGROUND_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//mLocationRequest.setSmallestDisplacement(10.0f); /* min dist for location change, here it is 10 meter */
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
//Check Google play is available or not
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
return ConnectionResult.SUCCESS == status;
}
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
protected void startLocationUpdates() {
try {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
} catch (IllegalStateException e) {}
}
#Override
public void onLocationChanged(Location location) {
//Save your location
}
............................
}
you can get current location onLocationChanged()
For more details check http://javapapers.com/android/android-location-fused-provider/ or follow official guide https://developer.android.com/training/location/index.html
Here is application that does something like you want:
https://github.com/sergstetsuk/CosyDVR/blob/master/src/es/esy/CosyDVR/CosyDVR.java
Main Activity starts on BackgroundVideoRecorder service.
Intent intent = new Intent(/*CosyDVR.this*/getApplicationContext(), BackgroundVideoRecorder.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
look at mConnection onServiceConnected,onServiceDisconnected.
Here is BackgroundVideoRecorder class:
https://github.com/sergstetsuk/CosyDVR/blob/master/src/es/esy/CosyDVR/BackgroundVideoRecorder.java
It implements LocationListener. So has onLocationChanged, onProviderDisabled, onProviderEnabled, onStatusChanged.
I am trying to create a route tracking app. it need to track location even if the app is in background. so i created a service and add code to this service. Following are my code. but there is one problem. I start the service from my main activity.
public void startTracking(View view) {
startService(new Intent(MainActivity.this, LocationIntentService.class));
}
public void stopTracking(View view) {
stopService(new Intent(MainActivity.this, LocationIntentService.class));
}
It start the service and locations are inserted to a local db. But i cant stop these service. When i stop service using above code it still track the location. How can i stop location update.
public class LocationIntentService extends IntentService implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = LocationIntentService.class.getSimpleName();
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
private static int DISPLACEMENT = 10;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
DBAdapter dbAdapter;
public LocationIntentService() {
super("LocationIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG, " ***** Service on handled");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.e(TAG, " ***** Service on connected");
startLocationUpdates();
openDB();
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, " ***** Service on suspended");
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "Location changed");
mLastLocation = location;
String latitude = String.valueOf(mLastLocation.getLatitude());
String longitude = String.valueOf(mLastLocation.getLongitude());
Log.e(TAG, " ##### Got new location"+ latitude+ longitude);
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
String timestamp = today.format("%Y-%m-%d %H:%M:%S");
dbAdapter.insertRow(latitude, longitude, timestamp);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ connectionResult.getErrorCode());
}
#Override
public void onDestroy() {
Log.e(TAG, "Service is Destroying...");
super.onDestroy();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
mGoogleApiClient.disconnect();
}
closeDB();
}
protected void stopLocationUpdates() {
Log.d(TAG, "Location update stoping...");
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
protected void startLocationUpdates() {
Log.d(TAG, "Location update starting...");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
private void openDB() {
dbAdapter = new DBAdapter(this);
dbAdapter.open();
}
private void closeDB() {
dbAdapter = new DBAdapter(this);
dbAdapter.close();
}
protected void createLocationRequest() {
Log.e(TAG, " ***** Creating location request");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
Log.e(TAG, " ***** Update google play service ");
return false;
}
}
}
The reason that it's not working for you is that you are using an IntentService, so calling stopService() will not cause onDestroy() to be called, presumably because it was already called after onHandleIntent() has completed. There is no need to ever call stopService() on an IntentService see here.
It looks like you should probably just use Service instead of IntentService. That way, when you call stopService(), it would call onDestroy() and unregister for location updates, as you expect.
The only other change you would need to make would be to override onStartCommand() instead of onHandleIntent().
You would have your class extend Service instead of IntentService, and then move your code to register for location updates to onStartCommand:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, " ***** Service on start command");
if (isGooglePlayServicesAvailable()) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
return Service.START_STICKY;
}
This way you can still call startService() and stopService(), and it should work as you are expecting.
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
call stopLocationUpdates() method in stopService()
When you stop your services. Then called this line in LocationIntentService.class.
locationManager.removeUpdates(this);