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

Gdy funkcja w aplikacji wymaga dostępu do lokalizacji, poczekaj, aż użytkownik wejdzie z nią w interakcję, zanim poprosisz go o zgodę na dostęp. Ten proces jest zgodny ze sprawdzoną metodą proszenia o uprawnienia w czasie działania w kontekście, która została opisana w przewodniku wyjaśniającym, jak prosić o uprawnienia aplikacji.

Na rysunku 1 pokazano przykład, jak przeprowadzić ten proces. Aplikacja zawiera funkcję „udostępnianie lokalizacji”, która wymaga dostępu do lokalizacji na pierwszym planie. Aplikacja nie prosi jednak o zezwolenie na dostęp do lokalizacji, dopóki użytkownik nie kliknie przycisku Udostępnij lokalizację.

Gdy użytkownik kliknie przycisk Udostępnij lokalizację, pojawi się okno uprawnień dostępu 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ć dostęp tylko do przybliżonej lokalizacji

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

Aby poradzić sobie z takim potencjalnym zachowaniem użytkowników, nie proś o samo uprawnienie ACCESS_FINE_LOCATION. Zamiast tego poproś o uprawnienie ACCESS_FINE_LOCATION i uprawnienie ACCESS_COARSE_LOCATION w ramach jednego żądania w czasie działania. Jeśli spróbujesz poprosić tylko o ACCESS_FINE_LOCATION, system zignoruje prośbę w niektórych wersjach Androida 12. Jeśli 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 widzi te opcje:

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

Ilustracja 3 pokazuje, że okno zawiera wizualne wskazówki dotyczące obu opcji, aby ułatwić użytkownikowi wybór. Gdy użytkownik zdecyduje się na dokładność lokalizacji, kliknie jeden z 3 przycisków, aby wybrać czas trwania przyznania uprawnień.

Na urządzeniach z Androidem 12 i nowszym użytkownicy mogą przejść do ustawień systemu, aby określić preferowaną dokładność lokalizacji dla dowolnej aplikacji, niezależnie od wersji pakietu SDK, na którą jest ona kierowana. Dotyczy to również sytuacji, gdy aplikacja jest zainstalowana na urządzeniu z Androidem 11 lub starszym, a potem użytkownik uaktualni urządzenie do Androida 12 lub nowszego.

Okno dialogowe 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 wysyła ACCESS_COARSE_LOCATIONtylko
żądanie.
Okno dialogowe ma 2 zestawy opcji, jeden nad drugim.
Rysunek 3. Okno dialogowe uprawnień systemowych, które pojawia się, gdy aplikacja wysyła pojedyncze żądanie w czasie działania, aby uzyskać dostęp do ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION.

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

W tabeli poniżej znajdziesz uprawnienia, które system przyznaje Twojej aplikacji na podstawie opcji wybranych przez użytkownika w oknie uprawnień w czasie działania aplikacji:

Dokładnie W przybliżeniu
Podczas używania aplikacji ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Tylko tym razem ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Odrzuć Brak dostępu do lokalizacji Brak dostępu do lokalizacji

Aby sprawdzić, które uprawnienia system przyznał Twojej aplikacji, sprawdź wartość zwracaną żądania uprawnień. Możesz używać bibliotek Jetpack w kodzie podobnym do tego poniżej lub bibliotek platformy, w których samodzielnie zarządzasz kodem żądania uprawnień.

Kotlin

@RequiresApi(Build.VERSION_CODES.N)
fun requestPermissions() {
    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:
    // https://developer.android.com/training/permissions/requesting#request-permission
    locationPermissionRequest.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}

Java

private void requestPermissions() {

    ActivityResultLauncher<String[]> locationPermissionRequest =
            registerForActivityResult(new ActivityResultContracts
                            .RequestMultiplePermissions(), result -> {

                Boolean fineLocationGranted = null;
                Boolean coarseLocationGranted = null;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    fineLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_FINE_LOCATION, false);
                    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
    });
}

Prośba o uaktualnienie do dokładnej lokalizacji

Możesz poprosić użytkownika o zwiększenie uprawnień dostępu aplikacji z przybliżonej lokalizacji do dokładnej lokalizacji. Zanim poprosisz użytkownika o zwiększenie uprawnień dostępu aplikacji do dokładnej lokalizacji, zastanów się, czy Twój przypadek użycia aplikacji bezwzględnie wymaga tego poziomu precyzji. Jeśli Twoja aplikacja musi sparować urządzenie z urządzeniami w pobliżu za pomocą Bluetootha lub Wi-Fi, rozważ użycie parowania urządzeń towarzyszących lub uprawnień Bluetootha zamiast prosić o uprawnienie ACCESS_FINE_LOCATION.

Aby poprosić użytkownika o zaktualizowanie dostępu aplikacji do lokalizacji z przybliżonego na dokładny:

  1. W razie potrzeby wyjaśnij, dlaczego Twoja aplikacja potrzebuje tych uprawnień.
  2. Ponownie poproś o uprawnienia ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION. Użytkownik zezwolił już systemowi na przyznanie aplikacji przybliżonej lokalizacji, więc okno systemowe jest tym razem inne, jak pokazano na rysunkach 4 i 5:
W oknie dialogowym znajdują się opcje „Zmień na dokładną lokalizację”, „Tylko tym razem” i „Odmów”.
Rysunek 4. Użytkownik wcześniej wybrał opcje PrzybliżonaPodczas używania aplikacji (w oknie z rysunku 3).
W oknie dialogowym znajdują się opcje „Tylko tym razem” i „Odmów”.
Rysunek 5. Użytkownik wcześniej wybrał opcje PrzybliżonaTylko tym razem (w oknie dialogowym z rysunku 3).

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

Nawet jeśli kilka funkcji w aplikacji wymaga dostępu do lokalizacji, prawdopodobnie tylko niektóre z nich wymagają dostępu do lokalizacji w tle. Dlatego zalecamy, aby aplikacja stopniowo prosiła o uprawnienia do lokalizacji, najpierw o dostęp do lokalizacji na pierwszym planie, a potem o dostęp do lokalizacji w tle. Dzięki żądaniom stopniowym użytkownicy mają większą kontrolę i zyskują większą przejrzystość, ponieważ mogą lepiej zrozumieć, które funkcje w aplikacji wymagają dostępu do lokalizacji w tle.

Ilustracja 6 przedstawia przykład aplikacji zaprojektowanej do obsługi żądań przyrostowych. Zarówno funkcja „pokaż bieżącą lokalizację”, jak i „polecaj miejsca w pobliżu” wymagają dostępu do lokalizacji na pierwszym planie. Tylko funkcja „polecaj pobliskie miejsca” wymaga dostępu do lokalizacji w tle.

Przycisk, który umożliwia dostęp do lokalizacji na pierwszym planie, znajduje się w połowie długości ekranu od przycisku, który umożliwia dostęp do lokalizacji w tle.
Rysunek 6. Obie funkcje wymagają dostępu do lokalizacji, ale tylko funkcja „polecaj pobliskie funkcje” 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, np. funkcji „udostępnij lokalizację” na ilustracji 1 lub funkcji „pokaż bieżącą lokalizację” na ilustracji 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 użytkownik będzie korzystać z funkcji wymagających dostępu do lokalizacji w tle, możesz poprosić o dostęp do lokalizacji w tle.

Dodatkowe materiały

Więcej informacji o uprawnieniach do lokalizacji na Androidzie znajdziesz w tych materiałach:

Codelabs

Filmy

Próbki