0

Below is my Location service class, it continue update the location if device changed location.

public class LocationService extends Service
        implements LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {
    private static final long INTERVAL = 1000 * 60;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    Location mLastLocation;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    String lat, lon;


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("", "********************** onStartCommand()");
        int permissionCheck = ContextCompat.checkSelfPermission(LocationService.this, Manifest.permission.ACCESS_FINE_LOCATION);

        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            //Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION..
            buildGoogleApiClient();
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d("", "********************** onBind()");
        return null;
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.d("", "********************** onConnected()");
//        Util.appendLog("Location Service onConnected()");
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            lat = String.valueOf(mLastLocation.getLatitude());
            lon = String.valueOf(mLastLocation.getLongitude());

            Util.WriteSharePrefrence(getApplicationContext(), "track_lat", "" + lat);
            Util.WriteSharePrefrence(getApplicationContext(), "track_lng", "" + lon);

            Util.appendLog("Location Service onConnected(): " + " Latitude: " + lat + " Longitude: " + lon);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Util.appendLog("Location Service onConnectionSuspended()");
    }

    synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d("", "********************** onLocationChanged()");
//        Util.appendLog("Location updated Latitude: " + location.getLatitude() + " longitude: " + location.getLongitude());
//        Toast.makeText(LocationService.this, "Latitude: " + location.getLatitude() + " Longitude: " + location.getLongitude(), Toast.LENGTH_SHORT).show();
        if (location != null) {
            Util.WriteSharePrefrence(getApplicationContext(), "track_lat", "" + location.getLatitude());
            Util.WriteSharePrefrence(getApplicationContext(), "track_lng", "" + location.getLongitude());
        }
//        stopSelf();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Util.appendLog("Location Service onConnectionFailed()");
        buildGoogleApiClient();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        Util.appendLog("Location servcie destroyed()");
    }
}

In Manifest i have declared this service as below:

<service
            android:name=".util.LocationService"
            android:enabled="true" />

I am starting this every time when user launch the app in his/her device

 if (!isMyServiceRunning(LocationService.class, context)) {
                    context.startService(new Intent(context, LocationService.class));
}

Note: I am not stopping service from anywhere.

Issues:

  1. Location update in all big brand devices Like google nexus 5, gionee, One+, Samsung....but in some device location not updating when internet or wifi not available like honor, xolo....
  2. Every time when device in outdoor or on driving onLocationChanged() method should be called and in WriteSharePrefrence() new updated latitude and longitude should be changed but it is not updating frequently in some of devices.
  3. Is there anything wrong in my service ? There is no battery draining matter in my app.
  4. Is there anything which is stopping my service ?
  5. How to continue running location update service in background and getting accurate location update from user device frequently ?
Himanshu
  • 861
  • 10
  • 25
  • is onDestroy getting called? If the device is getting low on RAM OS might kill your service. Try adding flag- Service.START_STICKY – X3Btel Jul 22 '16 at 11:11
  • @X3Btel onDestrye not calling. And what happened with Service.START_STICKY ? – Himanshu Jul 22 '16 at 11:15
  • Start sticky restarts the service if the system kills it. But if onDestroy is not getting called it should not help. Also does the other devices have gps turned on, with high accuracy? – X3Btel Jul 22 '16 at 11:24
  • yes, All devices has same code and logic. – Himanshu Jul 22 '16 at 11:51

1 Answers1

1

Google's Play Services API already handles this case cleanly.

Take a look at this: FusedLocationProviderApi requestLocationUpdates

You should be using the following function:

public abstract PendingResult<Status> requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callbackIntent)

The key highlight from the link:

This method is suited for the background use cases, more specifically for receiving location updates, even when the app has been killed by the system. For foreground use cases, the LocationListener version of the method is recommended...

Simply use the PendingIntent version of requestLocationUpdates, and you should start reliably receiving background location updates.

Ismail Khan
  • 842
  • 2
  • 8
  • 20