0Pricing
Android Academy · Lekcja

Uprawnienia i żądania w czasie działania

Proszę deklarować i żądać niebezpiecznych uprawnień w czasie działania za pomocą ActivityResultContracts, wyświetlać okna dialogowe z uzasadnieniem i obsługiwać trwałą odmowę uprawnień.

Uprawnienia i żądania w czasie działania to bezpłatna lekcja Android Academy na CoddyKit. To lekcja 7 z 7. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Android Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Android Academy zawiera 7 lekcji w sumie.

Przegląd uprawnień systemu Android

Aplikacje systemu Android muszą deklarować, z jakich funkcji urządzenia korzystają. Uprawnienia chronią prywatność użytkownika:

  • Uprawnienia normalne — niskiego ryzyka, przyznawane automatycznie (INTERNET, VIBRATE)
  • Uprawnienia niebezpieczne — zapewniają dostęp do poufnych danych i wymagają żądania w czasie działania aplikacji (CAMERA, LOCATION, READ_CONTACTS)
  • Uprawnienia sygnatury — dostępne tylko dla aplikacji podpisanych tym samym certyfikatem

Deklarowanie w manifeście

Wszystkie uprawnienia należy najpierw zadeklarować w pliku AndroidManifest.xml:

<!-- AndroidManifest.xml -->
<manifest ...>

    <!-- Normal: granted automatically -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <!-- Dangerous: must request at runtime -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application ...>
        ...
    </application>
</manifest>

Sprawdzanie, czy uprawnienie zostało przyznane

Przed użyciem funkcji wymagającej niebezpiecznego uprawnienia zawsze sprawdź, czy uprawnienie zostało już przyznane:

import androidx.core.content.ContextCompat
import android.content.pm.PackageManager

fun isCameraPermissionGranted(): Boolean {
    return ContextCompat.checkSelfPermission(
        this,   // Context
        android.Manifest.permission.CAMERA
    ) == PackageManager.PERMISSION_GRANTED
}

Żądanie uprawnienia za pomocą ActivityResultLauncher

Użyj ActivityResultContracts.RequestPermission() — to nowoczesne rozwiązanie, które nie wymaga przestarzałego onRequestPermissionsResult:

class CameraActivity : AppCompatActivity() {

    private val requestCameraPermission = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted ->
        if (isGranted) {
            openCamera()
        } else {
            showPermissionDeniedMessage()
        }
    }

    fun onTakePhotoClick(view: View) {
        if (isCameraPermissionGranted()) {
            openCamera()
        } else {
            requestCameraPermission.launch(android.Manifest.permission.CAMERA)
        }
    }
}

Wiele uprawnień jednocześnie

Żądaj wielu uprawnień za pomocą RequestMultiplePermissions:

private val requestMultiple = registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
    val cameraGranted   = permissions[android.Manifest.permission.CAMERA] ?: false
    val locationGranted = permissions[android.Manifest.permission.ACCESS_FINE_LOCATION] ?: false

    if (cameraGranted && locationGranted) {
        startFeature()
    } else {
        showWhichPermissionsDenied(cameraGranted, locationGranted)
    }
}

fun requestPermissions() {
    requestMultiple.launch(arrayOf(
        android.Manifest.permission.CAMERA,
        android.Manifest.permission.ACCESS_FINE_LOCATION
    ))
}

Uzasadnienie: kiedy wyjaśnić powód

shouldShowRequestPermissionRationale() zwraca true, gdy użytkownik wcześniej odmówił przyznania uprawnienia. Przed ponownym żądaniem wyświetl wyjaśnienie:

fun requestCameraWithRationale() {
    when {
        isCameraPermissionGranted() -> {
            openCamera()
        }
        shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA) -> {
            // Explain why we need it, then request
            AlertDialog.Builder(this)
                .setTitle("Camera needed")
                .setMessage("We use the camera to take profile photos.")
                .setPositiveButton("OK") { _, _ ->
                    requestCameraPermission.launch(android.Manifest.permission.CAMERA)
                }
                .show()
        }
        else -> {
            requestCameraPermission.launch(android.Manifest.permission.CAMERA)
        }
    }
}

Trwale odrzucone — przekierowanie do ustawień

Jeśli użytkownik wybierze opcję „Nie pytaj ponownie”, shouldShowRequestPermissionRationale zwróci false i nie będzie można ponownie poprosić o uprawnienie. Przekieruj użytkownika do ustawień aplikacji:

fun openAppSettings() {
    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
        data = Uri.fromParts("package", packageName, null)
    }
    startActivity(intent)
}

Uprawnienia do lokalizacji

Lokalizacja ma dwa poziomy dokładności — wybierz właściwy dla danego zastosowania:

  • ACCESS_COARSE_LOCATION — dokładność na poziomie miasta (Wi-Fi/stacje bazowe)
  • ACCESS_FINE_LOCATION — dokładność GPS
  • ACCESS_BACKGROUND_LOCATION — wymagane osobno w systemie Android 10 i nowszych, aby uzyskiwać dostęp do lokalizacji w tle

Pełny przykład uprawnienia do kamery

Kompletny przepływ łączący sprawdzenie → uzasadnienie → żądanie:

class PhotoActivity : AppCompatActivity() {

    private val cameraLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { granted ->
        if (granted) openCamera() else showDenied()
    }

    private fun handleCameraClick() {
        val permission = android.Manifest.permission.CAMERA
        when {
            ContextCompat.checkSelfPermission(this, permission) ==
                    PackageManager.PERMISSION_GRANTED -> openCamera()
            shouldShowRequestPermissionRationale(permission) ->
                showRationaleDialog()
            else -> cameraLauncher.launch(permission)
        }
    }

    private fun showDenied() {
        Snackbar.make(binding.root, "Camera permission required", Snackbar.LENGTH_LONG)
            .setAction("Settings") { openAppSettings() }.show()
    }
}

Najlepsze praktyki dotyczące uprawnień

Najważniejsze zasady zapewniające płynną obsługę uprawnień:

  • Żądaj uprawnień tylko wtedy, gdy są potrzebne (nie podczas uruchamiania aplikacji)
  • Żądaj tylko minimalnego zestawu wymaganych uprawnień
  • Zawsze odpowiednio obsługuj przypadek odmowy
  • Nie pytaj wielokrotnie po wybraniu opcji „Nie pytaj ponownie”
  • Przed wyświetleniem systemowego okna dialogowego wyjaśnij, dlaczego uprawnienie jest potrzebne, a nie dopiero po odmowie

Szczegółowe uprawnienia do multimediów w systemie Android 13+

Od systemu Android 13 (API 33) uprawnienie READ_EXTERNAL_STORAGE jest podzielone na szczegółowe uprawnienia:

  • READ_MEDIA_IMAGES
  • READ_MEDIA_VIDEO
  • READ_MEDIA_AUDIO

Zawsze sprawdzaj Build.VERSION.SDK_INT i żądaj właściwego uprawnienia dla danej wersji systemu operacyjnego.

Szybkie sprawdzenie

Kiedy należy wyświetlić okno dialogowe z uzasadnieniem przed zażądaniem niebezpiecznego uprawnienia?

Podsumowanie: uprawnienia

Poprawna obsługa uprawnień w czasie działania:

  • Zadeklaruj uprawnienie w AndroidManifest.xml
  • Sprawdzaj je za pomocą ContextCompat.checkSelfPermission()
  • Żądaj go za pomocą registerForActivityResult(RequestPermission())
  • Wyświetlaj uzasadnienie, gdy shouldShowRequestPermissionRationale() zwraca wartość true
  • W przypadku trwałej odmowy skieruj użytkownika do ustawień
  • Nigdy nie żądaj uprawnień, zanim użytkownik ich nie potrzebuje

Dalej: zapisywanie danych lokalnie za pomocą DataStore.

Często zadawane pytania

Czy lekcja „Uprawnienia i żądania w czasie działania” jest bezpłatna?

Tak — pełny tekst „Uprawnienia i żądania w czasie działania” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Android Academy, przejdź na CoddyKit PRO. Kurs Android Academy zawiera 7 lekcji w sumie.

Co nauczysz się w „Uprawnienia i żądania w czasie działania”?

Proszę deklarować i żądać niebezpiecznych uprawnień w czasie działania za pomocą ActivityResultContracts, wyświetlać okna dialogowe z uzasadnieniem i obsługiwać trwałą odmowę uprawnień. Ćwiczysz Android Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Android Academy?

Nie wymagamy żadnego doświadczenia. Android Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 7 z 7.

Ile czasu zajmuje lekcja „Uprawnienia i żądania w czasie działania”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Android Academy?

Tak. Każda lekcja Android Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Struktura projektu i manifest
  2. Aktywności i cykl życia
  3. Układy i widoki
  4. Obsługa danych wprowadzanych przez użytkownika
  5. Intencje i nawigacja
  6. Fragmenty
  7. Uprawnienia i żądania w czasie działania
← Powrót do Android Academy