Ubicación Actualización en función del estado del dispositivo

Necesito conseguir la localización (por la API del fusedlocation) del usuario después de ActivityRecognition Detectar el estado del usuario (que llama cada 3 minutos), como IN_VEHICLE, ON_FOOT, RUNNING etc.

En cada evento necesito la ubicación del usuario después de un intervalo regular Por ejemplo:

Si el usuario sigue siendo entonces setInterval(5*60*60*1000); Y comprobar la actualización de la siguiente ubicación en no antes de 5 horas. Pero ActivityRecognation Llamará cada 3 min.

Si el usuario está ejecutando entonces setInterval(2*60*1000); Y compruebe para la localización siguiente de la localización en no antes / después de 2 minutos. Pero ActivityRecognation Llamará cada 3 min.

Si el usuario está en ejecución, envíe la ubicación cada 1 minuto si el usuario está conduciendo y luego envíe la ubicación cada 15 minutos.

Intenté establecer boolean false en onConnected en false y true en el nivel de clase. Pero siempre se convierten en verdad porque el servicio de Intención entera se llama después de 3 minutos.

 if (startLocationFirst){ requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); LocationAPIclient.connect();// RequestLocation and GoogleAPIClient won't call until device comes from another ActivityRecognation State running,walking etc. And keep Updating location every 5 hours. } 

Problema actual

  • ActivityRecognation Obtiene el estado de usuario cada 3 minutos, pero no debe entrar en startLocationFirst boolean hasta que viene de otro ActivityRecognation State y mantener la actualización de la ubicación como se establece dentro de startLocationFirst

Aquí está IntentService con FusedLocation

 public class Activity_Recognized_Service extends IntentService implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener { /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public static final String TAG = "###RECOGNISED SRVCE###"; Timer timer; GoogleApiClient LocationAPIclient; LocationRequest mLocationRequest; Location mCurrentLocation; boolean startLocationFirst=true; public Activity_Recognized_Service() { super("Activity_Recognized_Service"); } public Activity_Recognized_Service(String name) { super(name); } @Override protected void onHandleIntent(@Nullable Intent intent) { Log.d(TAG, "On Handle Intent"); if (ActivityRecognitionResult.hasResult(intent)) { Log.d(TAG, "ActivityRecognition Has Result"); ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); handleDetectedActivities(result.getProbableActivities()); Navigation_Drawer nav = new Navigation_Drawer(); nav.UserMovementResult(result); } } @Override public void onCreate() { super.onCreate(); Log.d(TAG,"On Create Calling"); if (LocationAPIclient == null) { Log.d(TAG, "Location API is NULL Value Of This "); LocationAPIclient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); } } private void handleDetectedActivities(List<DetectedActivity> probableActivities) { for (DetectedActivity activity : probableActivities) { switch (activity.getType()) { case DetectedActivity.IN_VEHICLE: Log.d(TAG, "In Vehicle " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("In Vehicle"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(10*60*1000,8*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); if (startLocationFirst){ Log.d(TAG,"Start Location Update For Car"); } } break; case DetectedActivity.ON_BICYCLE: Log.d(TAG, "On Bicycle " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("On Bicycle"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(7*60*1000,5*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.ON_FOOT: Log.d(TAG, "On Foot " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("On Foot"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); } break; case DetectedActivity.RUNNING: Log.d(TAG, "On Running " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Running"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.STILL: Log.d(TAG, "On Still " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Still"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds // requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.TILTING: Log.d(TAG, "On Tilting " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Tilting"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST LocationAPIclient.connect(); } break; case DetectedActivity.WALKING: Log.d(TAG, "On Walking " + activity.getConfidence()); if (activity.getConfidence() >= 75) { //Send Notification To User NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("Let's Walk"); builder.setSmallIcon(R.drawable.elaxer_x); builder.setContentTitle("Elaxer"); NotificationManagerCompat.from(this).notify(0, builder.build()); requestLocatonSetting(3*60*1000,2*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds LocationAPIclient.connect(); } break; case DetectedActivity.UNKNOWN: Log.d(TAG, "UnKnown " + activity.getConfidence()); break; } } } public void setTimer(int Minutes) { Log.d(TAG, "=================================================="); Log.d(TAG, "Set Timeer Starts It will Run Every " + Minutes); int MilliSeconds = 60000 * Minutes; final Handler handler = new Handler(); timer = new Timer(); TimerTask doAsynchronousTask = new TimerTask() { @Override public void run() { handler.post(new Runnable() { public void run() { try { //CODE THAT YOU WANT TO EXECUTE AT GIVEN INTERVAL } catch (Exception e) { // TODO Auto-generated catch block } } }); } }; timer.schedule(doAsynchronousTask, 0, MilliSeconds); Log.d(TAG, "=================================================="); } @Override public void onConnected(@Nullable Bundle bundle) { Log.d(TAG, "On Connected Running"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(LocationAPIclient); if (mCurrentLocation!=null){ Log.d(TAG,"Last Known Location Is not Null "); new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); } else { Log.d(TAG,"Last Known Location Is NULL Start Location Updates"); LocationServices.FusedLocationApi.requestLocationUpdates(LocationAPIclient,mLocationRequest,this); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onLocationChanged(Location location) { Log.d(TAG,"On Location Changed Calling"); mCurrentLocation=location; new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); Log.d(TAG,"Stopping Location Update"); // LocationServices.FusedLocationApi.removeLocationUpdates(LocationAPIclient,this); } public void requestLocatonSetting(int Interval,int FastestInterval,int LocationAccuracy){ mLocationRequest=new LocationRequest(); mLocationRequest.setInterval(Interval); mLocationRequest.setFastestInterval(FastestInterval); mLocationRequest.setPriority(LocationAccuracy); } } 

Ejecuto este código después de agregar algunas líneas al mismo código que el anterior.

  • Primero declaro int estático en el nivel de clase en IntentService porque DectectedActivity.getType() devuelve int. static int detectedActivity;
  • A continuación, en i comprobar si su mismo estado como último como este if (activity.getConfidence() >= 75 && activity.getType()!=detectedActivity)

Eso es todo. Gracias a @Pablo Baxter que me dio algún tipo de lógica para aplicar. He probado esto en IntentService pero IntentService que probarlo en el servicio para que pueda actualizar ubicaciones. Actualizar pronto.

EDITAR

Aquí hay un ejemplo mejor usando sólo el código que ha proporcionado anteriormente:

Utilice este servicio al registrar su ActivityRecognitionApi:

 public class LocationUpdateService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { public static final String TAG = "###RECOGNISED SRVCE###"; private GoogleApiClient apiClient; private PendingIntent pendingIntent; private DetectedActivity lastActivity; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { apiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); apiClient.connect(); pendingIntent = PendingIntent.getService(this, 1, new Intent(this, YourIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT); } @Override public int onStartCommand(Intent intent, int flag, int startId) { Log.d(TAG, "onStartCommand"); if (ActivityRecognitionResult.hasResult(intent)) { Log.d(TAG, "ActivityRecognition Has Result"); ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); handleDetectedActivity(result); /* You should really use LocalBroadcastManager to send events out to an activity for UI updates */ // Navigation_Drawer nav = new Navigation_Drawer(); // nav.UserMovementResult(result); } return START_STICKY; } @Override public void onConnected(@Nullable Bundle bundle) { Log.d(TAG, "On Connected Running"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } Location location = LocationServices.FusedLocationApi.getLastLocation(apiClient); if (location!=null){ Log.d(TAG,"Last Known Location Is not Null "); Intent intent = new Intent(this, YourIntentService.class).putExtra("lastKnown", location); startService(intent); /* No more need for this! */ // new Location_sendeToServer_AsyncTask(this).execute(String.valueOf(mCurrentLocation.getLatitude()),String.valueOf(mCurrentLocation.getLongitude()),String.valueOf(mCurrentLocation.getAccuracy())); } else { Log.d(TAG,"Last Known Location Is NULL Start Location Updates"); updateLocationSetting(5*60*60*1000,3*60*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); // LocationServices.FusedLocationApi.requestLocationUpdates(apiClient,mLocationRequest,this); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } private void handleDetectedActivity(ActivityRecognitionResult result) { DetectedActivity mostProbableActivity = result.getMostProbableActivity(); switch (result.getMostProbableActivity().getType()) { case DetectedActivity.IN_VEHICLE: // Log.d(TAG, "In Vehicle " + activity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("In Vehicle"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); //requestLocatonSetting(6*60*1000,6*60*1000,LocationRequest.PRIORITY_HIGH_ACCURACY); //TEST if (apiClient.isConnected()) { updateLocationSetting(10 * 60 * 1000, 8 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; case DetectedActivity.ON_BICYCLE: Log.d(TAG, "On Bicycle " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("On Bicycle"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(7 * 60 * 1000, 5 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; case DetectedActivity.ON_FOOT: Log.d(TAG, "On Foot " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75) { DetectedActivity nextHighest = result.getProbableActivities().get(1); if (nextHighest.getType() == DetectedActivity.RUNNING && nextHighest != lastActivity) { Log.d(TAG, "On Running " + mostProbableActivity.getConfidence()); //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Running"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = nextHighest; } } else if (nextHighest.getConfidence() >= 75 && nextHighest != lastActivity) { Log.d(TAG, "On Walking " + mostProbableActivity.getConfidence()); //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Let's Walk"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = nextHighest; } } //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("On Foot"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); } break; case DetectedActivity.STILL: Log.d(TAG, "On Still " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Still"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(5 * 60 * 60 * 1000, 3 * 60 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; case DetectedActivity.TILTING: Log.d(TAG, "On Tilting " + mostProbableActivity.getConfidence()); if (mostProbableActivity.getConfidence() >= 75 && mostProbableActivity != lastActivity) { //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Tilting"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); if (apiClient.isConnected()) { updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds lastActivity = mostProbableActivity; } } break; // case DetectedActivity.WALKING: // Log.d(TAG, "On Walking " + mostProbableActivity.getConfidence()); // if (mostProbableActivity.getConfidence() >= 75) { // //Send Notification To User // NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // builder.setContentText("Let's Walk"); // builder.setSmallIcon(R.drawable.elaxer_x); // builder.setContentTitle("Elaxer"); // NotificationManagerCompat.from(this).notify(0, builder.build()); // // if (apiClient.isConnected()) { // updateLocationSetting(3 * 60 * 1000, 2 * 60 * 1000, LocationRequest.PRIORITY_HIGH_ACCURACY); //5 hours= hours * 60 min*60 sec* 1000 milliseconds // } // } // break; case DetectedActivity.UNKNOWN: Log.d(TAG, "UnKnown " + mostProbableActivity.getConfidence()); lastActivity = mostProbableActivity; break; } } private void updateLocationSetting(int Interval, int FastestInterval, int LocationAccuracy) { LocationRequest request = new LocationRequest(); request.setInterval(Interval); request.setFastestInterval(FastestInterval); request.setPriority(LocationAccuracy); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { //TODO DO SOMETHING HERE! return; } LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, request, pendingIntent); } } 

Y esto sería el IntentService para usar en lugar de usar el AsyncTask que estaba usando:

 public class YourIntentService extends IntentService { public YourIntentService() { super("YOUR_INTENT_SERVICE"); } @Override protected void onHandleIntent(@Nullable Intent intent) { if (intent != null) { if (LocationResult.hasResult(intent)) { LocationResult result = LocationResult.extractResult(intent); Location location = result.getLastLocation(); Log.d("YourIntentService", "Got new location: " + location); } else if (intent.hasExtra("lastKnown")) { Location location = intent.getParcelableExtra("lastKnown"); Log.d("YourIntentService", "Got last known location: " + location); } else if (LocationAvailability.hasLocationAvailability(intent)) { LocationAvailability locationAvailability = LocationAvailability.extractLocationAvailability(intent); Log.d("YourIntentService", "Location Availability: " + locationAvailability.isLocationAvailable()); } } } } 

Este servicio de intenciones puede manejar las solicitudes de bloqueo de red siempre y cuando se las llame dentro de la onHandleIntent .

He modificado el código handleDetectedActivity un poco para que en cada actualización de actividad, no se produzca una nueva actualización de ubicación.


En primer lugar, no le sugeriría que utilice un IntentService la manera que está ahora, ya que el servicio se matará una vez que salga onHandleIntent , lo que causaría una gran cantidad de problemas ya que está confiando en callbacks. Todo esto debe ser puesto en un Service lugar.

En cuanto a manejar las actualizaciones de ubicación basadas en el reconocimiento de actividad, encontré esta bonita biblioteca que simplifica esto y es bastante fácil de usar. https://github.com/mrmans0n/smart-location-lib

A continuación se muestra un ejemplo de cómo utilizar la biblioteca con actualizaciones de ubicación basadas en los resultados de la actividad.

 SmartLocation.with(this).location(new LocationBasedOnActivityProvider(new LocationBasedOnActivityProvider.LocationBasedOnActivityListener() { @Override public LocationParams locationParamsForActivity(DetectedActivity detectedActivity) { if (detectedActivity.getConfidence() >= 75) { LocationParams.Builder builder = new LocationParams.Builder(); switch (detectedActivity.getType()) { case DetectedActivity.IN_VEHICLE: builder.setInterval(/*Interval*/) .setAccuracy(/*Locaiton Accuracy*/); break; case DetectedActivity.ON_BICYCLE: /* So on and so forth.... */ break; } return builder.build(); } return null; } })).start(new OnLocationUpdatedListener() { @Override public void onLocationUpdated(Location location) { //Do what you need here. } }); 

Esto debe ser eliminado en un Service en la función onStart , con onStartCommand manejando cambios basados ​​en los extras de intención que usted proporciona. También puede utilizar esta biblioteca para obtener la última ubicación conocida y obtener una sola corrección.

Una última cosa, te recomiendo que te AsyncTask del AsyncTask si estás pasando contextos a él. En su lugar, utilice IntentService , ya que la función onHandleIntent se ejecuta en un subproceso de fondo y puede utilizar el contexto de IntentService para realizar las tareas que necesite con ella. Puede pasar el objeto Location como un extra en la intención cuando inicie su IntentService .

  • Android Context sin estar en una actividad? ¿Y otra programación sin actividad?
  • Habilitar servicios de ubicación para Android si el usuario eligió la opción Nunca
  • ¿Cómo puede obtener una ubicación en android cuando todos los proveedores de ubicación están inhabilitados?
  • Evitar que se detecte una ubicación incorrecta con el proveedor de la red
  • Uso del servicio LocationClient de Google Play Services en segundo plano
  • ACCESS_COARSE_LOCATION es necesario si el usuario ya ha concedido ACCESS_FINE_LOCATION?
  • La API de ubicación de Google Play Service devuelve una ubicación incorrecta a veces
  • Cómo recuperar la ubicación GPS a través de SMS
  • Obtener el nombre de ubicación actual del usuario sin necesidad de utilizar gps o Internet, sino mediante Network_Provider en android
  • Bug in Android Geofence Código de ejemplo? ¿Puede alguien confirmar?
  • Ubicación de Android getBearing () devuelve siempre 0
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.