Ghidul dezvoltatorului Android pentru API-ul Google Location Services

Publicat: 2022-03-11

Cunoașterea locației utilizatorului este o informație utilă în multe aplicații pe care le dezvoltăm și le folosim astăzi. Există o mulțime de aplicații populare bazate pe locație care ne fac viața mai ușoară, precum și schimbă modul în care folosim aceste servicii. Un exemplu este aplicația extrem de populară Foursquare, unde utilizatorii care frecventează o unitate și se „înregistrează” câștigă adesea reduceri. Uber, care vă ajută să obțineți o călătorie de pe telefonul mobil la un preț mai mic decât un taxi obișnuit. Lista este mare și încă în creștere.

API-ul serviciilor de locație

În acest articol, vom crea o aplicație simplă pentru Android pentru a determina latitudinea și longitudinea utilizatorului folosind API-ul Google Location Services de la Android. Când dezvoltați aplicații Android, există câteva modalități de a obține locația utilizatorului.

Pachetul „android.location”

Pachetul „android.location” este disponibil de când Android a fost introdus pentru prima dată și ne oferă acces la serviciile de localizare. Aceste servicii permit aplicațiilor să obțină actualizări periodice ale locației geografice a dispozitivului.

Pachetul oferă două mijloace de achiziție a datelor de locație:

  • LocationManager.GPS_PROVIDER: determină locația folosind sateliți. În funcție de condiții, acest furnizor poate dura ceva timp pentru a returna o remediere a locației.

  • LocationManager.NETWORK_PROVIDER: determină locația în funcție de disponibilitatea turnurilor celulare și a punctelor de acces WiFi din apropiere. Acesta este mai rapid decât GPS_PROVIDER.

Când cauți locația utilizatorului, trebuie să te joci cu acești furnizori și cu disponibilitatea lor. În mod ideal, obțineți prima locație folosind NETWORK_PROVIDER, care ar putea să nu fie la fel de precisă, dar este mult mai rapidă. Apoi, puteți încerca să creșteți acuratețea ascultând o fixare mai bună a locației folosind GPS_PROVIDER.

API-urile furnizate de acest pachet sunt la nivel destul de scăzut și necesită dezvoltatorului aplicației să se ocupe de detaliile mai fine de a stabili când să solicite date despre locație și să programeze apeluri către API într-un mod optimizat. Pentru a îmbunătăți experiența dezvoltatorului cu serviciile de sistem bazate pe locație și pentru a ușura procesul de dezvoltare a aplicațiilor care țin seama de locație, Google a introdus o nouă modalitate de a solicita locația unui utilizator folosind Serviciile Google Play. Oferă un API mai simplu, cu o precizie mai mare, geofencing de putere redusă și multe altele.

API-ul Google Location Services

API-ul Google Location Services, cunoscut și ca FusedLocationProviderApi, este modalitatea recomandată de Google de a obține locația unui utilizator. Oferă cea mai bună acuratețe în funcție de nevoile noastre. Unele dintre avantajele utilizării acestui API față de cel precedent sunt:

  • Simplitate: spre deosebire de API-ul precedent, nu mai trebuie să aveți de-a face cu mai mulți furnizori. În schimb, specificați nevoi de nivel înalt, cum ar fi „precizie mare” sau „putere redusă”, și va lua o abordare adecvată.

  • Disponibilitate: Oferă aplicației dvs. acces imediat la cea mai bună și cea mai recentă locație cunoscută. De obicei, aceste informații sunt ușor disponibile, trebuie doar să le cereți.

  • Eficiență energetică: Minimizează utilizarea energiei aplicației dvs.

  • Versatilitate: îndeplinește o gamă largă de nevoi, de la utilizări în prim-plan - care necesită date de locație foarte precise, până la utilizări în fundal - care necesită doar actualizări periodice ale locației cu impact de putere neglijabil.

Să construim o aplicație Android bazată pe locație folosind acest API. Pentru aceasta, vom folosi IDE-ul sugerat de Google pentru dezvoltarea de aplicații Android - Android Studio. Începerea cu Android Studio este destul de simplă. Site-ul lor web descrie procedura care implică instalarea și configurarea Android Studio în detaliu, inclusiv cum să porniți prima aplicație Android pentru dezvoltare.

Android Studio ar trebui să ne facă lucrurile super-ușoare. Cu toate acestea, va trebui să începem prin a configura scriptul de compilare și a adăuga Servicii Google Play ca dependență pentru această aplicație. Acest lucru se poate face prin modificarea fișierului „build.gradle” după cum urmează:

 dependencies { compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.google.android.gms:play-services:6.5.87' // Add this line }

În momentul în care scriu acest articol, cea mai recentă versiune a serviciilor Google Play disponibilă este 6.5.87. Asigurați-vă că verificați întotdeauna cea mai recentă versiune disponibilă înainte de a începe. În cazul în care mai târziu apar versiuni mai noi și decideți să le actualizați pentru propriile proiecte, testați toate funcțiile legate de locație cu toate versiunile de Android pe care le acceptați.

În acest moment, ar trebui să putem începe să facem munca efectivă pentru aplicația noastră.

Solicitarea permisiunii, configurarea AndroidManifest.xml

Androidii au caracteristici de securitate specifice care ar împiedica orice aplicație arbitrară să solicite o locație precisă a utilizatorului. Pentru a rezolva acest lucru, trebuie să edităm „AndroidManifest.xml” și să adăugăm permisiunea de care avem nevoie pentru această aplicație:

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

În timp ce ne aflăm, ar trebui să definim și versiunea serviciilor Google Play pe care o folosim pentru această aplicație:

 <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

Se verifică disponibilitatea serviciilor Google Play

Înainte de a accesa funcțiile oferite de Serviciile Google Play, trebuie să verificăm dacă dispozitivul are instalate Serviciile Google Play și dacă versiunea este cea pe care intenționăm să o folosim (6.5.87).

 private boolean checkGooglePlayServices(){ int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * Google Play Services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mContext, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; }

Această metodă va verifica serviciile Google Play, iar în cazul în care dispozitivul nu îl are instalat (este rar, dar am văzut astfel de cazuri), va deschide un dialog cu eroarea corespunzătoare și va invita utilizatorul să instaleze/actualizeze Servicii Google Play din Magazinul Google Play.

Servicii Google Play

După ce utilizatorul completează rezoluția oferită de „GooglePlayServicesUtil.getErrorDialog()”, este declanșată o metodă de apel invers „onActivityResult()”, așa că trebuie să implementăm o logică pentru a gestiona apelul respectiv:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(mContext, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } }

Accesarea API-urilor Google

Pentru a accesa API-urile Google, trebuie doar să facem încă un pas: creați o instanță GoogleApiClient. Clientul API Google oferă un punct de intrare comun la toate serviciile Google Play și gestionează conexiunea la rețea dintre dispozitivul utilizatorului și fiecare serviciu Google. Primul nostru pas aici este să inițiem conexiunea. De obicei numesc acest cod din metoda „onCreate” a activității:

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

Prin înlănțuirea unei serii de apeluri de metodă, specificăm implementarea interfeței de apel invers și API-ul Location Service pe care dorim să-l folosim. Implementarea interfeței, în acest caz „acest”, va primi răspuns la metoda asincronă „connect()” atunci când conexiunea la serviciile Google Play reușește, eșuează sau devine suspendată. După adăugarea acestui cod, „Activitatea principală” ar trebui să arate astfel:

 package com.bitwoo.userlocation; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200; private GoogleApiClient mGoogleApiClient; private Location mLastLocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (checkGooglePlayServices()) { buildGoogleApiClient(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean checkGooglePlayServices() { int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * google play services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } }

Apoi, în metoda noastră „onStart” apelăm metoda „connect” și așteptăm ca metoda de apel invers „onConnected” să fie invocată:

 @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } }

Metoda „onConnected” va arăta astfel:

 @Override public void onConnected(Bundle bundle) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } }

Acest apel invers este declanșat atunci când Serviciile Google Play sunt conectate, ceea ce înseamnă că până atunci ar trebui să avem ultima locație cunoscută. Totuși, această locație poate fi nulă (este rar, dar nu imposibil). În acest caz, ceea ce recomand este să ascultați actualizările locației, care vor fi tratate în continuare.

Ascultarea actualizărilor locației

După ce invocați „getLastLocation”, este posibil să doriți să solicitați actualizări periodice de la Furnizorul Fused Location. În funcție de aplicația dvs., această perioadă poate fi scurtă sau lungă. De exemplu, dacă construiți o aplicație care urmărește locația unui utilizator în timp ce conduce, va trebui să ascultați actualizări la intervale scurte. Pe de altă parte, dacă aplicația dvs. este despre partajarea locației utilizatorului cu prietenul său, poate trebuie doar să solicitați locația din când în când.

Crearea unei cereri este destul de ușoară - puteți apela această metodă în cadrul metodei „onCreate”:

 protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(20000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); }

Instanțiem un nou obiect LocationRequest. Setați intervalul la 20 de secunde (20000 milisecunde). În plus, am setat o rată de actualizare accelerată la 5 secunde. Aceasta îi spune API-ului să furnizeze actualizări la fiecare 20 de secunde (de preferință), dar dacă există o modificare disponibilă într-o perioadă de 5 secunde, ar trebui să furnizeze și asta. În cele din urmă, am stabilit prioritatea la „PRIORITY_HIGH_ACCURACY”, printre alte opțiuni de prioritate disponibile: PRIORITY_BALANCED_POWER_ACCURACY, PRIORITY_LOW_POWER, PRIORITY_NO_POWER.

Odată ce ați creat solicitarea, sunteți gata să începeți să ascultați actualizările locației după ce metoda „onConnected()” a fost declanșată:

 protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); }

Tot ce rămâne acum este să implementați metoda de apel invers pentru a satisface interfața LocationListener:

 public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { // ... @Override public void onLocationChanged(Location location) { mLastLocation = location; Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } } 

nu mai ascultați pentru actualizări

Nu mai ascultați pentru actualizări

Este important să nu mai ascultați în mod explicit actualizările atunci când nu mai aveți nevoie de ele sau dacă utilizatorul părăsește aplicația dvs. Următoarea metodă ar trebui invocată din apelul „onPause”:

 protected void stopLocationUpdates() { if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } }

… și deconectarea API-ului Google:

 @Override protected void onStop() { super.onStop(); if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } }

Încheierea

După cum puteți vedea, ideile fundamentale din spatele implementării aplicațiilor care știe locația în Android sunt foarte simple. Mai mult decât atât, cu API-urile disponibile, care sunt atât simplu de utilizat, cât și ușor de înțeles, ar trebui să fie o idee deloc să construiești aplicații de bază bazate pe locație pentru Android. Micul exemplu de aplicație pe care l-am construit aici este menit să demonstreze exact acest lucru. Puteți găsi codul sursă complet pentru acesta pe GitHub. Vă rugăm să rețineți că, pentru a menține lucrurile simple, aplicația nu gestionează metoda de apel invers „onConnectionFailed”.

Sperăm că acest tutorial vă va ajuta să începeți să utilizați API-ul Google Location Services.