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ń dla środowiska wykonawczego. Ważna różnica w przypadku dostępu do lokalizacji polega na tym, że system obejmuje wiele uprawnień związanych z lokalizacją. Uprawnienia, które chcesz uzyskać, i sposób ich wysyłania zależą od wymagań dotyczących lokalizacji w danym przypadku użycia.

Na tej stronie opisujemy różne typy wymagań związanych z lokalizacją i podajemy wskazówki, jak w każdym przypadku poprosić o dostęp do lokalizacji.

Rodzaje dostępu do lokalizacji

Każde uprawnienie charakteryzuje się następującymi cechami:

Lokalizacja na pierwszym planie

Jeśli aplikacja zawiera funkcję, która udostępnia lub otrzymuje 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 nawigacji zakręt po zakręcie dostępna w aplikacji nawigacyjnej.
  • Funkcja w aplikacji do obsługi wiadomości umożliwia udostępnianie bieżącej lokalizacji innemu użytkownikowi.

System uznaje, że aplikacja korzysta z lokalizacji na pierwszym planie, jeśli jej funkcja uzyskuje dostęp do bieżącej lokalizacji urządzenia w jednej z tych sytuacji:

  • Widoczna będzie aktywność, która należy do Twojej aplikacji.
  • Twoja aplikacja działa na pierwszym planie. Gdy usługa działa na pierwszym planie, system podnosi świadomość użytkownika, wyświetlając stałe powiadomienie. Aplikacja zachowuje dostęp, gdy jest umieszczona w tle, na przykład gdy użytkownik naciśnie przycisk ekranu głównego na urządzeniu lub wyłączy wyświetlacz urządzenia.

    Zalecamy też zadeklarowanie typu usługi na pierwszym planie o wartości location, jak pokazano w tym 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ę korzystania z lokalizacji na pierwszym planie, gdy aplikacja prosi o uprawnienie ACCESS_COARSE_LOCATION lub ACCESS_FINE_LOCATION, tak jak 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 używa interfejsu API geofencingu. Oto kilka przykładów:

  • Funkcja dostępna w aplikacji do udostępniania lokalizacji w grupie rodzinnej umożliwia użytkownikom ciągłe udostępnianie lokalizacji członkom grupy rodzinnej.
  • Funkcja dostępna w aplikacji IoT, która umożliwia użytkownikom konfigurowanie urządzeń domowych w taki sposób, aby wyłączały się, gdy użytkownik wyjdzie z domu, i włączały je ponownie po powrocie do domu.

System uznaje, że aplikacja korzysta z lokalizacji w tle, jeśli uzyskuje dostęp do bieżącej lokalizacji urządzenia w sytuacji innej niż opisana w sekcji lokalizacja na pierwszym planie. Dokładność lokalizacji w tle jest taka sama jak dokładność lokalizacji na pierwszym planie, która zależy od uprawnień dostępu do lokalizacji zadeklarowanych przez aplikację.

W Androidzie 10 (poziom interfejsu API 29) i nowszych musisz zadeklarować uprawnienie ACCESS_BACKGROUND_LOCATION w pliku manifestu aplikacji, aby prosić o dostęp do lokalizacji w tle w czasie działania. Na wcześniejszych wersjach Androida, gdy aplikacja uzyskuje dostęp do lokalizacji na pierwszym planie, automatycznie otrzymuje też dostęp do lokalizacji w tle.

<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
Podaje szacunkową lokalizację urządzenia. Jeśli przybliżona lokalizacja szacowana na podstawie danych z zakresu LocationManagerService lub FusedLocationProvider, jest dokładna z dokładnością do około 3 kilometrów kwadratowych. Aplikacja może otrzymywać lokalizacje z taką dokładnością, jeśli zadeklarujesz uprawnienie ACCESS_COARSE_LOCATION, ale nie ACCESS_FINE_LOCATION.
Dokładna
Udostępnia możliwie najdokładniejszą lokalizację urządzenia. Jeśli orientacyjna lokalizacja jest z zakresu LocationManagerService lub FusedLocationProvider, zwykle mieści się w odległości do około 50 metrów, a czasami jest z dokładnością do kilku metrów. Po zadeklarowaniu uprawnienia ACCESS_FINE_LOCATION aplikacja może otrzymywać lokalizacje z taką dokładnością.

Jeśli użytkownik przyzna dostęp do lokalizacji przybliżonej, aplikacja ma dostęp tylko do tej przybliżonej lokalizacji, niezależnie od tego, jakie uprawnienia deklaruje.

Aplikacja powinna nadal działać, gdy użytkownik przyzna dostęp tylko przybliżonej lokalizacji. Jeśli jakaś funkcja Twojej aplikacji bezwzględnie 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 w czasie działania

Jeśli funkcja aplikacji wymaga dostępu do lokalizacji, zanim poprosisz o uprawnienia, poczekaj, aż użytkownik wejdzie z nią w interakcję. Ten przepływ pracy jest zgodny ze sprawdzonymi metodami dotyczącymi proszenia o uprawnienia w czasie działania aplikacji. Opisaliśmy to w przewodniku, z którego dowiesz się, jak poprosić o uprawnienia aplikacji.

Rysunek 1 przedstawia przykład tego procesu. Aplikacja zawiera funkcję udostępniania lokalizacji, która wymaga dostępu do lokalizacji na pierwszym planie. Aplikacja nie prosi jednak o dostęp do lokalizacji, dopóki użytkownik nie kliknie przycisku Udostępnij lokalizację.

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

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

Na Androidzie 12 (poziom interfejsu API 31) i nowszych użytkownicy mogą poprosić o pobranie przez aplikację tylko przybliżonych informacji o lokalizacji, nawet jeśli prosi ona o uprawnienie związane z czasem działania ACCESS_FINE_LOCATION.

Aby uwzględnić to potencjalne zachowanie użytkownika, nie żądaj samego uprawnienia ACCESS_FINE_LOCATION. Zamiast tego poproś w jednym żądaniu środowiska wykonawczego zarówno o uprawnienia ACCESS_FINE_LOCATION, jak i o ACCESS_COARSE_LOCATION. Jeśli spróbujesz wysłać żądanie tylko ACCESS_FINE_LOCATION, w niektórych wersjach Androida 12 system zignoruje to żądanie. Jeśli Twoja aplikacja jest kierowana na Androida w wersji 12 lub nowszej, system zarejestruje w Logcat ten komunikat o błędzie:

ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.

Gdy aplikacja prosi zarówno o ACCESS_FINE_LOCATION, jak i ACCESS_COARSE_LOCATION, w oknie uprawnień systemowych zobaczysz te opcje:

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

Rysunek 3 pokazuje, że okno zawiera wizualną wskazówkę dotyczącą obu opcji, aby ułatwić użytkownikowi wybór. Gdy użytkownik określi dokładność lokalizacji, klika 1 z 3 przycisków, aby określić czas obowiązywania uprawnień.

Na Androidzie 12 i nowszych użytkownicy mogą przejść do ustawień systemu, aby ustawić dokładność preferowanej 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 użytkownik uaktualni 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 tylko o ACCESS_COARSE_LOCATION.
Okno zawiera 2 zestawy opcji, jedną nad drugą
Rysunek 3. Okno uprawnień systemowych, które pojawia się, gdy aplikacja prosi o ACCESS_FINE_LOCATION i ACCESS_COARSE_LOCATION w jednym żądaniu w czasie działania.

Wybór użytkownika wpływa na przyznane uprawnienia

W tabeli poniżej znajdziesz uprawnienia przyznane aplikacji przez system na podstawie opcji wybranych przez użytkownika w oknie czasu działania uprawnień:

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ć uprawnienia przyznane aplikacji przez system, sprawdź wartość zwracaną przez żądanie uprawnień. Możesz używać bibliotek Jetpack w kodzie podobnym do tego poniżej lub korzystać z bibliotek platform, gdzie samodzielnie zarządzasz kodem żądania uprawnień.

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 przejście na dokładną lokalizację

Możesz poprosić użytkownika o uaktualnienie dostępu aplikacji z przybliżonej lokalizacji do dokładnej. Zanim poprosisz użytkownika o uaktualnienie dostępu aplikacji do dokładnej lokalizacji, zastanów się, czy jej przypadek użycia bezwzględnie wymaga 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ę dostępu do lokalizacji z przybliżonej na dokładną, wykonaj te czynności:

  1. Jeśli to konieczne, wyjaśnij, dlaczego aplikacja potrzebuje odpowiednich uprawnień.
  2. Ponownie poproś o uprawnienia ACCESS_FINE_LOCATION i ACCESS_COARSE_LOCATION. Użytkownik pozwolił już systemowi na przypisanie Twojej aplikacji przybliżonej lokalizacji, więc tym razem okno systemowe jest inne, jak widać na rysunkach 4 i rysunkach 5:
Okno zawiera opcje „Zmień na dokładną lokalizację”, „Tylko tym razem” i „Odrzucaj”.
Rysunek 4. Użytkownik poprzednio wybrał Przybliżone i Podczas używania aplikacji (w oknie dialogowym z figure 3).
Okno zawiera opcje „Tylko tym razem” i „Odrzucaj”.
Rysunek 5. Użytkownik poprzednio wybrał Przybliżone i Tylko tym razem (w oknie z rysunku 3).

Początkowo poproś o lokalizację tylko na pierwszym planie

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

Rysunek 6 przedstawia przykład aplikacji, która obsługuje żądania przyrostowe. Zarówno funkcje „Pokaż bieżącą lokalizację”, jak i „Polecaj miejsca w pobliżu” wymagają dostępu do lokalizacji na pierwszym planie. Tylko funkcja „Polecaj miejsca w pobliżu” wymaga dostępu do lokalizacji w tle.

Przycisk umożliwiający dostęp do lokalizacji na pierwszym planie znajduje się o połowę długości ekranu od przycisku umożliwiającego dostęp do lokalizacji w tle
Rysunek 6. Obie funkcje wymagają dostępu do lokalizacji, ale tylko funkcja polecania obiektów w pobliżu wymaga dostępu do lokalizacji w tle.

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

  1. Początkowo aplikacja powinna wskazywać użytkownikom funkcje, które wymagają dostępu do lokalizacji na pierwszym planie, takie jak „udostępnianie lokalizacji” na Rysunku 1 czy „pokaż bieżącą lokalizację” na Rysunku 2.

    Zalecamy wyłączenie dostępu użytkowników do funkcji, które wymagają dostępu do lokalizacji w tle, dopóki aplikacja nie uzyska dostępu do lokalizacji na pierwszym planie.

  2. Gdy później użytkownik sprawdzi funkcję, która wymaga dostępu do lokalizacji w tle, możesz poprosić o dostęp do lokalizacji w tle.

W razie potrzeby poproś o lokalizację 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ń systemowych pojawia się opcja Zawsze zezwalaj. Jeśli użytkownik wybierze tę opcję, funkcja aplikacji uzyska dostęp do lokalizacji w tle.

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

Aby ułatwić użytkownikom przejście na tę stronę ustawień, postępuj zgodnie ze sprawdzonymi metodami dotyczącymi wysyłania prośby 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 ma uprawnień ACCESS_BACKGROUND_LOCATION, ale shouldShowRequestPermissionRationale() zwraca wartość true, pokaż użytkownikom interfejs edukacyjny, który zawiera:

  • jasne wyjaśnienie, dlaczego funkcja aplikacji wymaga dostępu do lokalizacji w tle;
  • Widoczna dla użytkownika etykieta opcji ustawień, która przyznaje lokalizację w tle (np. Zawsze zezwalaj na ilustracji 7). Aby uzyskać tę etykietę, możesz wywołać metodę getBackgroundPermissionOptionLabel(). Wartość zwracana przez tę metodę jest lokalizowana zgodnie z językiem ustawionym na urządzeniu użytkownika.
  • opcja umożliwiająca użytkownikom odrzucenie tych uprawnień. Jeśli użytkownicy odmówią dostępu do lokalizacji w tle, dalej będą mogli korzystać z Twojej aplikacji.
Użytkownicy mogą kliknąć powiadomienie systemowe, aby zmienić ustawienia lokalizacji określonej dla aplikacji
Rysunek 8. Powiadomienie przypominające użytkownikowi, że zezwolił aplikacji na dostęp do lokalizacji w tle.

Aplikacja jest kierowana na Androida 10 lub starszego

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

Jeśli Twoja aplikacja jest już zgodna ze sprawdzonymi metodami dotyczącymi wysyłania próśb o dostęp do lokalizacji, nie musisz wprowadzać żadnych zmian, aby obsługiwać to działanie.

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

Jeśli użytkownik prosi o przybliżoną lokalizację, jego wybór w oknie dostępu do lokalizacji dotyczy też lokalizacji w tle. Inaczej mówiąc, jeśli użytkownik przyzna Twojej aplikacji uprawnienie ACCESS_BACKGROUND_LOCATION, ale dostęp do lokalizacji na pierwszym planie przyzna tylko przybliżony dostęp do lokalizacji, aplikacja też będzie mieć dostęp do lokalizacji w tle tylko w przybliżeniu.

Przypomnienie o przyznaniu lokalizacji w tle

Na Androidzie 10 i nowszych, gdy po raz pierwszy funkcja aplikacji uzyska dostęp do lokalizacji urządzenia w tle po przyznaniu przez użytkownika dostępu do lokalizacji w tle, system zaplanuje wysłanie do niego powiadomienia. To powiadomienie przypomina użytkownikowi, że wciąż zezwalał aplikacji na dostęp do lokalizacji urządzenia. Przykładowe powiadomienie jest przedstawione na rys. 8.

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

Sprawdź, czy Twoja aplikacja korzysta z pakietów SDK, które wymagają dostępu do lokalizacji, a zwłaszcza uprawnienia ACCESS_FINE_LOCATION. Przeczytaj artykuł na temat Medium o poznawaniu zależności między pakietem 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