FusedLocationApi with PendingIntent for background location updates. Failed to get updates.

The source code for the google sample was easy to implement constant location updates on the interface, but I still can't figure out or understand how background updates work using FusedLocationApi and PendingIntent.

LocationService Class:

public class LocationService extends IntentService { private static final String TAG = LocationService.class.getSimpleName(); private static final String ACTION_LOCATION_UPDATED = "location_updated"; private static final String ACTION_REQUEST_LOCATION = "request_location"; public static IntentFilter getLocationUpdatedIntentFilter() { return new IntentFilter(LocationService.ACTION_LOCATION_UPDATED); } public static void requestLocation(Context context) { Intent intent = new Intent(context, LocationService.class); intent.setAction(LocationService.ACTION_REQUEST_LOCATION); context.startService(intent); } public LocationService() { super(TAG); } @Override protected void onHandleIntent(Intent intent) { String action = intent != null ? intent.getAction() : null; if (ACTION_REQUEST_LOCATION.equals(action)) { onRequestLocation(); } else if(ACTION_LOCATION_UPDATED.equals(action)) { onLocationUpdated(intent); } } /** * Called when a location update is requested. We block until we get a result back. * We are using Fused Location Api. */ private void onRequestLocation() { Log.v(TAG, ACTION_REQUEST_LOCATION); GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .build(); // we block here ConnectionResult connectionResult = googleApiClient.blockingConnect(10, TimeUnit.SECONDS); if (connectionResult.isSuccess() && googleApiClient.isConnected()) { Intent locationUpdatedIntent = new Intent(this, LocationService.class); locationUpdatedIntent.setAction(ACTION_LOCATION_UPDATED); // Send last known location out first if available Location location = FusedLocationApi.getLastLocation(googleApiClient); if (location != null) { Intent lastLocationIntent = new Intent(locationUpdatedIntent); lastLocationIntent.putExtra( FusedLocationProviderApi.KEY_LOCATION_CHANGED, location); startService(lastLocationIntent); } // Request new location LocationRequest mLocationRequest = new LocationRequest() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); FusedLocationApi.requestLocationUpdates( googleApiClient, mLocationRequest, PendingIntent.getService(this, 0, locationUpdatedIntent, 0)); googleApiClient.disconnect(); } else { Log.e(TAG, String.format("Failed to connect to GoogleApiClient (error code = %d)", connectionResult.getErrorCode())); } } /** * Called when the location has been updated & broadcast the new location */ private void onLocationUpdated(Intent intent) { Log.v(TAG, ACTION_LOCATION_UPDATED); // Extra new location Location location = intent.getParcelableExtra(FusedLocationProviderApi.KEY_LOCATION_CHANGED); if (location != null) { LatLng latLngLocation = new LatLng(location.getLatitude(), location.getLongitude()); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } } } 

MainActivity The code looks messy, so I will share the code in the drive link: https://drive.google.com/open?id=0B7QMYFlbkUpOVjkxMUtfenRLXzA

However, I followed the example from https://gist.githubusercontent.com/allenchi/c9659369c306752c0047/raw/16d6cd8e311013379e55b496d2b6d13347f418d6/gistfile1.txt

The next part in the example is that I just cannot understand the placement in MainActivity. How to get location updates using a broadcast receiver? I would also need a clean understanding of how FusedLocation works in the background and how I can use it to get a built-in gps tracker.

 @Override protected void onResume() { super.onResume(); if(checkPlayServices()) { LocationService.requestLocation(this); LocalBroadcastManager.getInstance(getActivity()) .registerReceiver(locationReceiver, LocationService.getLocationUpdatedIntentFilter()); } } @Override public void onResume() { super.onResume(); LocalBroadcastManager.getInstance(getActivity()).registerReceiver( locationReceiver, LocationService.getLocationUpdatedIntentFilter()); } @Override public void onPause() { super.onPause(); LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(locationReceiver); } private BroadcastReceiver locationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Location location = intent.getParcelableExtra(FusedLocationProviderApi.KEY_LOCATION_CHANGED); if (location != null) { LatLng latestLocation = new LatLng(location.getLatitude(), location.getLongitude()); // do something with the location } } }; 
+5
source share
1 answer

In the example below, you can receive location updates when the application runs in the background every 5 seconds using PRIORITY_HIGH_ACCURACY mode. You will see these updates when you receive notifications of your location coordinates.

I also wanted to check if updates could be received after the application was killed by the system, as indicated here :

public abstract PendingResult requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callback)

This method is suitable for use in the background, especially for receiving location updates , even when the application has been killed by the system . To do this, use PendingIntent for the running service.

therefore, I called System.exit (0) in the onBackPressed () Method of Activity, which of course you can skip.

Service:

 public class LocationService extends IntentService{ private static final String INTENT_SERVICE_NAME = LocationService.class.getName(); public LocationService() { super(INTENT_SERVICE_NAME); } @Override protected void onHandleIntent(Intent intent) { if (null == intent) { return; } Bundle bundle = intent.getExtras(); if (null == bundle) { return; } Location location = bundle.getParcelable("com.google.android.location.LOCATION"); if (null == location) { return; } if (null != location) { // TODO: Handle the incoming location Log.i(INTENT_SERVICE_NAME, "onHandleIntent " + location.getLatitude() + ", " + location.getLongitude()); // Just show a notification with the location coordinates NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder notification = new NotificationCompat.Builder(this); notification.setContentTitle("Location"); notification.setContentText(location.getLatitude() + ", " + location.getLongitude()); notification.setSmallIcon(R.drawable.ic_audiotrack); notificationManager.notify(1234, notification.build()); } } 

}

Activity:

 public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{ private GoogleApiClient googleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); googleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); } @Override public void onStart() { super.onStart(); googleApiClient.connect(); } @Override public void onStop() { super.onStop(); if (googleApiClient.isConnected()) { googleApiClient.disconnect(); } } @Override public void onBackPressed() { // Check whether you receive location updates after the app has been killed by the system System.exit(0); } @Override public void onConnected(Bundle bundle) { requestLocationUpdates(); } @Override public void onConnectionSuspended(int cause) { googleApiClient.connect(); } @Override public void onConnectionFailed(ConnectionResult result) { } public void requestLocationUpdates() { LocationRequest locationRequest = new LocationRequest() .setInterval(5 * 1000) .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); Intent intent = new Intent(this, LocationService.class); PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, pendingIntent); } 

}

Resolution in manifest:

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
+4
source

Source: https://habr.com/ru/post/1236050/


All Articles