AndroidManifest Permissions: kluczowe pojęcia, deklaracja i typy uprawnień

Autor: IT Sectr Opublikowano: 2026-05-21 Czas czytania: 10 min

AndroidManifest Permissions to deklaracje uprawnień w pliku AndroidManifest.xml, które określają, do jakich zasobów systemowych i danych ma dostęp aplikacja. Android wymaga określenia każdego uprawnienia w manifeście przed użyciem odpowiedniego API: od aparatu i geolokalizacji po wysyłanie SMS i dostęp do kontaktów. Według Android Developer Documentation każde uprawnienie dzieli się na jeden z czterech poziomów ochrony: normal, dangerous, signature i special.

Najważniejsze

  • AndroidManifest.xml — plik manifestu z deklaracją wszystkich uprawnień aplikacji
  • Poziomy ochrony — normal, dangerous, signature, special z różnymi mechanizmami żądania
  • Runtime Permission — uprawnienia dangerous wymagają żądania w czasie wykonywania (Android 6+)
  • Declare vs Request — deklaracja w manifeście jest obowiązkowa, ale dangerous wymagają dodatkowego żądania w kodzie
  • Grupy — uprawnienia są połączone w grupy, zgoda na jedno daje dostęp do całej grupy

Czym są AndroidManifest Permissions?

AndroidManifest Permissions to mechanizm bezpieczeństwa Android, który kontroluje dostęp aplikacji do chronionych danych i funkcji systemowych. Każda aplikacja musi deklarować wymagane uprawnienia w pliku AndroidManifest.xml za pomocą elementu <uses-permission>. Bez deklaracji wywołanie odpowiedniego API zakończy się błędem bezpieczeństwa SecurityException.

Model uprawnień Android przeszedł kilka etapów ewolucji. Przed Android 6.0 (API 23) wszystkie uprawnienia były przyznawane podczas instalacji — użytkownik widział pełną listę i zgadzał się lub rezygnował z instalacji aplikacji. Od Android 6.0 uprawnienia poziomu dangerous są żądane w czasie wykonywania (Runtime Permissions), co daje użytkownikowi bardziej elastyczną kontrolę.

Uprawnienia dzielą się na cztery poziomy ochrony: normal (automatycznie przyznawane podczas instalacji), dangerous (wymagają żądania w czasie wykonywania), signature (dostępne tylko dla aplikacji podpisanych tym samym certyfikatem) i special (wymagają osobnego włączenia w ustawieniach). Każdy poziom ma swój mechanizm przyznawania i odwoływania.

Według Google I/O 2024, w Android 15 planowane jest wprowadzenie bardziej szczegółowych uprawnień — użytkownik będzie mógł udostępniać dostęp tylko do określonych plików w bibliotece medialnej, a nie do całej biblioteki. Kontynuuje to trend Androida do minimalizacji zakresu udostępnianych danych domyślnie.

Różnica w porównaniu z modelem uprawnień iOS

W przeciwieństwie do iOS, gdzie wszystkie uprawnienia są żądane w czasie wykonywania (runtime), Android dzieli uprawnienia na instalacyjne (install-time) i wykonawcze (runtime). Poziom normal jest przyznawany automatycznie podczas instalacji bez powiadamiania użytkownika. Poziom dangerous wymaga jawnego okna dialogowego, podobnie jak w iOS.

Kolejna różnica: w Android uprawnienia są połączone w grupy (permission groups). Jeśli użytkownik zgodził się na dostęp do aparatu, aplikacja automatycznie otrzymuje dostęp do mikrofonu — są w tej samej grupie MICROPHONE. W iOS każde uprawnienie jest żądane osobno, niezależnie od grupy.

Ewolucja uprawnień według wersji Androida

Wersja AndroidaZmiana w modelu uprawnień
Android 1.0–5.xWszystkie uprawnienia przyznawane podczas instalacji (install-time)
Android 6.0 (API 23)Wprowadzenie Runtime Permissions dla poziomu dangerous
Android 10 (API 29)Scoped Storage — ograniczony dostęp do systemu plików
Android 11 (API 30)Auto-reset uprawnień — nieużywane uprawnienia są resetowane
Android 14 (API 34)Runtime uprawnienia dla dostępu do multimediów (zdjęcia, wideo, audio)

Jakie typy uprawnień istnieją

Android określa cztery poziomy ochrony (protection levels) dla uprawnień, każdy z własnymi zasadami przyznawania. Omówmy szczegółowo każdy poziom.

Normal Permissions (install-time)

Normal uprawnienia są przyznawane automatycznie podczas instalacji aplikacji bez powiadamiania lub żądania od użytkownika. Obejmują dostęp do funkcji niskiego ryzyka, które nie zagrażają prywatności użytkownika: INTERNET, ACCESS_NETWORK_STATE, VIBRATE, BLUETOOTH. Użytkownik nie widzi okna dialogowego zgody — uprawnienie jest uważane za przyznane z chwilą instalacji.

Deweloper nie musi obsługiwać żądania w kodzie dla normal uprawnień — wystarczy zadeklarować je w manifeście. Jednak w Android 12+ podczas instalacji z Google Play użytkownik widzi zakładkę „Uprawnienia” z listą wszystkich normal uprawnień, co zwiększa przejrzystość. Według Statista (2024) ponad 90% aplikacji w Google Play używa INTERNET jako najczęstszego normal uprawnienia.

Dangerous Permissions (runtime)

Dangerous uprawnienia obejmują dostęp do danych i funkcji, które mogą naruszyć prywatność: aparat, mikrofon, geolokalizacja, kontakty, SMS, telefon, kalendarz, czujniki ciała. Uprawnienia te wymagają dwuetapowego mechanizmu: deklaracji w manifeście + żądania w czasie wykonywania przez ActivityCompat.requestPermissions().

Użytkownik może odmówić przyznania dangerous uprawnienia, a aplikacja musi poprawnie obsłużyć ten scenariusz. W Android 11+ jeśli użytkownik dwukrotnie odmówił, kolejne żądania nie pokazują systemowego okna dialogowego — system automatycznie zwraca DENIED. W takim przypadku należy skierować użytkownika do ustawień.

Signature i Special Permissions

Poziom signature — uprawnienie jest przyznawane automatycznie, jeśli aplikacja jest podpisana tym samym certyfikatem co system lub inna aplikacja, która zdefiniowała uprawnienie. Używane w aplikacjach systemowych i korporacyjnych. Przykład: BIND_ACCESSIBILITY_SERVICE — dostępne tylko dla aplikacji systemowych.

Poziom special (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, REQUEST_INSTALL_PACKAGES, MANAGE_EXTERNAL_STORAGE) — wymaga osobnego działania użytkownika przez ustawienia systemowe. Aplikacja może otworzyć stronę ustawień za pomocą Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION). Google Play ogranicza użycie special uprawnień i wymaga uzasadnienia w formularzu podczas publikacji.

Runtime Permission: praca z uprawnieniami dangerous

Od Android 6.0 wszystkie dangerous uprawnienia wymagają żądania w czasie wykonywania. Omówmy pełny cykl pracy z runtime permissions w Kotlin.

Sprawdzanie i żądanie uprawnienia

Przed wywołaniem API wymagającego dangerous uprawnienia zawsze sprawdzaj aktualny status przez ContextCompat.checkSelfPermission(). Jeśli status to PERMISSION_GRANTED — można wywołać API. Jeśli PERMISSION_DENIED — należy żądać uprawnienia przez ActivityResultContract RequestPermission (AndroidX) lub przestarzałe requestPermissions().

Zaleca się używanie ActivityResultContracts.RequestMultiplePermissions do żądania wielu uprawnień jednocześnie. Google zaleca grupowanie powiązanych uprawnień (np. aparat + mikrofon do nagrywania wideo) w jednym oknie dialogowym, aby użytkownik widział pełny kontekst żądania.

kotlin
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat

class CameraActivity : AppCompatActivity() {
    private val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted) {
                openCamera()
            } else {
                explainWhyPermissionNeeded()
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        checkCameraPermission()
    }

    private fun checkCameraPermission() {
        when {
            ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED -> {
                openCamera()
            }
            shouldShowRequestPermissionRationale(
                Manifest.permission.CAMERA
            ) -> {
                showRationale()
            }
            else -> {
                requestPermissionLauncher.launch(
                    Manifest.permission.CAMERA
                )
            }
        }
    }
}

Obsługa odmowy „Don’t ask again”

Jeśli użytkownik dwukrotnie odmówił uprawnienia, Android przełącza żądanie w stan „Never ask again”. W takim przypadku shouldShowRequestPermissionRationale() zwraca false, a systemowe okno dialogowe nie zostanie pokazane. Aplikacja musi skierować użytkownika do ustawień systemowych przez Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).

Ważne: nie pokazuj okna dialogowego z propozycją otwarcia ustawień zaraz po pierwszej odmowie — jest to odbierane jako agresywne zachowanie. Użyj shouldShowRequestPermissionRationale() do określenia, czy należy pokazać wyjaśnienie. Material Design Guidelines zalecają pokazanie ekranu z wyjaśnieniem wartości dostępu, a nie tylko przycisku „Otwórz ustawienia”.

kotlin
private fun openAppSettings() {
    Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.fromParts("package", packageName, null)
    ).also { intent ->
        startActivity(intent)
    }
}

private fun showPermissionSettings() {
    AlertDialog.Builder(this)
        .setTitle("Dostęp do kamery")
        .setMessage("Zezwól na dostęp do kamery w Ustawieniach, "
            + "aby robić zdjęcia profilowe")
        .setPositiveButton("Otwórz ustawienia") { _, _ ->
            openAppSettings()
        }
        .setNegativeButton("Anuluj", null)
        .show()
}

Deklaracja uprawnień w AndroidManifest.xml

Plik AndroidManifest.xml zawiera element <uses-permission> dla każdego uprawnienia używanego przez aplikację. Uprawnienia są deklarowane na poziomie <manifest> przed elementem <application>.

Składnia deklaracji

Każde uprawnienie jest deklarowane osobnym elementem <uses-permission> z atrybutem android:name wskazującym pełną nazwę uprawnienia. Dla uprawnień, które pojawiły się w określonych wersjach Androida, użyj atrybutu maxSdkVersion, aby ograniczyć deklarację tylko do potrzebnych wersji — poprawia to kompatybilność.

Na przykład uprawnienie WRITE_EXTERNAL_STORAGE nie jest potrzebne na Android 10+ (Scoped Storage), więc określ maxSdkVersion=„28” (Android 9). Zapobiega to niepotrzebnym pytaniom od użytkowników na nowszych wersjach. Android Studio ostrzega o zalecanych maxSdkVersion przez Lint.

xml
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Normal permissions (install-time) -->
    <uses-permission
        android:name="android.permission.INTERNET" />
    <uses-permission
        android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Dangerous permissions (runtime) -->
    <uses-permission
        android:name="android.permission.CAMERA" />
    <uses-permission
        android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Legacy storage permission limited to API 28 and below -->
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="28" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

    <application>
        <!-- ... -->
    </application>
</manifest>

Użycie <uses-feature> do filtrowania

Element <uses-feature> określa, że aplikacja wymaga określonego sprzętu (aparat, GPS, NFC). Atrybut android:required=„false” umożliwia instalację aplikacji na urządzeniach bez tego sprzętu — sprawdzenie dostępności odbywa się w kodzie. Jeśli required=„true”, Google Play filtruje aplikację i staje się ona niedostępna dla nieodpowiednich urządzeń.

Zaleca się dla wszystkich funkcji sprzętowych określanie required=„false” i programowe sprawdzanie dostępności przez PackageManager.hasSystemFeature(). Zwiększa to grono odbiorców aplikacji. Jedynym wyjątkiem jest sytuacja, gdy funkcja jest krytyczna dla działania aplikacji (aplikacja do zamawiania taksówek bez GPS nie ma sensu).

Najlepsze praktyki i błędy

Prawidłowa praca z uprawnieniami to kluczowy aspekt jakości aplikacji Android. Omówmy główne zalecenia i typowe błędy.

Minimalizacja żądanych uprawnień

Żądaj tylko tych uprawnień, które są rzeczywiście niezbędne do działania aplikacji. Każde dodatkowe uprawnienie zmniejsza konwersję instalacji i zwiększa liczbę odmów. Google Play Console pokazuje, ilu użytkowników zrezygnowało z instalacji z powodu zestawu uprawnień. Według AppBrain (2024) aplikacje z 10+ dangerous uprawnieniami mają o 35% mniej instalacji.

Regularnie przeglądaj listę uprawnień. Usuwaj nieużywane, szczególnie przy przejściu na nowsze wersje Androida, gdzie niektóre uprawnienia stały się nieobowiązkowe. Na przykład z pojawieniem się selektora zdjęć (ActivityResultContracts.PickVisualMedia) w Android 13+ dostęp do biblioteki medialnej można uzyskać bez dangerous uprawnienia READ_MEDIA_IMAGES.

Pokazywanie rationale przed żądaniem

Przed żądaniem dangerous uprawnienia pokaż użytkownikowi ekran z wyjaśnieniem, dlaczego to uprawnienie jest potrzebne i jaką wartość daje. Material Design zaleca użycie bottom sheet lub okna dialogowego z ikoną, krótkim tekstem i przyciskiem „Kontynuuj”. Rationale zwiększa zgodę o 20–30% w porównaniu z bezpośrednim żądaniem.

Sprawdzaj shouldShowRequestPermissionRationale() przed wywołaniem launch(). Jeśli true — pokaż rationale. Jeśli false — albo uprawnienie już zostało przyznane, albo użytkownik odmówił na stałe (never ask again). W tym ostatnim przypadku pokaż przycisk „Otwórz ustawienia”, a nie powtarzaj żądania.

Testowanie wszystkich scenariuszy uprawnień

Przetestuj wszystkie możliwe scenariusze: przyznanie uprawnienia, odmowa, odmowa na stałe, cofnięcie uprawnienia w ustawieniach, reset uprawnień (Android 11+ auto-reset). Każdy scenariusz powinien być obsługiwany bez crasha i bez utraty danych. Android Testing Guide zaleca użycie biblioteki TestPermission do automatyzacji testów.

Szczególną uwagę poświęć scenariuszowi, gdy użytkownik cofnął uprawnienie podczas działania aplikacji (zminimalizowana aplikacja → Ustawienia → cofnięcie). Po powrocie do aplikacji sprawdź wszystkie uprawnienia ponownie przez onResume(). Nie polegaj na buforowaniu statusu uprawnień — użytkownik może je zmienić w każdej chwili.

Typowe błędy

  • Żądanie uprawnienia bez wcześniejszego sprawdzenia checkSelfPermission — spowoduje niepotrzebne okno dialogowe
  • Ignorowanie shouldShowRequestPermissionRationale — pogarsza UX po pierwszej odmowie
  • Żądanie uprawnienia bez kontekstu (tylko „Zezwolić na dostęp?”) — zmniejsza zgodę
  • Używanie WRITE_EXTERNAL_STORAGE na Android 10+ bez maxSdkVersion — niepotrzebne żądanie
  • Brak sprawdzania uprawnień w onResume — pominięcie cofnięcia uprawnienia w ustawieniach

Często zadawane pytania

Czy trzeba deklarować uprawnienie, jeśli żąda go SDK?

Tak, jeśli SDK dołącza do swojego manifestu uprawnienie, zostaje ono połączone z manifestem aplikacji podczas budowania. Możesz wyłączyć niepotrzebne uprawnienie SDK za pomocą tools:node=„remove” w AndroidManifest.xml.

Co się stanie, jeśli nie obsłużę odmowy uprawnienia?

Wywołanie API bez uprawnienia spowoduje SecurityException, co doprowadzi do crasha aplikacji. Zawsze sprawdzaj status uprawnienia przed użyciem odpowiedniego API i obsługuj odmowę poprawnie.

Jak zresetować uprawnienia podczas tworzenia aplikacji?

W ustawieniach urządzenia: Ustawienia → Aplikacje → [twoja aplikacja] → Uprawnienia. Do zresetowania wszystkich uprawnień użyj komendy adb: adb shell pm reset-permissions.

Czy można żądać uprawnienia bez Activity?

Tak, za pomocą ActivityResultLauncher we Fragment lub Service. Jednak okno dialogowe żądania zawsze wymaga kontekstu UI Activity. Dla Service możesz pokazać Notification z Intent otwierającym Activity z żądaniem.

Po co jest maxSdkVersion dla uprawnień?

Na przykład WRITE_EXTERNAL_STORAGE nie jest potrzebny na Android 10+ (Scoped Storage). Określając android:maxSdkVersion=„28”, wykluczasz deklarację uprawnienia na nowszych wersjach, co poprawia kompatybilność i zmniejsza listę żądanych uprawnień.

Podsumowanie

  • AndroidManifest Permissions — obowiązkowe deklaracje dostępu do zasobów systemowych w Android
  • 4 poziomy ochrony — normal, dangerous, signature, special z różnymi mechanizmami przyznawania
  • Runtime Permissions — dangerous uprawnienia wymagają żądania w czasie wykonywania (Android 6+)
  • Grupy uprawnień — zgoda na jedno uprawnienie w grupie daje dostęp do wszystkich w grupie
  • Rationale — pokazanie wyjaśnienia przed żądaniem zwiększa zgodę o 20–30%
  • Minimalizacja — żądaj tylko niezbędnych uprawnień i używaj maxSdkVersion
  • Zawsze sprawdzaj status uprawnienia przed wywołaniem API i obsługuj wszystkie scenariusze odmowy

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również