Zjišťování polohy v Androidu
V této příručce se seznámíte s rozpoznáváním polohy v aplikacích pro Android a ukážeme si, jak získat polohu uživatele pomocí rozhraní API služby zjišťování polohy androidu a také poskytovatele polohy, který je k dispozici s rozhraním API služby Google Location Services.
Android poskytuje přístup k různým technologiím umístění, jako je umístění mobilní věže, Wi-Fi a GPS. Podrobnosti o jednotlivých technologiích umístění jsou abstrahovány prostřednictvím poskytovatelů umístění, což umožňuje aplikacím získat umístění stejným způsobem bez ohledu na použitého poskytovatele. Tato příručka představuje poskytovatele polohy, který je součástí služeb Google Play, která inteligentně určuje nejlepší způsob, jak získat umístění zařízení na základě toho, jaké poskytovatele jsou k dispozici a jak se zařízení používá. Rozhraní API služby zjišťování polohy Androidu a ukazuje, jak komunikovat se službou umístění systému pomocí LocationManager
rozhraní . Druhá část příručky zkoumá rozhraní API služby Android Location Services pomocí nástroje LocationManager
.
Obecně platí, že aplikace by měly raději používat poskytovatele staveného umístění, v případě potřeby vrátit starší rozhraní API služby Android Location Service.
Základy umístění
V Androidu zůstává bez ohledu na to, jaké rozhraní API zvolíte pro práci s daty o poloze, několik konceptů stále stejné. Tato část představuje zprostředkovatele umístění a oprávnění související s umístěním.
Poskytovatelé umístění
K určení polohy uživatele se interně používá několik technologií. Použitý hardware závisí na typu poskytovatele umístění vybraného pro úlohu shromažďování dat. Android používá tři poskytovatele umístění:
GPS Poskytovatel – GPS poskytuje nejpřesnější polohu, používá nejvíce energie a funguje nejlépe venku. Tento poskytovatel používá kombinaci GPS a asistované GPS (aGPS), která vrací GPS data shromážděná mobilními věžemi.
Poskytovatel sítě – poskytuje kombinaci Wi-Fi a mobilních dat, včetně dat protokolu aGPS shromážděných mobilními věžemi. Využívá méně energie než poskytovatel GPS, ale vrací údaje o poloze s různou přesností.
Pasivní zprostředkovatel – možnost piggyback pomocí poskytovatelů požadovaných jinými aplikacemi nebo službami k vygenerování dat o poloze v aplikaci. Jedná se o méně spolehlivou, ale úspornou možnost ideální pro aplikace, které nevyžadují aktualizace konstantního umístění, aby fungovaly.
Poskytovatelé umístění nejsou vždy k dispozici. Můžeme například chtít použít GPS pro naši aplikaci, ale GPS může být vypnut v Nastavení nebo zařízení nemusí mít GPS vůbec. Pokud určitý poskytovatel není k dispozici, může volba daného poskytovatele vrátit null
.
Oprávnění k umístění
Aplikace pracující s polohou potřebuje přístup k hardwarovým senzorům zařízení pro příjem GPS, Wi-Fi a mobilních dat. Přístup se řídí příslušnými oprávněními v manifestu Android aplikace. K dispozici jsou dvě oprávnění – v závislosti na požadavcích vaší aplikace a výběru rozhraní API budete chtít povolit jednu:
ACCESS_FINE_LOCATION
– Umožňuje aplikaci přístup k GPS. Vyžaduje se pro možnosti poskytovatele GPS a pasivního poskytovatele (pasivní poskytovatel potřebuje oprávnění pro přístup k datům GPS shromážděným jinou aplikací nebo službou). Volitelné oprávnění pro poskytovatele sítě.ACCESS_COARSE_LOCATION
– Povolí aplikaci přístup k mobilní síti a wi-Fi umístění. Vyžaduje se pro poskytovatele sítě, pokudACCESS_FINE_LOCATION
není nastavený.
U aplikací, které cílí na rozhraní API verze 21 (Android 5.0 Lollipop) nebo vyšší, můžete povolit ACCESS_FINE_LOCATION
a stále běžet na zařízeních, která nemají hardware GPS. Pokud vaše aplikace vyžaduje hardware GPS, měli byste explicitně přidat android.hardware.location.gps
uses-feature
prvek do manifestu Androidu. Další informace najdete v referenčních informacích k prvkům androidu využívajících funkci .
Chcete-li nastavit oprávnění, rozbalte složku Vlastnosti v oblasti řešení a poklikejte na AndroidManifest.xml. Oprávnění budou uvedená v části Požadovaná oprávnění:
Nastavení některé z těchto oprávnění říká Androidu, že vaše aplikace potřebuje oprávnění od uživatele, aby bylo možné získat přístup k poskytovatelům umístění. Zařízení, na kterých běží rozhraní API úrovně 22 (Android 5.1) nebo nižší, požádá uživatele o udělení těchto oprávnění pokaždé, když je aplikace nainstalovaná. Na zařízeních s rozhraním API úrovně 23 (Android 6.0) nebo novějším by aplikace měla před provedením žádosti poskytovatele polohy provést kontrolu oprávnění za běhu.
Poznámka:
Poznámka: Nastavení ACCESS_FINE_LOCATION
znamená přístup k hrubým i jemným datům o poloze. Nikdy byste neměli nastavovat obě oprávnění, jenom minimální oprávnění, které vaše aplikace vyžaduje k fungování.
Tento fragment kódu je příkladem toho, jak zkontrolovat, jestli má aplikace oprávnění k ACCESS_FINE_LOCATION
oprávnění:
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.AccessFineLocation) == Permission.Granted)
{
StartRequestingLocationUpdates();
isRequestingLocationUpdates = true;
}
else
{
// The app does not have permission ACCESS_FINE_LOCATION
}
Aplikace musí být odolné vůči scénáři, kdy uživatel neudělí oprávnění (nebo ho odvolal) a má způsob, jak se s danou situací řádně vypořádat. Další podrobnosti o implementaci kontrol oprávnění za běhu v Xamarin.Androidu najdete v průvodci oprávněními oprávnění.
Použití zprostředkovatele umístění
Poskytovatel umístění je upřednostňovaným způsobem, jak aplikace pro Android přijímat aktualizace polohy ze zařízení, protože efektivně vybere poskytovatele polohy během běhu, aby poskytoval nejlepší informace o poloze efektivním způsobem baterie. Například uživatel, který chodí kolem venku, získá nejlepší polohu čtení s GPS. Pokud uživatel pak chodí uvnitř, kde GPS funguje špatně (pokud vůbec), tavený poskytovatel polohy může automaticky přepnout na Wi-Fi, což funguje lépe uvnitř.
Rozhraní API poskytovatele polohy poskytuje celou řadu dalších nástrojů, které umožňují aplikacím pracujícím s polohou, včetně monitorování geofencingu a aktivit. V této části se zaměříme na základy nastavení LocationClient
, zřizování poskytovatelů a získání polohy uživatele.
Zprostředkovatel polohy je součástí služeb Google Play. Balíček Služby Google Play musí být nainstalován a správně nakonfigurován v aplikaci, aby rozhraní API poskytovatele polohy fungovalo a zařízení musí mít nainstalovaný soubor APK služeb Google Play.
Než aplikace Xamarin.Android může použít zprostředkovatele sloučeného umístění, musí do projektu přidat balíček Xamarin.GooglePlayServices.Location . Kromě toho by měly být do všech zdrojových souborů, které odkazují na třídy popsané níže, přidány následující using
příkazy:
using Android.Gms.Common;
using Android.Gms.Location;
Kontrola, jestli je nainstalovaná služba Google Play
Xamarin.Android se chybově ukončí, pokud se pokusí použít zprostředkovatele sloučeného umístění v případě, že služba Google Play není nainstalovaná (nebo je za provozu), dojde k výjimce za běhu. Pokud služba Google Play není nainstalovaná, měla by se aplikace vrátit zpět do služby zjišťování polohy androidu, která je popsána výše. Pokud jsou služby Google Play zastaralé, aplikace může uživateli zobrazit zprávu s žádostí o aktualizaci nainstalované verze služeb Google Play.
Tento fragment kódu je příkladem toho, jak může aktivita Androidu programově zkontrolovat, jestli je nainstalovaná služba Google Play:
bool IsGooglePlayServicesInstalled()
{
var queryResult = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
if (queryResult == ConnectionResult.Success)
{
Log.Info("MainActivity", "Google Play Services is installed on this device.");
return true;
}
if (GoogleApiAvailability.Instance.IsUserResolvableError(queryResult))
{
// Check if there is a way the user can resolve the issue
var errorString = GoogleApiAvailability.Instance.GetErrorString(queryResult);
Log.Error("MainActivity", "There is a problem with Google Play Services on this device: {0} - {1}",
queryResult, errorString);
// Alternately, display the error to the user.
}
return false;
}
LocationProviderClient
Pro interakci se zprostředkovatelem lokace musí aplikace Xamarin.Android mít instanci FusedLocationProviderClient
. Tato třída zveřejňuje nezbytné metody pro přihlášení k odběru aktualizací polohy a načtení posledního známého umístění zařízení.
OnCreate
Metoda aktivity je vhodným místem pro získání odkazu na FusedLocationProviderClient
objekt , jak je znázorněno v následujícím fragmentu kódu:
public class MainActivity: AppCompatActivity
{
FusedLocationProviderClient fusedLocationProviderClient;
protected override void OnCreate(Bundle bundle)
{
fusedLocationProviderClient = LocationServices.GetFusedLocationProviderClient(this);
}
}
Získání poslední známé polohy
Tato FusedLocationProviderClient.GetLastLocationAsync()
metoda poskytuje jednoduchý neblokující způsob, jak aplikace Xamarin.Android rychle získat poslední známou polohu zařízení s minimální režií kódování.
Tento fragment kódu ukazuje, jak pomocí GetLastLocationAsync
metody načíst umístění zařízení:
async Task GetLastLocationFromDevice()
{
// This method assumes that the necessary run-time permission checks have succeeded.
getLastLocationButton.SetText(Resource.String.getting_last_location);
Android.Locations.Location location = await fusedLocationProviderClient.GetLastLocationAsync();
if (location == null)
{
// Seldom happens, but should code that handles this scenario
}
else
{
// Do something with the location
Log.Debug("Sample", "The latitude is " + location.Latitude);
}
}
Přihlášení k odběru aktualizací umístění
Aplikace Xamarin.Android se také může přihlásit k odběru aktualizací polohy od zprostředkovatele s taveným umístěním pomocí FusedLocationProviderClient.RequestLocationUpdatesAsync
metody, jak je znázorněno v tomto fragmentu kódu:
await fusedLocationProviderClient.RequestLocationUpdatesAsync(locationRequest, locationCallback);
Tato metoda má dva parametry:
Android.Gms.Location.LocationRequest
– ObjektLocationRequest
je způsob, jakým aplikace Xamarin.Android předává parametry o tom, jak by měl zprostředkovatel sloučeného umístění fungovat. ObsahujeLocationRequest
informace, jako je četnost požadavků nebo jak důležitá by měla být přesná aktualizace polohy. Například důležitý požadavek na polohu způsobí, že zařízení použije GPS a následně více energie při určování polohy. Tento fragment kódu ukazuje, jak vytvořitLocationRequest
umístění s vysokou přesností a kontrolovat přibližně každých pět minut aktualizaci umístění (ale ne dříve než dvě minuty mezi požadavky). Poskytovatel umístění s fuzí použijeLocationRequest
jako pokyny, které zprostředkovatele umístění použít při pokusu o určení umístění zařízení:LocationRequest locationRequest = new LocationRequest() .SetPriority(LocationRequest.PriorityHighAccuracy) .SetInterval(60 * 1000 * 5) .SetFastestInterval(60 * 1000 * 2);
Android.Gms.Location.LocationCallback
– Aby bylo možné přijímat aktualizace polohy, musí aplikace Xamarin.Android podtřídětLocationProvider
abstraktní třídu. Tato třída odhalila dvě metody, které je možná vyvoláno poskytovatelem sloučeného umístění k aktualizaci aplikace informacemi o poloze. Podrobněji se o tom budeme zabývat níže.
Chcete-li oznámit aplikaci Xamarin.Android o aktualizaci umístění, zprostředkovatel sloučeného umístění vyvolá LocationCallBack.OnLocationResult(LocationResult result)
. Parametr Android.Gms.Location.LocationResult
bude obsahovat informace o umístění aktualizace.
Když zprostředkovatel umístění zjistí změnu dostupnosti dat o poloze, zavolá metodu LocationProvider.OnLocationAvailability(LocationAvailability locationAvailability)
. LocationAvailability.IsLocationAvailable
Pokud se vlastnost vrátí true
, pak lze předpokládat, že výsledky polohy zařízení hlášené OnLocationResult
jsou tak přesné a aktuální, jak vyžaduje LocationRequest
. Pokud IsLocationAvailable
je false, nebudou výsledky umístění vráceny OnLocationResult
.
Tento fragment kódu je ukázkovou implementací objektu LocationCallback
:
public class FusedLocationProviderCallback : LocationCallback
{
readonly MainActivity activity;
public FusedLocationProviderCallback(MainActivity activity)
{
this.activity = activity;
}
public override void OnLocationAvailability(LocationAvailability locationAvailability)
{
Log.Debug("FusedLocationProviderSample", "IsLocationAvailable: {0}",locationAvailability.IsLocationAvailable);
}
public override void OnLocationResult(LocationResult result)
{
if (result.Locations.Any())
{
var location = result.Locations.First();
Log.Debug("Sample", "The latitude is :" + location.Latitude);
}
else
{
// No locations to work with.
}
}
}
Použití rozhraní API služby zjišťování polohy pro Android
Služba umístění androidu je starší rozhraní API pro použití informací o poloze v Androidu. Data o poloze jsou shromažďována hardwarovými senzory a shromažďovány systémovou službou, která je přístupná v aplikaci s LocationManager
třídou a třídou .ILocationListener
Služba zjišťování polohy je nejvhodnější pro aplikace, které musí běžet na zařízeních, která nemají nainstalované služby Google Play.
Služba zjišťování polohy je speciální typ služby spravované systémem. Systémová služba komunikuje s hardwarem zařízení a je vždy spuštěná. Pokud chceme v naší aplikaci klepnout na aktualizace polohy, přihlásíme se k odběru aktualizací polohy ze služby zjišťování polohy systému pomocí LocationManager
volání a RequestLocationUpdates
volání.
K získání polohy uživatele pomocí služby Android Location Service je potřeba provést několik kroků:
- Získejte odkaz na
LocationManager
službu. ILocationListener
Implementace rozhraní a zpracování událostí při změně umístěníLocationManager
Použijte k vyžádání aktualizací umístění pro zadaného poskytovatele. ZILocationListener
předchozího kroku se použije k příjmu zpětného volání z objektuLocationManager
.- Zastavte aktualizace umístění, když aplikace už není vhodná pro příjem aktualizací.
Správce umístění
Můžeme získat přístup ke službě umístění systému s instancí LocationManager
třídy. LocationManager
je speciální třída, která nám umožňuje pracovat se službou umístění systému a volat metody. Aplikace může získat odkaz na LocationManager
typ služby voláním GetSystemService
a předáním typu služby, jak je znázorněno níže:
LocationManager locationManager = (LocationManager) GetSystemService(Context.LocationService);
OnCreate
je dobré místo pro získání odkazu na LocationManager
.
Je vhodné zachovat LocationManager
proměnnou třídy jako proměnnou třídy, abychom ji mohli volat v různých bodech životního cyklu aktivity.
Žádosti o aktualizace umístění z locationManageru
Jakmile má aplikace odkaz na LocationManager
danou aplikaci, musí informovat LocationManager
o požadovaném typu informací o poloze a o tom, jak často se mají tyto informace aktualizovat. Proveďte to voláním RequestLocationUpdates
objektu LocationManager
a předáním některých kritérií pro aktualizace a zpětné volání, které obdrží aktualizace umístění. Toto zpětné volání je typ, který musí implementovat ILocationListener
rozhraní (podrobněji popsáno dále v této příručce).
Metoda RequestLocationUpdates
informuje službu umístění systému, že vaše aplikace chce začít přijímat aktualizace umístění. Tato metoda umožňuje určit poskytovatele a také prahové hodnoty času a vzdálenosti pro řízení četnosti aktualizací. Například následující metoda požaduje aktualizace polohy od poskytovatele polohy GPS každých 2000 milisekund a pouze v případě, že umístění změní více než 1 metr:
// For this example, this method is part of a class that implements ILocationListener, described below
locationManager.RequestLocationUpdates(LocationManager.GpsProvider, 2000, 1, this);
Aplikace by měla požadovat aktualizace umístění pouze tak často, jak je to nutné, aby aplikace fungovala dobře. Tím se zachová výdrž baterie a uživatel tak bude lépe fungovat.
Reagování na aktualizace z LocationManageru
Jakmile aplikace požádá o aktualizace, LocationManager
může přijímat informace ze služby implementací ILocationListener
rozhraní. Toto rozhraní poskytuje čtyři metody pro naslouchání službě umístění a poskytovateli umístění, OnLocationChanged
. Systém bude volat OnLocationChanged
, když se umístění uživatele dostatečně změní, aby se v souladu s kritérii nastavenými při žádosti o aktualizaci polohy změnilo umístění.
Následující kód ukazuje metody v ILocationListener
rozhraní:
public class MainActivity : AppCompatActivity, ILocationListener
{
TextView latitude;
TextView longitude;
public void OnLocationChanged (Location location)
{
// called when the location has been updated.
}
public OnProviderDisabled(string locationProvider)
{
// called when the user disables the provider
}
public OnProviderEnabled(string locationProvider)
{
// called when the user enables the provider
}
public OnStatusChanged(string locationProvider, Availability status, Bundle extras)
{
// called when the status of the provider changes (there are a variety of reasons for this)
}
}
Zrušení odběru aktualizací LocationManager
Aby bylo možné šetřit systémové prostředky, měla by aplikace co nejdříve odhlásit odběr aktualizací polohy. Metoda RemoveUpdates
říká LocationManager
, aby přestala odesílat aktualizace do naší aplikace. Aktivita může například volat RemoveUpdates
metodu OnPause
, abychom mohli ušetřit energii, pokud aplikace nepotřebuje aktualizace polohy, zatímco její aktivita není na obrazovce:
protected override void OnPause ()
{
base.OnPause ();
locationManager.RemoveUpdates (this);
}
Pokud vaše aplikace potřebuje získat aktualizace polohy na pozadí, budete chtít vytvořit vlastní službu, která se přihlásí k odběru služby zjišťování polohy systému. Další informace najdete v průvodci službami androidu na pozadí.
Určení nejlepšího poskytovatele umístění pro locationManager
Výše uvedená aplikace nastaví GPS jako poskytovatele polohy. GPS však nemusí být k dispozici ve všech případech, například pokud je zařízení uvnitř nebo nemá GPS přijímač. V takovém případě je null
výsledkem vrácení poskytovatele.
Pokud chcete, aby vaše aplikace fungovala, když GPS není k dispozici, použijete metodu GetBestProvider
, která při spuštění aplikace požádá o nejlepšího dostupného poskytovatele polohy (podporovaného zařízení a uživatelem). Místo předání konkrétního poskytovatele můžete požadavkům poskytovatele (například přesnosti a výkonu) sdělit GetBestProvider
objektemCriteria
. GetBestProvider
vrátí nejlepšího zprostředkovatele pro daná kritéria.
Následující kód ukazuje, jak získat nejlepšího dostupného poskytovatele a použít ho při vyžádání aktualizací umístění:
Criteria locationCriteria = new Criteria();
locationCriteria.Accuracy = Accuracy.Coarse;
locationCriteria.PowerRequirement = Power.Medium;
locationProvider = locationManager.GetBestProvider(locationCriteria, true);
if(locationProvider != null)
{
locationManager.RequestLocationUpdates (locationProvider, 2000, 1, this);
}
else
{
Log.Info(tag, "No location providers available");
}
Poznámka:
Pokud uživatel zakázal všechny poskytovatele polohy, GetBestProvider
vrátí null
. Pokud chcete zjistit, jak tento kód funguje na skutečném zařízení, nezapomeňte povolit GPS, Wi-Fi a mobilní sítě v režimu umístění > nastavení > Google, jak je znázorněno na tomto snímku obrazovky:
Následující snímek obrazovky ukazuje aplikaci umístění spuštěnou pomocí GetBestProvider
:
Mějte na paměti, že GetBestProvider
neměňí poskytovatele dynamicky. Místo toho určuje nejlepšího dostupného poskytovatele jednou během životního cyklu aktivity. Pokud se stav zprostředkovatele po nastavení změní, bude aplikace vyžadovat v ILocationListener
metodách další kód – OnProviderEnabled
OnProviderDisabled
a OnStatusChanged
– ke zpracování všech možností souvisejících s přepínačem poskytovatele.
Shrnutí
Tato příručka se zabývala získáním polohy uživatele pomocí Služby zjišťování polohy Androidu i poskytovatele polohy z rozhraní API Google Location Services.