FusedLocationApi con PendingIntent para actualizaciones de ubicación de fondo. No se pueden recibir actualizaciones
El código fuente de la muestra de google era fácil de implementar actualizaciones de ubicación continua en el frontend, pero todavía no puedo obtener o entender claramente cómo funcionan las actualizaciones de ubicación de fondo utilizando FusedLocationApi y PendingIntent.
LocationService clase:
- Cómo guardar persistentemente PendingIntent proporcionado por otra aplicación
- Cómo quitar la notificación de la barra de notificación mediante programación en android?
- AlarmManager activa PendingIntent demasiado pronto
- Crea un nuevo intento pendiente cada vez en Android
- ¿Es necesario usar FLAG_ACTIVITY_NEW_TASK en la opción PendingIntent de una notificación?
`Public class LocationService extends IntentService {private estático 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); } }
Todos los derechos reservados
MainActivity El código parece desordenado así que compartiré el código en un acoplamiento de la impulsión: https://drive.google.com/open?id=0B7QMYFlbkUpOVjkxMUtfenRLXzA
Sin embargo, he seguido el ejemplo de https://gist.githubusercontent.com/allenchi/c9659369c306752c0047/raw/16d6cd8e311013379e55b496d2b6d13347f418d6/gistfile1.txt
La siguiente parte del ejemplo es lo que simplemente no puedo entender la colocación en MainActivity. ¿Cómo recibo las actualizaciones de la ubicación mediante el receptor Broadcast? También necesitaría una comprensión limpia de FusedLocation que funciona en fondo y cómo puedo utilizar para conseguir un en el gps perseguidor de la mosca puesto en práctica.
`@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 } } };`
- ¿Puede un receptor de difusión captar múltiples transmisiones?
- Cómo detener una alarma en android
- ¿Cómo enviar datos a través de PendingIntent a Broadcast?
- Android: Inicie el servicio con Context.startService vs PendingIntent.getService
- ¿En qué se utiliza "requestCode" en PendingIntent?
- Android PendingIntent te lleva a una actividad ya existente?
- PendingIntent programado utilizando el tipo AlarmManager.RTC todavía se invoca en el modo de suspensión
- ¿Cómo utilizar PendingIntent para comunicarse desde un servicio a un cliente / actividad?
En el ejemplo siguiente, puede recibir las actualizaciones de ubicación cuando la aplicación se ejecuta en segundo plano cada 5 segundos utilizando el modo PRIORITY_HIGH_ACCURACY. Verá estas actualizaciones recibiendo notificaciones que indican las coordenadas de su ubicación.
También quería probar si las actualizaciones pueden ser recibidas después de que la aplicación ha sido eliminada por el sistema como se indica aquí :
Public abstract PendingResult requestLocationUpdates (cliente GoogleApiClient, solicitud LocationRequest, PendingIntent callbackIntent)
Este método es adecuado para los casos de uso de fondo, más específicamente para recibir actualizaciones de ubicación, incluso cuando la aplicación ha sido eliminada por el sistema . Para ello, utilice un PendingIntent para un servicio iniciado.
Es por eso que he llamado System.exit (0) en el método onBackPressed () de la actividad, que por supuesto se puede omitir.
El servicio:
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's 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()); } }
}
La actividad:
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); }
}
El permiso en el manifiesto:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
- ¿Qué sucede exactamente cuando se quita una tarea de los últimos?
- Detección de movimiento significativo del dispositivo en Android