androidintentservicewakelocklocationlistenerandroid-wake-lock

how to stop a Location listener service? (not stopping now)


I am using a Location listener service to update the current location of the user for every few secs. I have also used a WakeLock to make the listener work in the background. Now everything is working fine but i am unable to stop the Location listener. Even if the app is force closed the listener is updating the user location to the DB.

Location Listener:

 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.location.Location;
 import android.location.LocationManager;
 import android.os.Bundle;
 import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.maps.model.LatLng;

public class MyLocationService extends Service {
private static final String TAG = "MyLocationService";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 3000;
private static final float LOCATION_DISTANCE = 0f;
Context context = this;
PowerManager.WakeLock wakeLock;
public int e=0;

LocationListener[] mLocationListeners = new LocationListener[]{
        new LocationListener(LocationManager.GPS_PROVIDER),
        new LocationListener(LocationManager.NETWORK_PROVIDER)
};

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.e(TAG, "onStartCommand");
    super.onStartCommand(intent, flags, startId);
    Toast.makeText(this, "MyService Started.", Toast.LENGTH_SHORT).show();
    return START_STICKY;
}

@Override
public void onCreate() {
    Log.e(TAG, "onCreate");
    initializeLocationManager();
    PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    wakeLock= mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
    wakeLock.acquire();
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[1]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "fail to request location update, ignore", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "network provider does not exist, " + ex.getMessage());
    }
    try {
        mLocationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                mLocationListeners[0]);
    } catch (java.lang.SecurityException ex) {
        Log.i(TAG, "fail to request location update, ignore", ex);
    } catch (IllegalArgumentException ex) {
        Log.d(TAG, "gps provider does not exist " + ex.getMessage());
    }
}

@Override
public void onDestroy() {
    Log.e(TAG, "onDestroy");
    wakeLock.release();
    super.onDestroy();


    if (mLocationManager != null) {
        for (int i = 0; i < mLocationListeners.length; i++) {
            try {
                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;
                }
                mLocationManager.removeUpdates(mLocationListeners[i]);
            } catch (Exception ex) {
                Log.i(TAG, "fail to remove location listners, ignore", ex);
            }
        }
    }
}

private void initializeLocationManager() {
    Log.e(TAG, "initializeLocationManager");
    if (mLocationManager == null) {
        mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    }
}

// create LocationListener class to get location updates
private class LocationListener implements android.location.LocationListener
{
    Location mLastLocation;
    double latitude;
    double longitude;
    LatLng latLngcurrent;


    public LocationListener(String provider)
    {
        Log.e(TAG, "LocationListener " + provider);
        mLastLocation = new Location(provider);
    }

    @Override
    public void onLocationChanged(Location location)
    {
        Log.e(TAG, "onLocationChanged: " + location);
        mLastLocation.set(location);
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        Store.latu=latitude;
        Store.longu=longitude;
        latLngcurrent = new LatLng(location.getLatitude(), location.getLongitude());
        Toast.makeText(context,"Location " + String.valueOf(e), Toast.LENGTH_SHORT).show();
        e++;
        Toast.makeText(MyLocationService.this,Store.latu+" "+Store.longu, Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onProviderDisabled(String provider)
    {
        Log.e(TAG, "onProviderDisabled: " + provider);
    }

    @Override
    public void onProviderEnabled(String provider)
    {
        Log.e(TAG, "onProviderEnabled: " + provider);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)
    {
        Log.e(TAG, "onStatusChanged: " + provider);
    }
}
}

Starting the service intent:(from mainactivity)

   @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);


    Intent serviceIntent  = new Intent(context , MyLocationService.class);
    context.startService(serviceIntent  );



    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        checkLocationPermission();
    }
    if (!isGooglePlayServicesAvailable()) {
        finish();
    } else {
        Log.d("onCreate", "Google Play Services available.");
    }
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

Stopping the intent:(from mainactivity)

 private class LogOutTimerTask extends TimerTask
{
    @Override
    public void run()
    {
        Intent i = new Intent(MapsActivity.this, Login.class);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(i);
        Intent intent = new Intent(MapsActivity.this, MyLocationService.class);
        stopService(intent);
        finish();
    }
}

The stop intent is called when the user logout, now the onDestroy() method in the service class is getting called but its is not stopping the process. When the application is force closed the onDestroy() is not even called. In both the cases the process resumes and keep updating the values to DB.Thanks in advance.


Solution

  • Solution: I have finally found the solution for this. As @Yazan said i have removed the permissions from onDestroy() method, which helps the service to stop manually when the user logs out. And to stop the service when the app is force closed, In your manifest while using the tag add this line too.

    Snippet:

     <service android:name=".MyLocationService"
     android:stopWithTask="true"></service>
    

    stopWithTask will stop the service when we force close the application and the LocationListener will also stop.

    here is the documentation. After adding this my application works fine.