2

UPDATE: I'm getting this error, like it's explained in this questions (1 and 2), but according to this answer, this is only an internal log and shouldn't have impact on the functionality

V/GoogleSignatureVerifier: com.google.android.gms signature not valid

ORIGINAL QUESTION:

I have to implement different features related to the user location that have to work even if the app is killed. To achieve that, I'm using a service. I have issues when I try to track the user, because it seems that I have a problem requesting the location updates.

Here's the most relevant parts of my service:

DISCLAIMER: The code have been simplified for the reading sake. All the methods related to the service binding, along with several callbacks, have been removed because aren't part of the problem

public class LocationService extends RoboService implements LocationListener {

    private static final String TAG = "LocationService";
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = TimeUnit.SECONDS.toMillis(5);
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = TimeUnit.SECONDS.toMillis(1);
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

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

        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .build();

            mGoogleApiClient.connect();
        }

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_REDELIVER_INTENT;
    }

    public Location getCurrentLocation() {
        ConnectionResult connectionResult = mGoogleApiClient.blockingConnect();
        if (connectionResult.isSuccess()) {
            return LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        }
        return null;
    }

    public void startLocationUpdates() {
        ConnectionResult connectionResult = mGoogleApiClient.blockingConnect();
        if (connectionResult.isSuccess()) {
            Log.d(TAG, "startLocationUpdates: Posting request");
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            Log.d(TAG, "startLocationUpdates: Request posted");
        }
    }

    @Override
    public void onLocationChanged(Location newLocation) {
        System.out.println("LocationService.onLocationChanged");
    }
}

I'm using mGoogleApiClient.blockingConnect() because I can't use the connection callbacks due to architecture constrains, but I don't have any problems when I try to get the current location.

When I call startLocationUpdates() the execution seems to be lost when I request the location updates and neither Log.d(TAG, "startLocationUpdates: Request posted") nor onLocationChanged(Location newLocation) are ever called.

Here's the logcat:

05-23 11:42:47.509 13547-13547/com.example.location D/MapPresenterImpl: onRouteAdded: Starting route tracking
05-23 11:42:47.512 13547-13950/com.example.location D/LocationService: startLocationUpdates: Posting request
05-23 11:43:28.115 13547-13557/com.example.location W/art: Suspending all threads took: 7.530ms

My code is basically copied from the Android examples. I downloaded the example source code and I have it working correctly. The two only differences between my code and the example's is mine being inside a service and using mGoogleApiClient.blockingConnect(), but I don't know how this could affect in this way.

Someone have ever faced this kind of behaviour? I'm truly lost and I would preciate any help.

WORKAROUND:

At the end I solved this problem using PendingIntent instead of the Callback approach. I still would be glad to know why this happened, but if someone faces this problem and doesn't know how to proceed, here's my workaround.

Method to start the location updates:

public void startLocationTracking(long routeId) {
    ConnectionResult connectionResult = mGoogleApiClient.blockingConnect();
    if (connectionResult.isSuccess()) {
        Intent intent = new Intent(this, TrackingService.class);
        PendingIntent pi = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        LocationRequest request = new LocationRequest();
        request.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        request.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, pi);
    }
}

Tracking service:

public class TrackingService extends IntentService {

    public TrackingService() {
        super("TrackingService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            // Do whatever you need with the location
        }
    }
}

Using this method I faced another weird problem. If you put some extra in the Intent used to build the PendingIntent, when TrackingService is called there isn't any location in the Intent extras, only what was added when the Intent was created. My workaround for this was using the SharedPreferences to pass an id that I needed to have, but I'm not really convinced by this patch. This issue is discussed in this question.

Community
  • 1
  • 1
Jofre Mateu
  • 2,390
  • 15
  • 26
  • Can you post the logcat – akhil Rao May 23 '16 at 09:43
  • Sure, but I don't get any error, so it's not really useful – Jofre Mateu May 23 '16 at 09:44
  • Have you added the Access_fine_location and Access_coarse_location permission right – akhil Rao May 23 '16 at 09:45
  • Of course. As I clearly said, when I try to get the current location it's working flawlessly. Without the permissions I would get an error. – Jofre Mateu May 23 '16 at 09:48
  • did you find out that blockingConnect is responding with SUCCESS ? – Shvet May 23 '16 at 09:50
  • 1
    Now give it try by removing the mGoogleApiClient.connect(); in Oncreate() method – akhil Rao May 23 '16 at 09:51
  • You can see it's connecting successfully because the first log is printed in the logcat. – Jofre Mateu May 23 '16 at 09:52
  • In your code where did you call that method? I didnt find anything calling that method! (`startLocationUpdates()`), Call it after ` mLocationRequest.setPriority()`. – Shvet May 23 '16 at 09:54
  • @akhilRao there's no difference, as it should be according to the documentation – Jofre Mateu May 23 '16 at 09:55
  • @Shvet this method is called from outside the service, through a bind. The `setPriority()` method is called when the service is created, so it's always called before `startLocationUpdates()` – Jofre Mateu May 23 '16 at 09:58
  • Thing is when this method is called, `mLocationRequest` must not be null or `onCreate` of this service must be called else this statement will through nullpointerexecption. – Shvet May 23 '16 at 10:06
  • mLocationRequest is never null when it's used. When using a bound service, the method `onCreate()` is always called before the bind is returned in the `onBind()` method acording to the lifecycle https://developer.android.com/images/service_lifecycle.png – Jofre Mateu May 23 '16 at 10:23

0 Answers0