Poproś o dostęp do lokalizacji

Aby chronić prywatność użytkownika, aplikacje korzystające z usług lokalizacyjnych muszą prosić o dostęp do lokalizacji.

Gdy prosisz o dostęp do lokalizacji, postępuj zgodnie z tymi samymi sprawdzonymi metodami, co w przypadku innych uprawnień środowiska wykonawczego. Ważna różnica dotycząca dostępu do lokalizacji polega na tym, że system obejmuje wiele uprawnień związanych z lokalizacją. To, które uprawnienia chcesz uzyskać i w jaki sposób o nie prosisz, zależą od wymagań dotyczących lokalizacji w danym przypadku użycia aplikacji.

Na tej stronie opisujemy różne typy wymagań dotyczących lokalizacji oraz podajemy wskazówki, jak w każdym z tych przypadków prosić o dostęp do lokalizacji.

Rodzaje dostępu do lokalizacji

Każde uprawnienie ma następujące cechy:

Lokalizacja na pierwszym planie

Jeśli aplikacja zawiera funkcję, która udostępnia lub odbiera informacje o lokalizacji tylko raz lub przez określony czas, wymaga ona dostępu do lokalizacji na pierwszym planie. Oto kilka przykładów:

  • Funkcja w aplikacji do nawigacji umożliwia użytkownikom otrzymywanie szczegółowych wskazówek dojazdu.
  • Funkcja w aplikacji do obsługi wiadomości umożliwia użytkownikom udostępnianie swojej bieżącej lokalizacji innemu użytkownikowi.

System uznaje aplikację za używaną na pierwszym planie, jeśli jakaś funkcja uzyskuje dostęp do bieżącej lokalizacji urządzenia w jednej z tych sytuacji:

  • Widoczna jest aktywność należąca do Twojej aplikacji.
  • Twoja aplikacja działa na pierwszym planie. Gdy usługa na pierwszym planie jest uruchomiona, system informuje użytkowników o tym, wyświetlając trwałe powiadomienie. Aplikacja zachowuje dostęp, gdy jest działająca w tle, na przykład gdy użytkownik naciśnie przycisk ekranu głównego na urządzeniu lub wyłączy wyświetlacz.

    Zalecamy też zadeklarowanie typu usługi na pierwszym planie o wartości location, jak pokazano w poniższym fragmencie kodu. W Androidzie 10 (poziom interfejsu API 29) i nowszych musisz zadeklarować ten typ usługi na pierwszym planie.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements would go here. -->
    </service>
    

Deklarujesz potrzebę dostępu do lokalizacji na pierwszym planie, gdy Twoja aplikacja prosi o uprawnienie ACCESS_COARSE_LOCATION lub ACCESS_FINE_LOCATION, jak pokazano w tym fragmencie:

<manifest ... >
  <!-- Always include this permission -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Lokalizacja w tle

Aplikacja wymaga dostępu do lokalizacji w tle, jeśli jej funkcja stale udostępnia lokalizację innym użytkownikom lub korzysta z interfejsu Geofencing API. Oto kilka przykładów:

  • Funkcja w aplikacji do udostępniania lokalizacji w grupie rodzinnej pozwala użytkownikom na bieżąco udostępniać lokalizację członkom grupy rodzinnej.
  • Funkcja w aplikacji IoT umożliwia użytkownikom takie skonfigurowanie urządzeń domowych, aby wyłączały się, gdy użytkownik wychodziły z domu, i włączały się ponownie, gdy użytkownik wraca do domu.

System uznaje, że aplikacja używa lokalizacji w tle, jeśli uzyskuje dostęp do bieżącej lokalizacji urządzenia w sytuacjach innych niż opisane w sekcji dotyczącej lokalizacji na pierwszym planie. Dokładność lokalizacji w tle jest taka sama jak dokładność lokalizacji na pierwszym planie, która zależy od zadeklarowanych przez aplikację uprawnień do lokalizacji.

Aby w czasie działania aplikacji prosić o dostęp do lokalizacji w tle na Androidzie 10 (poziom interfejsu API 29) i nowszym, musisz zadeklarować uprawnienia ACCESS_BACKGROUND_LOCATION w pliku manifestu aplikacji. We wcześniejszych wersjach Androida aplikacja automatycznie uzyskuje również dostęp do lokalizacji w tle, gdy otrzymuje dostęp do lokalizacji na pierwszym planie.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Dokładność

Android obsługuje następujące poziomy dokładności lokalizacji:

Przybliżona
Udostępnia przybliżoną lokalizację urządzenia. Jeśli szacowana lokalizacja pochodzi z regionu LocationManagerService lub FusedLocationProvider, jest przewidywana z dokładnością do około 3 kilometrów kwadratowych. Jeśli zadeklarujesz uprawnienie ACCESS_COARSE_LOCATION, Twoja aplikacja może otrzymywać lokalizacje z taką dokładnością, ale nie ACCESS_FINE_LOCATION.
Dokładna
Udostępnia najdokładniejszą orientacyjną lokalizację urządzenia. Jeśli lokalizacja szacowana jest z LocationManagerService lub FusedLocationProvider, zwykle mieści się w odległości około 50 metrów, a czasami jest równie dokładna, jak kilka metrów (10 metrów) lub nawet lepsza. Gdy zadeklarujesz uprawnienie ACCESS_FINE_LOCATION, Twoja aplikacja będzie mogła otrzymywać lokalizacje z taką dokładnością.

Jeśli użytkownik przyzna dostęp do przybliżonej lokalizacji, aplikacja będzie mieć dostęp tylko do przybliżonej lokalizacji niezależnie od tego, które uprawnienia dotyczące lokalizacji deklaruje.

Aplikacja powinna nadal działać, gdy użytkownik przyzna tylko dostęp do przybliżonej lokalizacji. Jeśli funkcja aplikacji absolutnie wymaga dostępu do dokładnej lokalizacji za pomocą uprawnienia ACCESS_FINE_LOCATION, możesz poprosić użytkownika o zezwolenie aplikacji na dostęp do dokładnej lokalizacji.

Wysyłanie prośby o dostęp do lokalizacji podczas działania

Gdy funkcja w aplikacji wymaga dostępu do lokalizacji, przed wysłaniem prośby o uprawnienia poczekaj, aż użytkownik wejdzie z nią w interakcję. Ten przepływ pracy jest zgodny ze sprawdzonymi metodami wysyłania próśb o przyznanie uprawnień czasu działania w kontekście, co opisano w przewodniku, który wyjaśnia, jak wysyłać prośby o uprawnienia aplikacji.

Ilustracja 1 pokazuje, jak to zrobić. Aplikacja ma funkcję „udostępniania lokalizacji”, która wymaga dostępu do lokalizacji na pierwszym planie. Aplikacja nie prosi o dostęp do lokalizacji, dopóki użytkownik nie kliknie przycisku Udostępnij lokalizację.

Gdy użytkownik wybierze przycisk Udostępnij lokalizację, pojawi się okno dialogowe przyznawania dostępu do lokalizacji w systemie
Rysunek 1. Funkcja udostępniania lokalizacji, która wymaga dostępu do lokalizacji na pierwszym planie. Funkcja zostanie włączona, jeśli użytkownik wybierze Zezwalaj tylko podczas używania aplikacji.

Użytkownik może przyznawać tylko przybliżoną lokalizację

Na Androidzie 12 (poziom interfejsu API 31) lub nowszym użytkownicy mogą prosić o pobranie przez aplikację tylko przybliżonych informacji o lokalizacji, nawet jeśli aplikacja prosi o przyznanie uprawnień środowiska wykonawczego ACCESS_FINE_LOCATION.

Aby obsłużyć takie potencjalne zachowanie użytkowników, nie żądaj samego uprawnienia ACCESS_FINE_LOCATION. Zamiast tego w jednym żądaniu środowiska wykonawczego poproś zarówno o uprawnienie ACCESS_FINE_LOCATION, jak i uprawnienie ACCESS_COARSE_LOCATION. Jeśli spróbujesz poprosić tylko o ACCESS_FINE_LOCATION, system zignoruje ją w niektórych wersjach Androida 12. Jeśli Twoja aplikacja jest kierowana na Androida 12 lub nowszego, system rejestruje w Logcat ten komunikat o błędzie:

ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.

Gdy aplikacja żąda zarówno ACCESS_FINE_LOCATION, jak i ACCESS_COARSE_LOCATION, okno uprawnień systemowych będzie zawierać te opcje dla użytkownika:

  • Dokładna: umożliwia aplikacji uzyskiwanie dokładnych informacji o lokalizacji.
  • Przybliżona: umożliwia aplikacji pobieranie tylko informacji o przybliżonej lokalizacji.

Rysunek 3 pokazuje, że okno zawiera podpowiedź dla obu opcji, aby pomóc użytkownikowi dokonać wyboru. Gdy użytkownik określi dokładność lokalizacji, klika 1 z 3 przycisków, aby wybrać czas obowiązywania zezwolenia.

Na urządzeniach z Androidem 12 i nowszym użytkownicy mogą przejść do ustawień systemu, aby ustawić preferowaną dokładność lokalizacji dla każdej aplikacji, niezależnie od jej docelowej wersji pakietu SDK. Dzieje się tak nawet wtedy, gdy aplikacja jest zainstalowana na urządzeniu z Androidem 11 lub starszym, a następnie użytkownik aktualizuje urządzenie do Androida 12 lub nowszego.

Okno odnosi się tylko do przybliżonej lokalizacji i zawiera 3 przyciski, jeden nad drugim
Rysunek 2. Okno uprawnień systemowych, które pojawia się, gdy aplikacja prosi o dostęp tylko do ACCESS_COARSE_LOCATION.
Okno zawiera 2 zestawy opcji, jeden nad drugim
Rysunek 3. Okno uprawnień systemowych, które pojawia się, gdy aplikacja poprosi o uprawnienia ACCESS_FINE_LOCATION i ACCESS_COARSE_LOCATION w jednym żądaniu w czasie działania.

Wybór użytkownika wpływa na przyznawanie uprawnień

Tabela poniżej zawiera uprawnienia przyznane aplikacji przez system na podstawie opcji wybranych przez użytkownika w oknie uprawnień w środowisku wykonawczym:

Dokładna Przybliżona
Podczas używania aplikacji ACCESS_FINE_LOCATION i
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Tylko tym razem ACCESS_FINE_LOCATION i
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Odmów Brak dostępu do lokalizacji Brak dostępu do lokalizacji

Aby określić, które uprawnienia aplikacji przyznał system, sprawdź wartość zwracaną w prośbie o uprawnienia. Możesz użyć bibliotek Jetpack w kodzie podobnym do tego poniżej lub użyć bibliotek platformy, gdzie samodzielnie zarządzasz kodem prośby o uprawnienia.

Kotlin

val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Precise location access granted.
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Only approximate location access granted.
            } else -> {
                // No location access granted.
            }
        }
    }

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

Java

ActivityResultLauncher<String[]> locationPermissionRequest =
    registerForActivityResult(new ActivityResultContracts
        .RequestMultiplePermissions(), result -> {
            Boolean fineLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_FINE_LOCATION, false);
            Boolean coarseLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_COARSE_LOCATION,false);
            if (fineLocationGranted != null && fineLocationGranted) {
                // Precise location access granted.
            } else if (coarseLocationGranted != null && coarseLocationGranted) {
                // Only approximate location access granted.
            } else {
                // No location access granted.
            }
        }
    );

// ...

// Before you perform the actual permission request, check whether your app
// already has the permissions, and whether your app needs to show a permission
// rationale dialog. For more details, see Request permissions.
locationPermissionRequest.launch(new String[] {
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION
});

Poproś o podniesienie dokładnej lokalizacji

Możesz poprosić użytkownika o zmianę dostępu do aplikacji z przybliżonej na dokładną lokalizację. Zanim poprosisz użytkownika o zwiększenie dostępu aplikacji do dokładnej lokalizacji, zastanów się, czy jej zastosowanie wymaga absolutnie takiego poziomu dokładności. Jeśli Twoja aplikacja musi sparować urządzenie z urządzeniami w pobliżu przez Bluetooth lub Wi-Fi, rozważ skorzystanie z parowania urządzeń towarzyszących lub uprawnień Bluetooth, zamiast prosić o uprawnienia ACCESS_FINE_LOCATION.

Aby poprosić użytkownika o zmianę przybliżonej lokalizacji w dostępie do lokalizacji, wykonaj te czynności:

  1. Jeśli to konieczne, wyjaśnij, dlaczego aplikacja wymaga danego uprawnienia.
  2. Poproś ponownie o uprawnienia ACCESS_FINE_LOCATION i ACCESS_COARSE_LOCATION. Ponieważ użytkownik zezwolił już systemowi na przyznawanie Twojej aplikacji przybliżonej lokalizacji, okno dialogowe systemu jest tym razem inne, co pokazuje ilustracje 4 i rysunki 5:
To okno zawiera opcje „Zmień na dokładną lokalizację”, „Tylko tym razem” i „Odmów”.
Rysunek 4. Użytkownik wcześniej wybrał opcje Przybliżone i Podczas używania aplikacji (w oknie z ilustracji 3).
To okno zawiera opcje „Tylko tym razem” i „Odrzuć”.
Rysunek 5. Użytkownik wcześniej wybrał opcje Przybliżone i Tylko tym razem (w oknie z ilustracji 3).

Początkowo żądaj tylko lokalizacji na pierwszym planie

Nawet jeśli kilka funkcji aplikacji wymaga dostępu do lokalizacji, prawdopodobnie tylko niektóre z nich wymagają dostępu do lokalizacji w tle. Dlatego zalecamy, aby aplikacja wysyłała żądania przyrostowe uprawnień do lokalizacji, prosząc o dostęp do lokalizacji na pierwszym planie, a następnie o dostęp do lokalizacji w tle. Wykonując żądania przyrostowe, dajesz użytkownikom większą kontrolę i większą przejrzystość, ponieważ mogą lepiej zrozumieć, które funkcje aplikacji wymagają dostępu do lokalizacji w tle.

Rysunek 6 przedstawia przykład aplikacji zaprojektowanej do obsługi żądań przyrostowych. Funkcje „Pokaż bieżącą lokalizację” i „Poleć miejsca w pobliżu” wymagają dostępu do lokalizacji na pierwszym planie. Tylko funkcja „Poleć miejsca w pobliżu” wymaga dostępu do lokalizacji w tle.

Przycisk włączający dostęp do lokalizacji na pierwszym planie znajduje się o połowę długości ekranu od przycisku, który włącza lokalizację w tle.
Rysunek 6. Obie funkcje wymagają dostępu do lokalizacji, ale tylko funkcja „Poleć funkcje w pobliżu” wymaga dostępu do lokalizacji w tle.

Proces wykonywania żądań przyrostowych wygląda tak:

  1. Aplikacja powinna najpierw pokazać użytkownikom funkcje, które wymagają dostępu do lokalizacji na pierwszym planie, takie jak „udostępnianie lokalizacji” na rys. 1 czy „pokaż bieżącą lokalizację” na rys. 2.

    Zalecamy wyłączenie dostępu użytkowników do funkcji, które wymagają dostępu do lokalizacji w tle, do czasu, aż aplikacja uzyska taki dostęp.

  2. Później, gdy użytkownik sprawdzi funkcje, które wymagają dostępu do lokalizacji w tle, możesz poprosić o dostęp do lokalizacji w tle.

W razie potrzeby poproś o dostęp do lokalizacji w tle

Rysunek 7. Strona ustawień zawiera opcję Zawsze zezwalaj, która przyznaje dostęp do lokalizacji w tle.

Zawartość okna uprawnień zależy od docelowej wersji pakietu SDK

Gdy funkcja aplikacji prosi o dostęp do lokalizacji w tle na urządzeniu z Androidem 10 (poziom interfejsu API 29), w oknie uprawnień systemu pojawi się opcja Zawsze zezwalaj. Jeśli użytkownik wybierze tę opcję, funkcja aplikacji uzyska dostęp do lokalizacji w tle.

W Androidzie 11 (poziom interfejsu API 30) i nowszych w oknie systemowym nie ma jednak opcji Zawsze zezwalaj. Zamiast tego użytkownicy muszą włączyć lokalizację w tle na stronie ustawień, jak pokazano na rys. 7.

Możesz pomóc użytkownikom przejść na tę stronę ustawień, stosując sprawdzone metody wysyłania próśb o dostęp do lokalizacji w tle. Proces przyznawania uprawnień zależy od docelowej wersji pakietu SDK aplikacji.

Aplikacja jest kierowana na Androida 11 lub nowszego

Jeśli Twoja aplikacja nie otrzymała uprawnienia ACCESS_BACKGROUND_LOCATION, a shouldShowRequestPermissionRationale() zwraca true, pokaż użytkownikom interfejs edukacyjny zawierający te informacje:

  • jasne wyjaśnienie, dlaczego funkcja aplikacji potrzebuje dostępu do lokalizacji w tle;
  • Widoczna dla użytkownika etykieta opcji ustawień, która umożliwia określanie lokalizacji w tle (np. Zawsze zezwalaj na ilustracji 7). Aby pobrać tę etykietę, możesz wywołać metodę getBackgroundPermissionOptionLabel(). Zwracana wartość tej metody jest zlokalizowana zgodnie z ustawieniami języka na urządzeniu użytkownika.
  • opcja odmowy uprawnień przez użytkowników; Jeśli użytkownicy odmówią dostępu do lokalizacji w tle, powinni mieć możliwość dalszego korzystania z aplikacji.
Użytkownik może kliknąć powiadomienie systemowe, aby zmienić ustawienia lokalizacji w aplikacji
Rysunek 8. Powiadomienie przypominające użytkownikowi, że przyznał aplikacji dostęp do lokalizacji w tle.

Aplikacja jest kierowana na Androida 10 lub starszego

Gdy funkcja aplikacji poprosi o dostęp do lokalizacji w tle, użytkownicy zobaczą okno systemowe. To okno zawiera opcję przejścia do opcji dostępu do lokalizacji dla aplikacji na stronie ustawień.

Jeśli Twoja aplikacja jest już zgodna ze sprawdzonymi metodami wysyłania próśb o dostęp do lokalizacji, nie musisz wprowadzać żadnych zmian, aby to umożliwić.

Użytkownik może wpływać na dokładność lokalizacji w tle

Jeśli użytkownik prosi o przybliżoną lokalizację, wybór użytkownika określony w oknie uprawnień do lokalizacji ma również zastosowanie do lokalizacji w tle. Inaczej mówiąc, jeśli użytkownik przyznał aplikacji uprawnienia ACCESS_BACKGROUND_LOCATION, ale przyznaje tylko dostęp do przybliżonej lokalizacji na pierwszym planie, aplikacja również ma dostęp do przybliżonej lokalizacji w tle.

Przypomnienie o przyznaniu lokalizacji w tle

Na Androidzie 10 i nowszych, gdy funkcja aplikacji po raz pierwszy przyzna dostęp do lokalizacji urządzenia w tle, system zaplanuje wysłanie do użytkownika powiadomienia. To powiadomienie przypomina użytkownikowi, że zezwala aplikacji na stały dostęp do lokalizacji urządzenia. Przykładowe powiadomienie wyświetla się na rys. 8.

Sprawdź wymagania dotyczące lokalizacji w zależnościach pakietu SDK aplikacji

Sprawdź, czy Twoja aplikacja korzysta z pakietów SDK zależnych od dostępu do lokalizacji (a zwłaszcza z uprawnienia ACCESS_FINE_LOCATION). Zapoznaj się z tym artykułem w Medium o poznawaniu zachowań zależności SDK.

Dodatkowe materiały

Więcej informacji o dostępie do lokalizacji w Androidzie znajdziesz w tych materiałach:

Ćwiczenia z programowania

Filmy

Próbki