I am trying to subscribe to location updates through Google FusedLocationProviderApi. I want to receive updates in the background to receive updates, even if the application is killed. Following the online documentation as far as I can, I wrote the following code. Note: this is done in the intent service, not in the user interface thread, so I use blocking connection / result methods.
private void startLocationServices(String deviceId, int pollingInterval) { Log.i(TAG, "Starting location services with interval: " + pollingInterval + "ms"); PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); wakeLock.acquire(); final GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .build(); ConnectionResult result = googleApiClient.blockingConnect(); if (!result.isSuccess() || !googleApiClient.isConnected()) { Log.e(TAG, "Failed to connect to Google Api"); wakeLock.release(); return; } LocationRequest locationRequest = new LocationRequest(); locationRequest.setInterval(pollingInterval); locationRequest.setFastestInterval(10000); locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); Intent locationIntent = new Intent(this, GeoBroadcastReceiver.class); locationIntent.putExtra(EXTRA_LOCATION_UPDATE_DEVICE_ID, deviceId); locationIntent.setAction(GeoBroadcastReceiver.ACTION_LOCATION_UPDATE); PendingIntent locationPendingIntent = PendingIntent.getBroadcast( this, 0, locationIntent, PendingIntent.FLAG_UPDATE_CURRENT); PendingResult pendingResult = LocationServices.FusedLocationApi .requestLocationUpdates(googleApiClient, locationRequest, locationPendingIntent); Result requestResult = pendingResult.await(); Status requestStatus = requestResult.getStatus(); if (requestStatus.isSuccess()) { Log.i(TAG, "Successfully subscribed to location updates."); } else { Log.e(TAG, String.format( "Failed subscribe to location updates. Error code: %d, Message: %s.", requestStatus.getStatusCode(), requestStatus.getStatusMessage())); } googleApiClient.disconnect(); wakeLock.release(); }
When I run this, I see that requestStatus.isSuccess() returns true, indicating that I have successfully subscribed to location updates. In addition, the GeoBroadcastReciever , which extends the WakefulBroadcastReceiver , gets the intent in the right polling interval with the right action. Good bye, it would seem. Here is what I do in the onReceive method for GeoBroadcastReceiver :
if (LocationResult.hasResult(intent)) { LocationResult locationResult = LocationResult.extractResult(intent); Location location = locationResult.getLastLocation(); if (location != null) { GeoMonitoringService.wakefulLocationUpdate(context, location); } else { Log.e(TAG, "LocationResult does not contain a LastLocation."); } } else { Log.e(TAG, "Intent does not contain a LocationResult."); }
The problem is that whenever an intent occurs, it does not contain LocationResult and does not contain LocationAvailabilityResult . I checked the incoming intention in the debugger, and the only element for additional purposes is the additional one that I added when setting up the intent (device identifier). Thus, LocationResult.hasResult() returns false. Everytime.
I tried this on a Galaxy Note 4 running 4.0.1, and Nexus 4 with 5.1.1, with the same result.
If I turn off the location on the phone, I stop getting intentions at all, as expected.