Android - Servizi basati sulla posizione

Le API di localizzazione Android ti consentono di creare facilmente applicazioni in grado di riconoscere la posizione, senza dover concentrarti sui dettagli della tecnologia di localizzazione sottostante.

Ciò diventa possibile con l'aiuto di Google Play services, che facilita l'aggiunta della consapevolezza della posizione alla tua app con rilevamento automatico della posizione, geofencing e riconoscimento delle attività.

Questo tutorial mostra come utilizzare i servizi di localizzazione nella tua APP per ottenere la posizione corrente, ricevere aggiornamenti periodici sulla posizione, cercare indirizzi ecc.

L'oggetto posizione

Il LocationL'oggetto rappresenta una posizione geografica che può essere costituita da latitudine, longitudine, data e ora e altre informazioni come rilevamento, altitudine e velocità. Sono disponibili i seguenti metodi importanti che è possibile utilizzare con l'oggetto Posizione per ottenere informazioni specifiche sulla posizione:

Sr.No. Metodo e descrizione
1

float distanceTo(Location dest)

Restituisce la distanza approssimativa in metri tra questa posizione e la posizione data.

2

float getAccuracy()

Ottieni la precisione stimata di questa posizione, in metri.

3

double getAltitude()

Ottieni l'altitudine, se disponibile, in metri sul livello del mare.

4

float getBearing()

Ottieni il rilevamento, in gradi.

5

double getLatitude()

Ottieni la latitudine, in gradi.

6

double getLongitude()

Ottieni la longitudine, in gradi.

7

float getSpeed()

Ottieni la velocità, se disponibile, in metri / secondo dal suolo.

8

boolean hasAccuracy()

Vero se questa posizione ha una precisione.

9

boolean hasAltitude()

Vero se questa posizione ha un'altitudine.

10

boolean hasBearing()

Vero se questa posizione ha una rilevanza.

11

boolean hasSpeed()

Vero se questa posizione ha una velocità.

12

void reset()

Cancella il contenuto della posizione.

13

void setAccuracy(float accuracy)

Imposta la precisione stimata di questa posizione, metri.

14

void setAltitude(double altitude)

Imposta l'altitudine, in metri sul livello del mare.

15

void setBearing(float bearing)

Imposta il rilevamento, in gradi.

16

void setLatitude(double latitude)

Imposta la latitudine, in gradi.

17

void setLongitude(double longitude)

Imposta la longitudine, in gradi.

18

void setSpeed(float speed)

Imposta la velocità, in metri / secondo rispetto al fondo.

19

String toString()

Restituisce una stringa contenente una descrizione concisa e leggibile di questo oggetto.

Ottieni la posizione corrente

Per ottenere la posizione corrente, creare un client di posizione che sia LocationClient oggetto, collegalo ai servizi di localizzazione utilizzando connect() metodo, quindi chiamalo getLastLocation()metodo. Questo metodo restituisce la posizione più recente sotto forma diLocationoggetto che contiene coordinate di latitudine e longitudine e altre informazioni come spiegato sopra. Per avere funzionalità basate sulla posizione nella tua attività, dovrai implementare due interfacce:

  • GooglePlayServicesClient.ConnectionCallbacks
  • GooglePlayServicesClient.OnConnectionFailedListener

Queste interfacce forniscono i seguenti importanti metodi di callback, che devi implementare nella tua classe di attività:

Sr.No. Metodi di richiamata e descrizione
1

abstract void onConnected(Bundle connectionHint)

Questo metodo di callback viene chiamato quando il servizio di posizione è connesso correttamente al client di posizione. Useraiconnect() metodo per connettersi al client di posizione.

2

abstract void onDisconnected()

Questo metodo di callback viene chiamato quando il client è disconnesso. Useraidisconnect() metodo per disconnettersi dal client di posizione.

3

abstract void onConnectionFailed(ConnectionResult result)

Questo metodo di callback viene chiamato quando si è verificato un errore durante la connessione del client al servizio.

È necessario creare il client di posizione in onCreate() metodo della tua classe di attività, quindi collegalo a onStart(), in modo che i servizi di localizzazione mantengano la posizione corrente mentre la tua attività è completamente visibile. Dovresti disconnettere il client in onStop(), in modo che quando la tua app non è visibile, i servizi di localizzazione non mantengono la posizione corrente. Questo aiuta a risparmiare la carica della batteria in larga misura.

Ottieni la posizione aggiornata

Se desideri avere aggiornamenti sulla posizione, oltre alle interfacce sopra menzionate, dovrai implementare LocationListeneranche l'interfaccia. Questa interfaccia fornisce il seguente metodo di callback, che devi implementare nella tua classe di attività:

Sr.No. Metodo e descrizione di richiamata
1

abstract void onLocationChanged(Location location)

Questo metodo di callback viene utilizzato per ricevere notifiche da LocationClient quando la posizione è cambiata.

Posizione Qualità del servizio

Il LocationRequest viene utilizzato per richiedere una qualità del servizio (QoS) per gli aggiornamenti della posizione da LocationClient. Ci sono i seguenti metodi setter utili che puoi usare per gestire QoS. Sono disponibili metodi getter equivalenti che puoi controllare nella documentazione ufficiale di Android.

Sr.No. Metodo e descrizione
1

setExpirationDuration(long millis)

Imposta la durata di questa richiesta, in millisecondi.

2

setExpirationTime(long millis)

Imposta l'ora di scadenza della richiesta, in millisecondi dall'avvio.

3

setFastestInterval(long millis)

Imposta esplicitamente l'intervallo più veloce per gli aggiornamenti della posizione, in millisecondi.

4

setInterval(long millis)

Impostare l'intervallo desiderato per gli aggiornamenti della posizione attivi, in millisecondi.

5

setNumUpdates(int numUpdates)

Imposta il numero di aggiornamenti della posizione.

6

setPriority(int priority)

Imposta la priorità della richiesta.

Ad esempio, se la tua applicazione desidera una posizione ad alta precisione, dovrebbe creare una richiesta di posizione con setPriority(int) impostato su PRIORITY_HIGH_ACCURACY e setInterval(long)a 5 secondi. Puoi anche utilizzare intervalli più grandi e / o altre priorità come PRIORITY_LOW_POWER per richiedere la precisione del livello "città" o PRIORITY_BALANCED_POWER_ACCURACY per la precisione del livello "blocco".

Le attività dovrebbero considerare fortemente la rimozione di tutte le richieste di posizione quando si accede allo sfondo (ad esempio in onPause ()), o almeno scambiare la richiesta con un intervallo più ampio e di qualità inferiore per risparmiare energia.

Visualizzazione di un indirizzo di posizione

Una volta che hai Location oggetto, puoi usare Geocoder.getFromLocation()metodo per ottenere un indirizzo per una data latitudine e longitudine. Questo metodo è sincrono e potrebbe richiedere molto tempo per eseguire il suo lavoro, quindi dovresti chiamare il metodo dadoInBackground() metodo di un AsyncTask classe.

Il AsyncTask deve essere una sottoclasse per essere utilizzata e la sottoclasse avrà la precedenza doInBackground(Params...) metodo per eseguire un'attività in background e onPostExecute(Result)viene richiamato sul thread dell'interfaccia utente al termine del calcolo in background e al momento della visualizzazione del risultato. C'è un altro metodo importante disponibile in AyncTask che èexecute(Params... params), questo metodo esegue l'attività con i parametri specificati.

Esempio

L'esempio seguente mostra in pratica come utilizzare i servizi di localizzazione nella tua app per ottenere la posizione corrente e i suoi indirizzi equivalenti, ecc.

Per sperimentare questo esempio, avrai bisogno di un dispositivo mobile effettivo dotato dell'ultimo sistema operativo Android, altrimenti dovrai lottare con l'emulatore che potrebbe non funzionare.

Crea applicazione Android

Passo Descrizione
1 Si utilizzerà l'IDE di Android Studio per creare un'applicazione Android e denominarla come Tutorialspoint in un pacchetto com.example.tutorialspoint7.myapplication .
2 aggiungi il file src / GPSTracker.java e aggiungi il codice richiesto.
3 Modificare il file src / MainActivity.java e aggiungere il codice richiesto come mostrato di seguito per occuparsi di ottenere la posizione corrente e il suo indirizzo equivalente.
4 Modifica il file XML di layout res / layout / activity_main.xml per aggiungere tutti i componenti della GUI che includono tre pulsanti e due visualizzazioni di testo per mostrare posizione / indirizzo.
5 Modificare res / values ​​/ strings.xml per definire i valori costanti richiesti
6 Modifica AndroidManifest.xml come mostrato di seguito
7 Esegui l'applicazione per avviare l'emulatore Android e verifica il risultato delle modifiche apportate nell'applicazione.

Di seguito è riportato il contenuto del file di attività principale modificato MainActivity.java.

package com.example.tutorialspoint7.myapplication;

import android.Manifest;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.test.mock.MockPackageManager;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

   Button btnShowLocation;
   private static final int REQUEST_CODE_PERMISSION = 2;
   String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;

   // GPSTracker class
   GPSTracker gps;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
		
      try {
         if (ActivityCompat.checkSelfPermission(this, mPermission)
            != MockPackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{mPermission}, 
               REQUEST_CODE_PERMISSION);

            // If any permission above not allowed by user, this condition will
               execute every time, else your else part will work
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      btnShowLocation = (Button) findViewById(R.id.button);

      // show location button click event
      btnShowLocation.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View arg0) {
            // create class object
            gps = new GPSTracker(MainActivity.this);

            // check if GPS enabled
            if(gps.canGetLocation()){

               double latitude = gps.getLatitude();
               double longitude = gps.getLongitude();

               // \n is for new line
               Toast.makeText(getApplicationContext(), "Your Location is - \nLat: "
                  + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
            }else{
               // can't get location
               // GPS or Network is not enabled
               // Ask user to enable GPS/network in settings
               gps.showSettingsAlert();
            }

         }
      });
   }
}

Di seguito è riportato il contenuto del file di attività principale modificato GPSTracker.java.

package com.example.tutorialspoint7.myapplication;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener {

   private final Context mContext;

   // flag for GPS status
   boolean isGPSEnabled = false;

   // flag for network status
   boolean isNetworkEnabled = false;

   // flag for GPS status
   boolean canGetLocation = false;

   Location location; // location
   double latitude; // latitude
   double longitude; // longitude

   // The minimum distance to change Updates in meters
   private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

   // The minimum time between updates in milliseconds
   private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

   // Declaring a Location Manager
   protected LocationManager locationManager;

   public GPSTracker(Context context) {
      this.mContext = context;
      getLocation();
   }

   public Location getLocation() {
      try {
         locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

         // getting GPS status
         isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

         // getting network status
         isNetworkEnabled = locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

         if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
         } else {
            this.canGetLocation = true;
            // First get location from Network Provider
            if (isNetworkEnabled) {
               locationManager.requestLocationUpdates(
                  LocationManager.NETWORK_PROVIDER,
                  MIN_TIME_BW_UPDATES,
                  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
						
               Log.d("Network", "Network");
               if (locationManager != null) {
                  location = locationManager
                     .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
							
                  if (location != null) {
                     latitude = location.getLatitude();
                     longitude = location.getLongitude();
                  }
               }
            }
				
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
               if (location == null) {
                  locationManager.requestLocationUpdates(
                     LocationManager.GPS_PROVIDER,
                     MIN_TIME_BW_UPDATES,
                     MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
							
                  Log.d("GPS Enabled", "GPS Enabled");
                  if (locationManager != null) {
                     location = locationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
								
                     if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                     }
                  }
               }
            }
         }

      } catch (Exception e) {
         e.printStackTrace();
      }

      return location;
   }

   /**
      * Stop using GPS listener
      * Calling this function will stop using GPS in your app
   * */
	
   public void stopUsingGPS(){
      if(locationManager != null){
         locationManager.removeUpdates(GPSTracker.this);
      }
   }

   /**
      * Function to get latitude
   * */
	
   public double getLatitude(){
      if(location != null){
         latitude = location.getLatitude();
      }

      // return latitude
      return latitude;
   }

   /**
      * Function to get longitude
   * */
	
   public double getLongitude(){
      if(location != null){
         longitude = location.getLongitude();
      }

      // return longitude
      return longitude;
   }

   /**
      * Function to check GPS/wifi enabled
      * @return boolean
   * */
	
   public boolean canGetLocation() {
      return this.canGetLocation;
   }

   /**
      * Function to show settings alert dialog
      * On pressing Settings button will lauch Settings Options
   * */
	
   public void showSettingsAlert(){
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

      // Setting Dialog Title
      alertDialog.setTitle("GPS is settings");

      // Setting Dialog Message
      alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

      // On pressing Settings button
      alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog,int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
         }
      });

      // on pressing cancel button
      alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
         }
      });

      // Showing Alert Message
      alertDialog.show();
   }

   @Override
   public void onLocationChanged(Location location) {
   }

   @Override
   public void onProviderDisabled(String provider) {
   }

   @Override
   public void onProviderEnabled(String provider) {
   }

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

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

Di seguito sarà il contenuto di res/layout/activity_main.xml file -

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
   android:layout_width = "fill_parent"
   android:layout_height = "fill_parent"
   android:orientation = "vertical" >


   <Button
      android:id = "@+id/button"
      android:layout_width = "fill_parent"
      android:layout_height = "wrap_content"
      android:text = "getlocation"/>

</LinearLayout>

Di seguito sarà il contenuto di res/values/strings.xml per definire due nuove costanti -

<?xml version = "1.0" encoding = "utf-8"?>
<resources>
   <string name = "app_name">Tutorialspoint</string>
</resources>

Di seguito è riportato il contenuto predefinito di AndroidManifest.xml -

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
   package = "com.example.tutorialspoint7.myapplication">
   <uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name = "android.permission.INTERNET" />
   <application
      android:allowBackup = "true"
      android:icon = "@mipmap/ic_launcher"
      android:label = "@string/app_name"
      android:supportsRtl = "true"
      android:theme = "@style/AppTheme">
		
      <activity android:name = ".MainActivity">
         <intent-filter>
            <action android:name = "android.intent.action.MAIN" />

            <category android:name = "android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
   </application>

</manifest>

Proviamo a eseguire il tuo Tutorialspointapplicazione. Presumo che tu abbia collegato il tuo attuale dispositivo mobile Android al tuo computer. Per eseguire l'app da Android Studio, apri uno dei file di attività del progetto e fai clic sull'icona Esegui dalla barra degli strumenti. Prima di avviare l'applicazione, il programma di installazione di Android Studio visualizzerà la seguente finestra per selezionare un'opzione in cui si desidera eseguire l'applicazione Android.

Ora per vedere la posizione seleziona il pulsante Ottieni posizione che visualizzerà le informazioni sulla posizione come segue: