AndroidManifest.xml to obowiązkowy plik konfiguracyjny każdej aplikacji Android, opisujący jej komponenty, uprawnienia i metadane. System Android odczytuje ten plik podczas instalacji i uruchamiania każdej aplikacji. Według Android Developers, 2025, bez poprawnego manifestu aplikacja nie zostanie zainstalowana na urządzeniu. AndroidManifest.xml rejestruje Activity, Service, BroadcastReceiver i ContentProvider dla systemu operacyjnego.
Najważniejsze
AndroidManifest.xml to główny plik konfiguracyjny w formacie XML, który każdy projekt Android musi zawierać w katalogu app/src/main. System Android analizuje go przed uruchomieniem jakiegokolwiek kodu aplikacji — na etapie parsowania APK podczas instalacji. Jeśli w manifeście występuje błąd składniowy lub brakuje obowiązkowej deklaracji, instalacja jest przerywana z komunikatem błędu.
Plik zawiera pełną deklarację aplikacji: listę wszystkich komponentów (Activity, Service, BroadcastReceiver, ContentProvider), żądane uprawnienia, minimalną wersję SDK, wymagania sprzętowe oraz konfigurację motywów i stylów. Każdy komponent, który może być wywołany przez system lub inne aplikacje, musi być jawnie zadeklarowany w manifeście. Jest to wymóg bezpieczeństwa: bez jawnej deklaracji komponent jest niedostępny do wywołania.
Bez prawidłowo skonfigurowanego manifestu aplikacja nie może zostać zainstalowana przez Google Play ani sideloading. System sprawdza manifest na etapie parsowania APK i odrzuca instalację w przypadku błędów. Google Play skanuje również manifest w poszukiwaniu niebezpiecznych konfiguracji: w przypadku exported=true w komponencie bez intent-filter wyświetlane jest ostrzeżenie, a w przypadku braku obowiązkowych uprawnień dla targetSdk 34+ publikacja jest blokowana. Dlatego zrozumienie struktury manifestu to obowiązkowa umiejętność dewelopera Androida.
Każdy komponent aplikacji Android musi być jawnie zarejestrowany w manifeście. Jest to obowiązkowy wymóg platformy dla wszystkich czterech typów komponentów. Bez rejestracji komponent nie może zostać utworzony przez system, a próba jego uruchomienia zakończy się wyjątkiem ActivityNotFoundException lub podobnym. Komponenty rejestruje się wewnątrz tagu application w kolejności nie wpływającej na ich działanie.
Tag activity rejestruje ekran aplikacji. Atrybut exported określa, czy inne aplikacje mogą uruchamiać to Activity. Od Androida 12 brak exported przy obecności intent-filter powoduje błąd kompilacji — jest to wymóg bezpieczeństwa. Punkt wejścia określa się przez intent-filter z action MAIN i category LAUNCHER. Każde Activity musi mieć unikalną nazwę android:name, odpowiadającą pełnej lub względnej nazwie klasy.
<activity
android:name=".MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Tag service definiuje usługę działającą w tle. Od Androda 8 usługi działające w tle mają ścisłe ograniczenia: foreground service wymaga obowiązkowego powiadomienia z ikoną widoczną dla użytkownika, a bound service żyje tylko przy obecności podłączonego klienta. Usługi działające w tle bez powiadomienia są automatycznie kończone przez system po kilku minutach od przejścia aplikacji w tryb tła. Do długotrwałych zadań używaj WorkManager zamiast Service.
<service
android:name=".SyncService"
android:exported="false"
android:foregroundServiceType="dataSync" />
Tag receiver deklaruje odbiornik systemowych lub niestandardowych komunikatów rozgłaszanych. Od Androida 8 większość niejawnych rozgłoszeń nie jest już dostarczana do statycznie zadeklarowanych w manifeście odbiorników. Zamiast tego zaleca się dynamiczną rejestrację odbiorników przez Context.registerReceiver w kodzie. Wyjątkiem są niektóre rozgłoszenia systemowe, np. BOOT_COMPLETED, które nadal wymagają statycznej rejestracji w manifeście.
<receiver
android:name=".ConnectivityReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Każde niebezpieczne uprawnienie w Android wymaga deklaracji w manifeście przez tag uses-permission. Od Androida 6 niebezpieczne uprawnienia są żądane w czasie wykonania przez dialog z użytkownikiem, ale deklaracja w manifeście pozostaje obowiązkowa. Bez niej metoda requestPermissions zgłasza wyjątek SecurityException. Uprawnienia normalnego poziomu, takie jak INTERNET i ACCESS_NETWORK_STATE, są przyznawane automatycznie podczas instalacji.
| Uprawnienie | Przeznaczenie |
|---|---|
| CAMERA | Dostęp do aparatu urządzenia do zdjęć i wideo |
| ACCESS_FINE_LOCATION | Dokładna lokalizacja przez GPS i sieć |
| RECORD_AUDIO | Nagrywanie dźwięku z mikrofonu urządzenia |
| READ_CONTACTS | Odczyt kontaktów z książki telefonicznej |
| POST_NOTIFICATIONS | Wysyłanie powiadomień na Android 13+ |
Tag uses-permission-sdk-23 określa uprawnienia wymagane tylko na Android 6.0+. Pozwala to zachować zgodność ze starszymi wersjami bez żądania nieistniejących uprawnień. Na przykład POST_NOTIFICATIONS jest dostępne tylko na Android 13+, dlatego należy je określać przez uses-permission-sdk-33, aby na starszych urządzeniach nie występował błąd nieznanego uprawnienia. Atrybut maxSdkVersion w uses-permission pozwala automatycznie cofać niepotrzebne uprawnienia podczas aktualizacji aplikacji na nowsze wersje Androida.
Uprawnienia normalnego poziomu (INTERNET, ACCESS_NETWORK_STATE) są przyznawane automatycznie podczas instalacji i nie wymagają żądania w czasie wykonania. Są one również deklarowane przez uses-permission, ale nie są wyświetlane użytkownikowi w dialogu. Do kontroli dostępu do komponentów aplikacji z innych aplikacji stosuje się mechanizm permission-protected components: można określić niestandardowe uprawnienie na poziomie Activity lub Service, które będzie sprawdzane przez system przy wywołaniu komponentu z zewnątrz. Zapewnia to dodatkowy poziom bezpieczeństwa dla komunikacji międzyprocesowej.
Tag intent-filter w manifeście deklaruje, jakie niejawne intenty może obsługiwać komponent. Jest to mechanizm, przez który Android łączy systemowe lub niestandardowe działania z aplikacją. Intent filter składa się z trzech elementów: action (działanie), category (kategoria) i data (dane). Wszystkie trzy można łączyć w celu dokładnego opisania, które intenty powinien otrzymywać komponent. System wybiera odpowiedni komponent na podstawie najbardziej specyficznego filtra.
<activity android:name=".DeepLinkActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="itsectr.com"
android:pathPrefix="/app" />
</intent-filter>
</activity>
Atrybut autoVerify włącza weryfikację Android App Links: system kontaktuje się z serwerem w celu potwierdzenia własności domeny. Bez weryfikacji głębokie linki działają przez standardowy chooser dialog, w którym użytkownik wybiera, którą aplikacją otworzyć link. Po pomyślnej weryfikacji linki otwierają się bezpośrednio w aplikacji bez dialogu. Google Search Console również używa autoVerify do indeksowania deep links i wyświetlania ich w wynikach wyszukiwania.
Filtry z action.VIEW i kategoriami DEFAULT i BROWSABLE obsługują linki z przeglądarki, e-maili i innych aplikacji. Jest to główny mechanizm realizacji głębokich linków w Android. Do obsługi niestandardowych schematów URL, np. myapp://, wystarczy określić scheme bez hosta. Jednak Google zaleca używanie HTTPS deep links zamiast niestandardowych schematów, ponieważ są bezpieczniejsze i nie wymagają dodatkowych uprawnień. Niestandardowe schematy mogą zostać przechwycone przez dowolną aplikację, która zarejestruje ten sam schemat.
Główny tag manifest zawiera atrybuty pakietu, wersji i SDK. Tag application przechowuje ustawienia globalne: motyw, ikonę, etykietę i flagi debugowania. Atrybuty manifest określają wersjonowanie na poziomie pakietu, a atrybuty application definiują wygląd i zachowanie aplikacji jako całości. Wartości mogą być odnośnikami do zasobów przez składnię @ lub literałami łańcuchowymi.
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itsectr.myapp"
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="34" />
<application
android:label="MyApp"
android:icon="@mipmap/ic_launcher"
android:theme="@style/Theme.MyApp"
android:supportsRtl="true"
android:allowBackup="true">
<!-- Komponenty aplikacji -->
</application>
</manifest>
Tag meta-data wewnątrz application pozwala przechowywać dowolne pary klucz-wartość. Jest to wygodne do konfiguracji bibliotek zewnętrznych: kluczy API, adresów endpointów i flag funkcjonalności. Dane z meta-data są dostępne przez PackageManager.getApplicationInfo().metaData w czasie wykonania. Na przykład Firebase i Google Maps używają meta-data do przekazywania kluczy dostępu bez sztywnego kodowania w kodzie źródłowym. Klucze są określane w manifeście i mogą się różnić dla różnych wariantów kompilacji.
Atrybut android:extractNativeLibs zarządza wyodrębnianiem bibliotek natywnych z APK. Dla aplikacji z targetSdk 34+ ten atrybut musi być jawnie określony, w przeciwnym razie kompilacja może zakończyć się błędem INSTALL_FAILED_INVALID_APK. Jeśli extractNativeLibs=false, biblioteki natywne pozostają wewnątrz APK bez rozpakowywania, co zmniejsza rozmiar zainstalowanej aplikacji, ale zwiększa czas ładowania bibliotek. Dla większości nowoczesnych aplikacji zaleca się extractNativeLibs=false w celu zmniejszenia zajmowanego miejsca na dysku użytkownika.
Atrybut android:networkSecurityConfig pozwala określić plik konfiguracji bezpieczeństwa sieciowego. Jest to szczególnie ważne dla aplikacji z targetSdk 28+, gdzie ruch HTTP jest domyślnie blokowany. Plik konfiguracyjny określa zaufane certyfikaty, domeny dla połączeń HTTP i reguły przypinania certyfikatów. Zastępuje to przestarzały atrybut android:usesCleartextTraffic i zapewnia bardziej elastyczny mechanizm zarządzania bezpieczeństwem połączeń na poziomie systemu operacyjnego.
Atrybut android:largeHeap żąda zwiększonego rozmiaru sterty dla aplikacji. Domyślnie Android przydziela każdej aplikacji ograniczoną ilość pamięci, zależną od urządzenia i wersji systemu operacyjnego. Jeśli aplikacja pracuje z dużymi obrazami, wideo lub dużymi zestawami danych, largeHeap może zapobiec OutOfMemoryError. Jednak nadużywanie tego atrybutu jest szkodliwe: aplikacja z dużym zużyciem pamięci jest szybciej kończona przez system przy braku zasobów. Używaj largeHeap tylko po profilowaniu i potwierdzeniu konieczności.
Często zadawane pytania
Od Androida 12 brak atrybutu exported przy obecności intent-filter powoduje błąd kompilacji. System wymaga jawnego określenia widoczności każdego komponentu z intent-filter — jest to środek bezpieczeństwa zapobiegający przypadkowemu otwarciu komponentów przez inne aplikacje. Dla Activity bez intent-filter exported domyślnie ma wartość false.
Tak, ale w launcherze wyświetli się kilka ikon aplikacji. Każde Activity z MAIN/LAUNCHER staje się osobnym punktem wejścia. Jest to używane do tworzenia skrótów do różnych sekcji aplikacji, na przykład do przejścia od razu do ustawień lub do utworzenia nowego wpisu. Każda ikona otwiera odpowiednie Activity bezpośrednio.
Android łączy manifesty z bibliotek z głównym manifestem aplikacji. W przypadku konfliktu atrybutów używa się tools:replace lub tools:node="merge" do rozwiązania. Mechanizm jest automatyczny: podczas dodawania biblioteki przez Gradle jej manifest jest scalany z głównym. Aby anulować lub zastąpić atrybut z biblioteki, użyj tools:node="remove" lub tools:replace="attributeName".
Typowe przyczyny: uprawnienie nie zostało zadeklarowane w manifeście przez uses-permission, używane jest uprawnienie normalnego poziomu (bez żądania w czasie wykonania), użytkownik wybrał opcję „Nie pytaj więcej" i uprawnienie zostało trwale odrzucone, lub targetSdkVersion jest niższe niż 23, gdzie uprawnienia są żądane podczas instalacji. Do diagnostyki sprawdź manifest i logi przez adb logcat.
Atrybut android:debuggable włącza debugowanie aplikacji przez ADB. Dla kompilacji wydaniowych w Google Play musi mieć wartość false. Jeśli debuggable=true w kompilacji wydaniowej, osoba atakująca może połączyć się z aplikacją przez ADB, czytać dane i wykonywać dowolny kod. Google Play automatycznie blokuje publikację kompilacji z debuggable=true.
Podsumowanie
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.
Przeczytaj również