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. Jedną z ważnych różnic w przypadku uprawnień dotyczących lokalizacji jest to, ż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 i podajemy wskazówki, jak w każdym przypadku poprosić o dostęp do lokalizacji.

Rodzaje dostępu do lokalizacji

Każde uprawnienie ma kombinację tych cech:

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, funkcja ta wymaga dostępu do lokalizacji na pierwszym planie. Oto kilka przykładów:

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

System uznaje, że aplikacja używa lokalizacji na pierwszym planie, jeśli jej funkcja uzyskuje dostęp do bieżącej lokalizacji urządzenia w jednym z tych przypadków:

  • 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.

    Dodatkowo zalecamy zadeklarowanie typu usługi na pierwszym planie 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ę 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 API do tworzenia geoogrodzenia. 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 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 deklarowanych przez aplikację uprawnień do lokalizacji.

W Androidzie 10 (interfejs API na poziomie 29) i nowszych musisz zadeklarować uprawnienie ACCESS_BACKGROUND_LOCATION w pliku manifestu aplikacji, aby poprosić o dostęp do lokalizacji w tle w czasie działania. W starszych wersjach Androida, gdy aplikacja uzyska dostęp do lokalizacji na pierwszym planie, automatycznie uzyska 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:

W przybliżeniu
Podaje 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ładnie
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 uprawnienia do przybliżonej lokalizacji, aplikacja ma dostęp tylko do przybliżonej lokalizacji, niezależnie od tego, jakie uprawnienia do lokalizacji deklaruje.

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

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

Jeśli funkcja w aplikacji wymaga dostępu do lokalizacji, poczekaj, aż użytkownik zacznie z niej korzystać, a dopiero potem poproś o uprawnienia. Ten proces jest zgodny ze sprawdzoną metodą polegającą na prośbach o uprawnienia w kontekście, jak opisano w przewodniku Prośby o uprawnienia aplikacji.

Rysunek 1 przedstawia przykładowy sposób wykonania tej procedury. Aplikacja ma funkcję „udostępniania lokalizacji”, która wymaga dostępu do lokalizacji na pierwszym planie. Aplikacja nie poprosi 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 jest włączona, jeśli użytkownik wybierze Zezwalaj tylko podczas używania aplikacji.

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

W Androidzie 12 (poziom API 31) lub nowszym użytkownicy mogą poprosić aplikację o pobieranie tylko przybliżonych informacji o lokalizacji, nawet jeśli aplikacja poprosi o uprawnienia w czasie działania.

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 wysłać prośbę tylko z parametrem 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 prosi o uprawnienia ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION, w oknie uprawnień systemowych użytkownik ma do wyboru te opcje:

  • Dokładna: aplikacja może uzyskać dokładne informacje o lokalizacji.
  • Przybliżona: aplikacja może uzyskać tylko przybliżone informacje o lokalizacji.

Rysunek 3 pokazuje, że okno zawiera wizualne wskazówki dotyczące obu opcji, aby ułatwić użytkownikowi dokonanie 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 do ACCESS_COARSE_LOCATION.
Okno zawiera 2 zestawy opcji, jeden nad drugim
Rysunek 3. Okno uprawnień systemowych, które pojawia się, gdy aplikacja prosi o dostęp do ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION w jednym żądaniu w czasie działania.

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

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

Dokładnie W przybliżeniu
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
Odrzuć Brak uprawnień do lokalizacji Brak dostępu do lokalizacji

Aby określić, które uprawnienia aplikacji przyznał system, sprawdź wartość zwracaną w prośbie o uprawnienia. W kodzie możesz użyć bibliotek Jetpacka podobnych do tego przykładu lub bibliotek platformy, w których 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ę uprawnień dostępu aplikacji z dostępu do przybliżonej lokalizacji na dokładną lokalizację. Zanim poprosisz użytkownika o udostępnienie aplikacji dostępu do dokładnej lokalizacji, zastanów się, czy w danym przypadku konieczny jest taki poziom 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ę z przybliżonego na dokładny dostępu aplikacji do lokalizacji:

  1. Jeśli to konieczne, wyjaśnij, dlaczego aplikacja wymaga danego uprawnienia.
  2. Poproś o uprawnienia ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION ponownie. 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).
W oknie znajdują się opcje „Tylko tym razem” i „Odrzuć”.
Rysunek 5. Użytkownik wcześniej wybrał PrzybliżoneTylko tym razem (w oknie z rysunku 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 stopniowe żądania dostępu do lokalizacji, prosząc najpierw o dostęp do lokalizacji na pierwszym planie, a potem w tle. Dzięki żądaniom stopniowym użytkownicy zyskują większą kontrolę i przejrzystość, ponieważ mogą lepiej zrozumieć, które funkcje aplikacji potrzebują 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 „polecanie miejsc 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. Na początku aplikacja powinna kierować użytkowników do funkcji, które wymagają dostępu do lokalizacji na pierwszym planie, takich jak funkcja „Udostępnij lokalizację” na rysunku 1 lub funkcja „Pokaż aktualną 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 będzie mieć dostępu do lokalizacji na pierwszym planie.

  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.

Treść 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 w Twojej 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ć lokalizowanie w tle na stronie ustawień (patrz 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 uzyskać tę etykietę, zadzwoń pod numer getBackgroundPermissionOptionLabel(). Wartość zwracana przez tę metodę jest dostosowywana do preferowanego języka urządzenia użytkownika.
  • Opcja odrzucenia uprawnień przez użytkowników. Jeśli użytkownicy odmówią udostępnienia dostępu do lokalizacji w tle, powinni nadal mieć możliwość korzystania z aplikacji.
Użytkownicy mogą kliknąć powiadomienie systemowe, aby zmienić ustawienia lokalizacji dla aplikacji.
Rysunek 8. Powiadomienie przypominające użytkownikowi, że zezwolił na dostęp aplikacji 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 już stosuje się do sprawdzonych metod dotyczących żądania uprawnień do lokalizacji, nie musisz wprowadzać żadnych zmian, aby obsługiwać tę funkcję.

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 zezwolił aplikacji na stały dostęp do lokalizacji urządzenia. Rysunek 8 przedstawia przykładowe powiadomienie.

Sprawdzanie wymagań dotyczących lokalizacji w zależnych pakietach 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 na Androidzie znajdziesz w tych materiałach:

Ćwiczenia z programowania

Filmy

Próbki