Ricerca…


introduzione

Le API di Android Location sono utilizzate in un'ampia varietà di app per scopi diversi, come trovare la posizione dell'utente, notificare quando un utente ha lasciato un'area generale (Geofencing) e aiutare a interpretare l'attività dell'utente (camminare, correre, guidare, ecc.).

Tuttavia, le API di posizione Android non sono l'unico mezzo per acquisire la posizione dell'utente. Quanto segue fornirà esempi su come utilizzare il LocationManager di Android e altre librerie di posizioni comuni.

Osservazioni

Per creare app che supportano la localizzazione in Android, esistono due percorsi:

LocationManager

Professionisti

  • Controllo più granulare
  • Disponibile in tutti i dispositivi
  • Parte del framework Android

Contro

  • Lo scarico della batteria è un problema, se non gestito correttamente
  • Richiede la logica per cambiare provider di posizione, se il dispositivo non è in grado di trovare una posizione (ad esempio, un GPS scadente all'interno di un edificio)

Caratteristiche

  • Listener NMEA
  • Listener di stato GPS
  • Ascolta le modifiche allo stato del provider (ad esempio, il GPS è disattivato dall'utente)
  • Elenco dei fornitori per scegliere l'origine della posizione da

provider

GPS

  • Autorizzazioni richieste:
  • Precisione: 10m - 100m
  • Requisiti di potenza: ALTA
  • Disponibilità: in tutto il mondo (con una visione chiara del cielo)
  • NOTE :
    • Gli aggiornamenti delle posizioni di solito arrivano una volta al secondo, ma in situazioni in cui il GPS non è stato utilizzato per un po 'di tempo e l' A-GPS non è disponibile, ci vuole qualche minuto per ricevere una posizione.
    • Nei casi in cui la visione chiara del cielo è ostruita, i punti GPS non si raggruppano molto bene (i punti posizione "salta") e la precisione può essere fuorviante in certe aree a causa dell'effetto " Urban Canyon ".

Rete

  • Autorizzazioni richieste:
  • Precisione: 100m - 1000m +
  • Requisiti di alimentazione: LOW - MEDIUM
  • Disponibilità: entro il raggio della torre cellulare o del segnale wifi
  • GLI APPUNTI:
    • Gli aggiornamenti delle posizioni si verificano meno frequentemente del GPS
    • Gli aggiornamenti di posizione in genere non si raggruppano bene (i punti di localizzazione "saltano") e la precisione può variare in base al numero di fattori diversi (numero di segnali wifi, intensità del segnale, tipo di torre cellulare, ecc.)

Passivo

  • Autorizzazioni richieste:
  • Precisione: 10m - 1000m +
  • Requisiti di alimentazione: NESSUNO
  • Disponibilità: solo quando un'altra app riceve una posizione dal GPS o dalla rete
  • GLI APPUNTI:
    • Non fare affidamento su questo per darti aggiornamenti continui. Questo ascolta passivamente altre app che fanno richieste di posizione e le restituisce.
    • Non restituisce punti FusedLocationProviderApi, solo i punti di localizzazione sottostanti utilizzati per generarli.

FusedLocationProviderApi

Professionisti

  • Offre meno batteria scarica "fuori dalla scatola"
  • Gestisce male il GPS
  • Ottiene aggiornamenti più regolarmente

Contro

  • Controllo meno granulare sul GPS
  • Potrebbe non essere disponibile su tutti i dispositivi o in alcuni Paesi
  • Richiede dipendenza dalla libreria di terze parti

Caratteristiche

  • Uso ben gestito dei fornitori di localizzazione per risparmi ottimali sulle batterie
  • Generalmente genera punti più precisi di Network Location Provider
  • Aggiornamenti più frequenti della libreria, consentendo ulteriori miglioramenti
  • Non è necessario specificare il tipo di provider da utilizzare

PosizioneRichiedi livelli di priorità

PRIORITY_HIGH_ACCURACY

  • Autorizzazioni richieste:
  • Precisione: 10m - 100m
  • Requisiti di potenza: ALTA
  • Disponibilità: ovunque siano disponibili i servizi di Google Play.
  • GLI APPUNTI:
    • Se ACCESS_FINE_LOCATION non viene utilizzato, questo non utilizzerà il GPS per generare aggiornamenti di posizione, ma troverà comunque un punto abbastanza accurato nelle giuste condizioni.
    • Se si utilizza ACCESS_FINE_LOCATION , può o non può utilizzare il GPS per generare punti di posizione, a seconda di quanto accurato possa attualmente tracciare il dispositivo in base alle condizioni ambientali.
    • Sebbene questo possa riportare aggiornamenti di posizione più accurati rispetto alle altre impostazioni, è ancora soggetto all'effetto " Urban Canyon ".

PRIORITY_BALANCED_POWER_ACCURACY

  • Autorizzazioni richieste:
  • Precisione: 100m - 1000m +
  • Requisiti di alimentazione: MEDIO
  • Disponibilità: ovunque siano disponibili i servizi di Google Play.
  • GLI APPUNTI:
    • Stesse note di PRIORITY_HIGH_ACCURACY
    • Sebbene sia improbabile, questa impostazione potrebbe comunque utilizzare il GPS per generare una posizione.

PRIORITY_LOW_POWER

  • Autorizzazioni richieste:
  • Precisione: 100m - 1000m +
  • Requisiti di alimentazione: LOW
  • Disponibilità: ovunque siano disponibili i servizi di Google Play.
  • GLI APPUNTI:
    • Probabilmente non usa il GPS, ma finora non è stato testato.
    • Gli aggiornamenti in genere non sono molto accurati
    • Usato generalmente per rilevare cambiamenti significativi nella posizione

PRIORITY_NO_POWER

  • Autorizzazioni richieste:
  • Precisione: 10m - 1000m +
  • Requisiti di alimentazione: NESSUNO
  • Disponibilità: ovunque siano disponibili i servizi di Google Play.
  • GLI APPUNTI:
    • Funziona in modo quasi identico a LocationManager PASSIVE_PROVIDER
    • Riporta gli aggiornamenti dei servizi di Google Play quando ricevuti, dove PASSIVE_PROVIDER riporta gli aggiornamenti di posizione sottostanti utilizzati

Risoluzione dei problemi

OnLocationChanged () Mai chiamato

Poiché questo sembra essere un problema comune con il rilevamento di posizioni Android, inserirò una breve lista di controllo delle correzioni comuni:


  1. Controlla il tuo manifest!

    Uno dei problemi più comuni è che le autorizzazioni corrette non sono mai state fornite. Se utilizzi il GPS (con o senza rete), usa <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> , altrimenti usa <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> . FusedLocationApi di Google richiede ACCESS_FINE_LOCATION .


  1. (Per Android 6+) Verifica le autorizzazioni di runtime !

    Verifica e richiedi le autorizzazioni! Se non ti vengono mai concesse autorizzazioni, finirai con arresti anomali, o peggio (se stai riscontrando tutte le eccezioni), finirai senza alcuna indicazione di nulla! Non importa se l'utente concede il permesso all'inizio dell'app, controlla sempre se hai le autorizzazioni per tutte le chiamate. L'utente può facilmente accedere alle proprie impostazioni e revocarle.


  1. Controlla il tuo codice!

    Sei sicuro di passare nell'ascoltatore giusto? Hai aggiunto BroadcastReceiver o IntentService al manifest? Stai utilizzando PendingIntent.getService() su una classe BroadcastReceiver o su getBroadcast() su una classe IntentService ? Sei sicuro di non annullare la registrazione del listener da qualche altra parte nel tuo codice subito dopo la richiesta?


  1. Controlla le impostazioni del dispositivo!

    Ovviamente, assicurati di aver attivato i servizi di localizzazione.

    inserisci la descrizione dell'immagine qui

    Se utilizzi i servizi di rete, hai attivato "Scansione sempre disponibile"? La modalità di localizzazione è impostata su "Migliore" ("Alta precisione") o "Risparmio batteria" ("Solo rete")?

    inserisci la descrizione dell'immagine qui

    Se utilizzi il GPS, hai attivato "Migliore" ("Alta precisione") o "Solo dispositivo" in modalità Posizione?

    inserisci la descrizione dell'immagine qui


  1. Controlla il tuo codice!

    Sì, è qui due volte. Hai provato a utilizzare LocationListener invece di PendingIntent o viceversa per assicurarti di aver implementato correttamente LocationManager ? Sei sicuro che la richiesta di posizione non venga rimossa in una parte del ciclo di vita di attività o servizio che non ti aspettavi di accadere?


  1. Controlla i tuoi dintorni!

    Stai testando il GPS al primo piano di un edificio nel centro di San Francisco? Stai testando le posizioni della rete nel bel mezzo del nulla? Lavori in un bunker sotterraneo segreto privo di tutti i segnali radio, chiedendoti perché il tuo dispositivo non ha la posizione? Controlla sempre i dintorni quando cerchi di risolvere i problemi di localizzazione!


Potrebbero esserci molte altre ragioni meno ovvie per cui la posizione non funziona, ma prima di cercare quelle correzioni esoteriche, è sufficiente scorrere questa lista di controllo rapida.

API di posizione fusa

Esempio di utilizzo dell'attività 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
    }
}

Esempio Utilizzo servizio w / PendingIntent e BroadcastReceiver

ExampleActivity

Lettura consigliata: 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
            }
        }
    }
}

Servizio di localizzazione

NOTA: non dimenticare di registrare questo servizio nel Manifesto!

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;
    }
}

LocationReceiver

NOTA: non dimenticare di registrare questo ricevitore nel Manifest!

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));
        }
    }
}

Richiesta di aggiornamenti di posizione tramite LocationManager

Come sempre, è necessario assicurarsi di disporre delle autorizzazioni necessarie.

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) {

    }
}

Richiesta di aggiornamenti di posizione su un thread separato utilizzando LocationManager

Come sempre, è necessario assicurarsi di disporre delle autorizzazioni necessarie.

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) {

    }
}

Registra geofence

Ho creato GeoFenceObserversationService classe 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);
        }
    }

Dove ho iniziato il servizio? Dalla classe dell'applicazione

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

Come ho registrato Geofences?

  • GeoFenceObserversationService.getInstant().addGeofences();

Ottieni indirizzo da posizione usando Geocoder

Dopo aver ottenuto il Location oggetto dal FusedAPI , si può facilmente acquisire Address informazioni da quell'oggetto.

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;
}

Ottenere gli aggiornamenti di posizione in un BroadcastReceiver

Per prima cosa creare una classe BroadcastReceiver per gestire gli aggiornamenti della posizione in arrivo:

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 ***");
            }
        }
    }
}

Quindi, quando ti connetti a GoogleApiClient nel callback 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);
}

Non dimenticare di rimuovere l'intento di aggiornamento della posizione nella callback del ciclo di vita appropriato:

@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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow