Buscar..


Introducción

Las API de ubicación de Android se utilizan en una amplia variedad de aplicaciones para diferentes propósitos, como encontrar la ubicación del usuario, notificar cuando un usuario ha abandonado un área general (Geofencing) y ayudar a interpretar la actividad del usuario (caminar, correr, conducir, etc.).

Sin embargo, las API de ubicación de Android no son el único medio de adquirir la ubicación del usuario. Lo siguiente le dará ejemplos de cómo usar el LocationManager de Android y otras bibliotecas de ubicación comunes.

Observaciones

Para crear aplicaciones conscientes de la ubicación en Android, hay dos caminos:

Gerente de locación

Pros

  • Control más granular.
  • Disponible en todos los dispositivos.
  • Parte del framework Android

Contras

  • El consumo de la batería es un problema, si no se administra correctamente
  • Requiere lógica para cambiar los proveedores de ubicación, si el dispositivo no puede encontrar una ubicación (por ejemplo, GPS deficiente dentro de un edificio)

Caracteristicas

  • Oyente NMEA
  • Escucha del estado del GPS
  • Escuche los cambios de estado del proveedor (por ejemplo, el GPS está apagado por el usuario)
  • Lista de proveedores para elegir la fuente de ubicación de

Proveedores

GPS

  • Permisos requeridos:
  • Precisión: 10m - 100m
  • Requisitos de potencia: ALTA
  • Disponibilidad: Mundial (con clara vista del cielo).
  • NOTAS :
    • Las actualizaciones de ubicación generalmente se realizan una vez por segundo, pero en situaciones donde el GPS no se ha utilizado durante un tiempo y el A-GPS no está disponible, puede tomar varios minutos para que se reciba una ubicación.
    • En los casos en que se obstruye la vista clara del cielo, los puntos GPS no se agruparán muy bien (los puntos de ubicación "saltan") y la precisión puede ser engañosa en ciertas áreas debido al efecto del " Cañón urbano ".

Red

  • Permisos requeridos:
  • Precisión: 100m - 1000m +
  • Requisitos de alimentación: BAJO - MEDIO
  • Disponibilidad: Dentro del rango de torre celular o señal wifi.
  • NOTAS:
    • Las actualizaciones de ubicación ocurren con menos frecuencia que el GPS
    • Las actualizaciones de ubicación generalmente no se agrupan bien (los puntos de ubicación "saltan") y la precisión puede variar según el número de factores diferentes (número de señales wifi, intensidad de la señal, tipo de torre celular, etc.)

Pasivo

  • Permisos requeridos:
  • Precisión: 10m - 1000m +
  • Requisitos de alimentación: NINGUNO
  • Disponibilidad: solo cuando otra aplicación recibe una ubicación de GPS o red
  • NOTAS:
    • No confíe en esto para darle actualizaciones continuas. Esto escucha de forma pasiva a otras aplicaciones que realizan solicitudes de ubicación y devuelve esas ubicaciones.
    • No devuelve los puntos generados por FusedLocationProviderApi, solo los puntos de ubicación subyacentes utilizados para generarlos.

FusedLocationProviderApi

Pros

  • Ofrece menos consumo de batería "fuera de la caja"
  • Maneja bien el mal GPS
  • Recibe actualizaciones más regularmente

Contras

  • Menos control granular sobre GPS
  • Puede no estar disponible en todos los dispositivos o en ciertos países
  • Requiere dependencia de biblioteca de terceros

Caracteristicas

  • Uso bien administrado de los proveedores de ubicación para un ahorro óptimo de la masa
  • Normalmente genera puntos más precisos que el proveedor de ubicación de red
  • Actualizaciones más frecuentes de la biblioteca, permitiendo más mejoras.
  • No es necesario especificar qué tipo de proveedor utilizar

UbicaciónSolicitud de Niveles de Prioridad

PRIORITY_HIGH_ACCURACY

  • Permisos requeridos:
  • Precisión: 10m - 100m
  • Requisitos de potencia: ALTA
  • Disponibilidad: Dondequiera que esté disponible Google Play Services.
  • NOTAS:
    • Si no se usa ACCESS_FINE_LOCATION , esto no usará el GPS para generar actualizaciones de ubicación, pero seguirá encontrando un punto bastante preciso en las condiciones correctas.
    • Si se usa ACCESS_FINE_LOCATION , puede o no usar GPS para generar puntos de ubicación, dependiendo de la precisión con la que actualmente puede rastrear el dispositivo dadas las condiciones ambientales.
    • Aunque esto puede reportar actualizaciones de ubicación más precisas que las otras configuraciones, todavía es propenso al efecto " Urban Canyon ".

PRIORITY_BALANCED_POWER_ACCURACY

  • Permisos requeridos:
  • Precisión: 100m - 1000m +
  • Requisitos de energía: MEDIO
  • Disponibilidad: Dondequiera que esté disponible Google Play Services.
  • NOTAS:
    • Las mismas notas que PRIORITY_HIGH_ACCURACY
    • Aunque es poco probable, esta configuración puede seguir utilizando el GPS para generar una ubicación.

PRIORITY_LOW_POWER

  • Permisos requeridos:
  • Precisión: 100m - 1000m +
  • Requisitos de alimentación: BAJA
  • Disponibilidad: Dondequiera que esté disponible Google Play Services.
  • NOTAS:
    • Probablemente no use GPS, pero no está probado hasta ahora.
    • Las actualizaciones no suelen ser muy precisas
    • Usado generalmente para detectar cambios significativos en la ubicación.

PRIORITY_NO_POWER

  • Permisos requeridos:
  • Precisión: 10m - 1000m +
  • Requisitos de alimentación: NINGUNO
  • Disponibilidad: Dondequiera que esté disponible Google Play Services.
  • NOTAS:
    • Funciona de forma casi idéntica al LocationManager PASSIVE_PROVIDER
    • Informa sobre las actualizaciones de Google Play Services cuando se recibe, donde PASSIVE_PROVIDER informa sobre las actualizaciones de ubicación subyacentes utilizadas

Solución de problemas

OnLocationChanged () nunca llamado

Ya que este parece ser un problema común con la obtención de ubicaciones de Android, pondré una lista rápida de correcciones comunes:


  1. Revisa tu manifiesto!

    Uno de los problemas más comunes es que nunca se dieron los permisos correctos. Si está utilizando GPS (con o sin red), use <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> , o use <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> . FusedLocationApi de Google requiere ACCESS_FINE_LOCATION .


  1. (Para Android 6+) Verifique los permisos de tiempo de ejecución !

    Compruebe y solicite permisos! Si nunca te dan permisos, terminarás con colisiones o, lo que es peor (si estás detectando todas las excepciones), ¡terminarás sin ninguna indicación de nada! No importa si el usuario le otorga permiso al inicio de la aplicación, siempre verifique si tiene permisos para todas las llamadas. El usuario puede acceder fácilmente a sus ajustes y revocarlos.


  1. ¡Comprueba tu código!

    ¿Estás seguro de que estás pasando en el oyente correcto? ¿ IntentService ese BroadcastReceiver o IntentService a su manifiesto? ¿Está utilizando PendingIntent.getService() en una clase BroadcastReceiver , o getBroadcast() en una clase IntentService ? ¿Está seguro de que no está desregistrando a su oyente en otra parte de su código inmediatamente después de realizar la solicitud?


  1. Compruebe la configuración del dispositivo!

    Obviamente, asegúrate de tener los servicios de ubicación activados.

    introduzca la descripción de la imagen aquí

    Si está utilizando servicios de red, ¿activó "Escanear siempre disponible"? ¿Tiene el modo de ubicación configurado en "Mejor" ("Alta precisión") o "Ahorro de batería" ("Sólo en red")?

    introduzca la descripción de la imagen aquí

    Si está utilizando GPS, ¿activó "Mejor" ("Alta precisión") o "Solo dispositivo" en el modo de ubicación?

    introduzca la descripción de la imagen aquí


  1. ¡Comprueba tu código!

    Sí, esto está aquí dos veces. ¿ PendingIntent usar un LocationListener lugar de un PendingIntent , o viceversa, para asegurarse de que realmente implementó el LocationManager correctamente? ¿Está seguro de que la solicitud de ubicación no se está eliminando en alguna parte del ciclo de vida de la actividad o el servicio que no esperaba que ocurriera?


  1. Revisa tu entorno!

    ¿Está probando el GPS en el primer piso de un edificio en el centro de San Francisco? ¿Está probando ubicaciones de red en medio de la nada? ¿Trabaja en un búnker subterráneo secreto sin todas las señales de radio, preguntándose por qué su dispositivo no tiene ubicación? ¡Siempre revise dos veces sus alrededores cuando intente solucionar problemas de ubicación!


Podría haber muchas otras razones menos obvias por las que la ubicación no funciona, pero antes de buscar esas correcciones esotéricas, simplemente ejecute esta lista de verificación rápida.

API de ubicación fusionada

Ejemplo de uso de la actividad con LocationRequest

/*
 * This example is useful if you only want to receive updates in this 
 * activity only, and have no use for location anywhere else.
 */
public class LocationActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    protected void onStart(){
        super.onStart();
        mGoogleApiClient.connect();
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }
        }
    }
    
    @Override
    protected void onPause(){
        super.onPause();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            }
        }
    }
    
    @Override
    protected void onStop(){
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    @Override
    public void onLocationChanged(Location location) {
        //Handle your location update code here
    }
}

Ejemplo de uso de Service w / PendingIntent y BroadcastReceiver

EjemploActividad

Lectura recomendada: LocalBroadcastManager

/*
 * This example is useful if you have many different classes that should be 
 * receiving location updates, but want more granular control over which ones
 * listen to the updates.
 * 
 * For example, this activity will stop getting updates when it is not visible, but a database
 * class with a registered local receiver will continue to receive updates, until "stopUpdates()" is called here.
 *
 */
public class ExampleActivity extends AppCompatActivity {

    private InternalLocationReceiver mInternalLocationReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        //Create internal receiver object in this method only.
        mInternalLocationReceiver = new InternalLocationReceiver(this);
    }

    @Override
    protected void onResume(){
        super.onResume();
        
        //Register to receive updates in activity only when activity is visible
        LocalBroadcastManager.getInstance(this).registerReceiver(mInternalLocationReceiver, new IntentFilter("googleLocation"));
    }

    @Override
    protected void onPause(){
        super.onPause();
        
        //Unregister to stop receiving updates in activity when it is not visible.
        //NOTE: You will still receive updates even if this activity is killed.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mInternalLocationReceiver);
    }

    //Helper method to get updates
    private void requestUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("request", true));
    }

    //Helper method to stop updates
    private void stopUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("remove", true));
    }

    /*
     * Internal receiver used to get location updates for this activity.
     * 
     * This receiver and any receiver registered with LocalBroadcastManager does
     * not need to be registered in the Manifest.
     *
     */
    private static class InternalLocationReceiver extends BroadcastReceiver{

        private ExampleActivity mActivity;

        InternalLocationReceiver(ExampleActivity activity){
            mActivity = activity;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            final ExampleActivity activity = mActivity;
            if(activity != null) {
                LocationResult result = intent.getParcelableExtra("result");
                //Handle location update here
            }
        }
    }
}

Servicio de localización

NOTA: ¡No olvides registrar este servicio en el Manifiesto!

public class LocationService extends Service implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate(){
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        super.onStartCommand(intent, flags, startId);
        //Permission check for Android 6.0+
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (intent.getBooleanExtra("request", false)) {
                if (mGoogleApiClient.isConnected()) {
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
                } else {
                    mGoogleApiClient.connect();
                }
            }
            else if(intent.getBooleanExtra("remove", false)){
                stopSelf();
            }
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        if(mGoogleApiClient.isConnected()){
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, getPendingIntent());
            mGoogleApiClient.disconnect();
        }
    }
    
    private PendingIntent getPendingIntent(){
        
        //Example for IntentService
        //return PendingIntent.getService(this, 0, new Intent(this, **YOUR_INTENT_SERVICE_CLASS_HERE**), PendingIntent.FLAG_UPDATE_CURRENT);
        
        //Example for BroadcastReceiver
        return PendingIntent.getBroadcast(this, 0, new Intent(this, LocationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        //Permission check for Android 6.0+
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

UbicaciónReceptor

NOTA: ¡No olvides registrar este receptor en el Manifiesto!

public class LocationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(LocationResult.hasResult(intent)){
            LocationResult locationResult = LocationResult.extractResult(intent);
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("googleLocation").putExtra("result", locationResult));
        }
    }
}

Solicitando actualizaciones de ubicación usando LocationManager

Como siempre, debe asegurarse de tener los permisos necesarios.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }


    @Override
    protected void onResume() {
        super.onResume();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update!
        Log.i("onLocationChanged", location.toString());
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

Solicitar actualizaciones de ubicación en un subproceso separado utilizando LocationManager

Como siempre, debe asegurarse de tener los permisos necesarios.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;
    HandlerThread mLocationHandlerThread = null;
    Looper mLocationHandlerLooper = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationHandlerThread = new HandlerThread("locationHandlerThread");
    }


    @Override
    protected void onResume() {
        super.onResume();

        mLocationHandlerThread.start();
        mLocationHandlerLooper = mLocationHandlerThread.getLooper();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this, mLocationHandlerLooper);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        mLocationHandlerLooper = null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
            mLocationHandlerThread.quitSafely();
        else
            mLocationHandlerThread.quit();

        mLocationHandlerThread = null;


        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update on a separate thread!
        Log.i("onLocationChanged", location.toString());

        // You can verify which thread you're on by something like this:
        // Log.d("Which thread?", Thread.currentThread() == Looper.getMainLooper().getThread() ? "UI Thread" : "New thread");
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

Registrar geofence

He creado la clase de GeoFenceObserversationService singleton .

GeoFenceObserversationService.java :

public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {

    protected static final String TAG = "GeoFenceObserversationService";
    protected GoogleApiClient mGoogleApiClient;
    protected ArrayList<Geofence> mGeofenceList;
    private boolean mGeofencesAdded;
    private SharedPreferences mSharedPreferences;
    private static GeoFenceObserversationService mInstant;
    public static GeoFenceObserversationService getInstant(){
        return mInstant;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstant = this;
        mGeofenceList = new ArrayList<Geofence>();
        mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
        mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);

        buildGoogleApiClient();
    }


    @Override
    public void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

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

    protected void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
    }

    @Override
    public void onConnectionSuspended(int cause) {

    }

    private GeofencingRequest getGeofencingRequest() {

        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
        builder.addGeofences(mGeofenceList);
        return builder.build();
    }


    public void addGeofences() {
            if (!mGoogleApiClient.isConnected()) {
                Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
                return;
            }

        populateGeofenceList();
        if(!mGeofenceList.isEmpty()){
            try {
                LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
            } catch (SecurityException securityException) {
                securityException.printStackTrace();
            }
        }

        }

    public void removeGeofences() {
        if (!mGoogleApiClient.isConnected()) {
            Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
        } catch (SecurityException securityException) {
            securityException.printStackTrace();
        }
    }


    public void onResult(Status status) {

        if (status.isSuccess()) {
            mGeofencesAdded = !mGeofencesAdded;
            SharedPreferences.Editor editor = mSharedPreferences.edit();
            editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
            editor.apply();
        } else {
            String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
            Log.i("Geofence", errorMessage);
        }
    }

    private PendingIntent getGeofencePendingIntent() {
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private void populateGeofenceList() {
        mGeofenceList.clear();
        List<GeoFencingResponce> geoFenceList = getGeofencesList;
        if(geoFenceList!=null&&!geoFenceList.isEmpty()){
            for (GeoFencingResponce obj : geoFenceList){
                mGeofenceList.add(obj.getGeofence());
                Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
            }
        }
    }
}

AppConstant :

   public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
    public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
    public static final String DETECTED_GEOFENCES = "detected_geofences";
    public static final String DETECTED_BEACONS = "detected_beacons";

    public static String getErrorString(Context context, int errorCode) {
        Resources mResources = context.getResources();
        switch (errorCode) {
            case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
                return mResources.getString(R.string.geofence_not_available);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
                return mResources.getString(R.string.geofence_too_many_geofences);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
                return mResources.getString(R.string.geofence_too_many_pending_intents);
            default:
                return mResources.getString(R.string.unknown_geofence_error);
        }
    }

¿Dónde empecé servicio? De la clase de aplicación

  • startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));

¿Cómo me registré Geofences?

  • GeoFenceObserversationService.getInstant().addGeofences();

Obtener la dirección de la ubicación utilizando Geocoder

Después de obtener el objeto de Location de FusedAPI , puede adquirir fácilmente la información de Address de ese objeto.

private Address getCountryInfo(Location location) {
    Address address = null;
    Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
    String errorMessage;
    List<Address> addresses = null;
    try {
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = "IOException>>" + ioException.getMessage();
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = "IllegalArgumentException>>" + illegalArgumentException.getMessage();
    }
    if (addresses != null && !addresses.isEmpty()) {
        address = addresses.get(0);
    }
    return country;
}

Obteniendo actualizaciones de ubicación en un BroadcastReceiver

Primero cree una clase BroadcastReceiver para manejar las actualizaciones de ubicación entrantes:

public class LocationReceiver extends BroadcastReceiver implements Constants {

    @Override
     public void onReceive(Context context, Intent intent) {

        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            if (location != null) {
                // Do something with your location
            } else {
                Log.d(LocationReceiver.class.getSimpleName(), "*** location object is null ***");
            }
        }
    }
}

Luego, cuando se conecte a GoogleApiClient en la devolución de llamada onConnected:

@Override
public void onConnected(Bundle connectionHint) {
    Intent backgroundIntent = new Intent(this, LocationReceiver.class);
    mBackgroundPendingIntent = backgroundPendingIntent.getBroadcast(getApplicationContext(), LOCATION_REUEST_CODE, backgroundIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    mFusedLocationProviderApi.requestLocationUpdates(mLocationClient, mLocationRequest, backgroundPendingIntent);
}

No olvide eliminar el intento de actualización de la ubicación en la devolución de llamada del ciclo de vida apropiado:

@Override
public void onDestroy() {
    if (servicesAvailable && mLocationClient != null) {
        if (mLocationClient.isConnected()) {
            fusedLocationProviderApi.removeLocationUpdates(mLocationClient, backgroundPendingIntent);
            // Destroy the current location client
            mLocationClient = null;
        } else {
            mLocationClient.unregisterConnectionCallbacks(this);
            mLocationClient = null;
        }
    }
    super.onDestroy();
}


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow