Omówienie pliku manifestu aplikacji

Każdy projekt aplikacji musi mieć plik AndroidManifest.xml o dokładnie tej nazwie w katalogu głównym zbioru źródłowego projektu. Plik manifestu zawiera najważniejsze informacje o aplikacji, które możesz przekazywać w narzędziach do kompilacji i w systemie operacyjnym Android oraz w Google Play.

Plik manifestu musi zawierać między innymi te elementy:

  • Komponenty aplikacji, w tym wszystkie aktywności, usługi, odbiorniki i dostawcy treści. Każdy komponent musi określać podstawowe właściwości, np. nazwę swojej klasy Kotlin lub Java. Może też deklarować możliwości, np. obsługiwane konfiguracje urządzenia, a także filtry intencji opisujące sposób uruchamiania komponentu. Więcej informacji o komponentach aplikacji znajdziesz w następnej sekcji.
  • Uprawnienia wymagane do uzyskania dostępu do chronionych części systemu lub innych aplikacji. Deklaruje też wszelkie uprawnienia, jakie inne aplikacje muszą mieć, jeśli chcą uzyskać dostęp do treści z tej aplikacji. Więcej informacji o uprawnieniach znajdziesz w następnej sekcji.
  • Sprzęt i oprogramowanie wymagane przez aplikację, które wpływają na to, na których urządzeniach można ją zainstalować z Google Play. Więcej informacji o zgodności urządzeń znajdziesz w następnej sekcji.

Jeśli tworzysz aplikację za pomocą Android Studio, plik manifestu jest tworzony za Ciebie, a większość najważniejszych elementów manifestu jest dodawana w trakcie tworzenia aplikacji, zwłaszcza gdy używasz szablonów kodu.

Funkcje pliku

W poniższych sekcjach opisano, jak plik manifestu odzwierciedla niektóre z najważniejszych cech aplikacji.

Komponenty aplikacji

Dla każdego komponentu aplikacji, który utworzysz w swojej aplikacji, zadeklaruj w pliku manifestu odpowiadający mu element XML:

Jeśli zmienisz klasę dowolnego z tych komponentów na inną bez zadeklarowania go w pliku manifestu, system nie będzie mógł go uruchomić.

Podaj nazwę klasy podrzędnej za pomocą atrybutu name, używając pełnego oznaczenia pakietu. Na przykład podklasa Activity jest zadeklarowana w ten sposób:

<manifest ... >
    <application ... >
        <activity android:name="com.example.myapp.MainActivity" ... >
        </activity>
    </application>
</manifest>

Jeśli jednak pierwszy znak w wartości name jest kropką, nazwa przestrzeni nazw aplikacji (z właściwości namespace pliku build.gradle na poziomie modułu) jest poprzedzona nazwą. Jeśli na przykład przestrzeń nazw to "com.example.myapp", ta nazwa działania przyjmuje wartość com.example.myapp.MainActivity:

<manifest ... >
    <application ... >
        <activity android:name=".MainActivity" ... >
            ...
        </activity>
    </application>
</manifest>

Więcej informacji o ustawianiu nazwy lub przestrzeni nazw pakietu znajdziesz w artykule Ustawianie przestrzeni nazw.

Jeśli masz komponenty aplikacji, które znajdują się w podpakietach, np. w com.example.myapp.purchases, wartość name musi zawierać brakujące nazwy podpakietów, np. ".purchases.PayActivity", lub używać w pełni kwalifikowanej nazwy pakietu.

Filtry intencji

Działania w aplikacji, usługi i odbiorniki transmisji są aktywowane przez zamiary. Intencja to komunikat zdefiniowany przez obiekt Intent, który opisuje działanie do wykonania. Zawiera m.in. dane, na które ma zostać wykonane działanie, kategorię komponentu, który ma wykonać to działanie, i inne instrukcje.

Gdy aplikacja wysyła intencję do systemu, system znajduje komponent aplikacji, który może obsłużyć intencję na podstawie deklaracji filtra intencji w pliku manifestu aplikacji. System uruchamia instancję pasującego komponentu i przekazuje do niego obiekt Intent. Jeśli więcej niż 1 aplikacja obsługuje intencję, użytkownik może wybrać aplikację, której chce użyć.

Komponent aplikacji może mieć dowolną liczbę filtrów intencji (zdefiniowanych za pomocą elementu <intent-filter>), a każdy z nich opisuje inne możliwości danego komponentu.

Więcej informacji znajdziesz w dokumencie Intencje i filtry intencji.

Ikony i etykiety

Wiele elementów manifestu ma atrybuty icon i label, które pozwalają wyświetlać użytkownikom odpowiednio małą ikonę i etykietę tekstową w przypadku odpowiedniego komponentu aplikacji.

W każdym przypadku ikona i etykieta ustawiona w elemencie nadrzędnym stają się domyślnymi wartościami icon i label wszystkich elementów podrzędnych. Na przykład ikona i etykieta ustawiona w elemencie <application> są domyślną ikoną i etykietą każdego komponentu, np. wszystkich działań.

Ikona i etykieta ustawiona w elemencie <intent-filter> są wyświetlane użytkownikowi, gdy ten komponent jest prezentowany jako opcja wypełnienia intencji. Domyślnie ta ikona jest dziedziczona z ikony deklarowanej dla komponentu nadrzędnego (<activity> lub <application>).

Możesz zmienić ikonę filtra intencji, jeśli udostępnia on unikalne działanie, które chcesz lepiej oznaczyć w oknie wyboru. Więcej informacji znajdziesz w artykule Zezwalanie innym aplikacjom na rozpoczynanie Twojej aktywności.

Uprawnienia

Aplikacje na Androida muszą prosić o dostęp do poufnych danych użytkownika, np. kontaktów i SMS-ów, lub dostępu do określonych funkcji systemowych, takich jak aparat czy dostęp do internetu. Każde uprawnienie jest oznaczone unikalną etykietą. Na przykład aplikacja, która musi wysyłać SMS-y, musi mieć w pliku manifestu ten wiersz:

<manifest ... >
    <uses-permission android:name="android.permission.SEND_SMS"/>
    ...
</manifest>

Począwszy od Androida 6.0 (poziom interfejsu API 23) użytkownik może zatwierdzać lub odrzucać niektóre uprawnienia aplikacji w czasie działania. Bez względu na to, którą wersję Androida obsługuje Twoja aplikacja, wszystkie prośby o uprawnienia musisz zadeklarować w pliku manifestu za pomocą elementu <uses-permission>. Jeśli to uprawnienie zostanie przyznane, aplikacja będzie mogła korzystać z funkcji chronionych. W przeciwnym razie próby uzyskania dostępu do tych funkcji się nie uda.

Aplikacja może też chronić własne komponenty za pomocą uprawnień. Może korzystać z dowolnych uprawnień zdefiniowanych przez Androida (wymienionych w sekcji android.Manifest.permission) lub uprawnień zadeklarowanych w innej aplikacji. Aplikacja może też określać własne uprawnienia. W elemencie <permission> zadeklarowano nowe uprawnienie.

Więcej informacji znajdziesz w artykule Uprawnienia na Androidzie.

Zgodność urządzeń

W pliku manifestu możesz też zadeklarować, jakiego typu sprzętu lub funkcji oprogramowania potrzebuje Twoja aplikacja, a także, z jakiego typu urządzeniami jest zgodna. Sklep Google Play nie zezwala użytkownikom na instalowanie Twojej aplikacji na urządzeniach, które nie zapewniają wymaganych funkcji lub wersji systemu wymaganych przez Twoją aplikację.

Istnieje kilka tagów manifestu, które określają, z którymi urządzeniami jest zgodna aplikacja. Oto najpopularniejsze z nich.

<uses-feature>

Element <uses-feature> umożliwia zadeklarowanie funkcji sprzętu i oprogramowania, których potrzebuje Twoja aplikacja. Jeśli na przykład Twoja aplikacja nie działa na urządzeniu bez czujnika kompasu, możesz go zadeklarować, używając tego tagu manifestu:

<manifest ... >
    <uses-feature android:name="android.hardware.sensor.compass"
                  android:required="true" />
    ...
</manifest>

Uwaga: jeśli chcesz udostępnić swoją aplikację na Chromebookach, musisz wziąć pod uwagę kilka ważnych ograniczeń funkcji sprzętu i oprogramowania. Więcej informacji znajdziesz w artykule o zgodności pliku manifestu aplikacji na Chromebookach.

<uses-sdk>

Każda kolejna wersja platformy często dodaje nowe interfejsy API, które nie były dostępne w poprzedniej wersji. Aby można było określić minimalną wersję, z którą aplikacja jest zgodna, plik manifestu musi zawierać tag <uses-sdk> i jego atrybut minSdkVersion.

Pamiętaj jednak, że atrybuty w elemencie <uses-sdk> są zastępowane przez odpowiednie właściwości z pliku build.gradle. Jeśli więc korzystasz z Android Studio, podaj w nim wartości minSdkVersion i targetSdkVersion:

Odlotowe

android {
    defaultConfig {
        applicationId 'com.example.myapp'

        // Defines the minimum API level required to run the app.
        minSdkVersion 21

        // Specifies the API level used to test the app.
        targetSdkVersion 33
        ...
    }
}

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"

        // Defines the minimum API level required to run the app.
        minSdkVersion(21)

        // Specifies the API level used to test the app.
        targetSdkVersion(33)
        ...
    }
}

Więcej informacji o pliku build.gradle znajdziesz w artykule o konfigurowaniu kompilacji.

Aby dowiedzieć się, jak zadeklarować obsługę różnych urządzeń, przeczytaj artykuł o zgodności urządzeń.

Konwencje plików

W tej sekcji opisujemy konwencje i reguły, które zwykle mają zastosowanie do wszystkich elementów i atrybutów w pliku manifestu.

Elementy
Wymagane są tylko elementy <manifest> i <application>. Każda z nich musi wystąpić tylko raz. Większość pozostałych elementów może wystąpić zero lub więcej razy. Niektóre z nich muszą jednak być obecne, aby plik manifestu był przydatny.

Wszystkie wartości są ustawiane za pomocą atrybutów, a nie jako danych znaków w elemencie.

Elementy na tym samym poziomie zwykle nie są uporządkowane. Na przykład elementy <activity>, <provider> i <service> mogą być umieszczone w dowolnej kolejności. Istnieją 2 główne wyjątki od tej reguły:

  • Element <activity-alias> musi występować po elemencie <activity>, dla którego jest aliasem.
  • Element <application> musi być ostatnim elementem wewnątrz elementu <manifest>.
Atrybuty
Z technicznego punktu widzenia wszystkie atrybuty są opcjonalne. Jednak aby element spełnił swoje przeznaczenie, trzeba określić wiele atrybutów. W przypadku atrybutów naprawdę opcjonalnych wartości domyślne znajdziesz w dokumentacji referencyjnej.

Z wyjątkiem niektórych atrybutów elementu głównego <manifest> wszystkie nazwy atrybutów zaczynają się od prefiksu android:, np. android:alwaysRetainTaskState. Ponieważ prefiks jest uniwersalny, dokumentacja zwykle go pomija w odniesieniu do atrybutów według nazwy.

Wiele wartości
Jeśli można określić więcej niż jedną wartość, element jest prawie zawsze powtarzany, a nie w jednym elemencie. Na przykład filtr intencji może wyświetlić listę kilku działań:
<intent-filter ... >
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.INSERT" />
    <action android:name="android.intent.action.DELETE" />
    ...
</intent-filter>
Wartości zasobów
Niektóre atrybuty mają wartości, które są wyświetlane użytkownikom, takie jak tytuł aktywności czy ikona aplikacji. Wartości tych atrybutów mogą różnić się w zależności od języka użytkownika lub konfiguracji urządzenia (np. ze względu na inny rozmiar ikon w zależności od gęstości pikseli na urządzeniu), dlatego wartości powinny być ustawiane na podstawie zasobu lub motywu, a nie na stałe w pliku manifestu. Rzeczywista wartość może się wtedy zmieniać w zależności od zasobów alternatywnych, które udostępniasz dla różnych konfiguracji urządzeń.

Zasoby są wyrażone jako wartości w tym formacie:

"@[package:]type/name"

Możesz pominąć nazwę package, jeśli zasób został dostarczony przez aplikację (np. jeśli pochodzi z zależności biblioteki, ponieważ zasoby biblioteki są scalane z Twoją). Jedyną prawidłową nazwą pakietu jest android, jeśli chcesz użyć zasobu z platformy Android.

type to typ zasobu, np. string lub drawable, a name to nazwa identyfikująca konkretny zasób. Oto przykład:

<activity android:icon="@drawable/smallPic" ... >

Więcej informacji o dodawaniu zasobów do projektu znajdziesz w artykule Omówienie zasobów aplikacji.

Aby zamiast tego zastosować wartość określoną w motywie, pierwszym znakiem musi być ?, a nie @:

"?[package:]type/name"

Wartości ciągu znaków
Gdy wartością atrybutu jest ciąg znaków, użyj podwójnych ukośników lewych (\\) do zmiany znaczenia znaków. Na przykład \\n oznacza nowy wiersz lub \\uxxxx w przypadku znaku Unicode.

Odniesienie do elementów pliku manifestu

W poniższej tabeli znajdziesz linki do dokumentów referencyjnych dotyczących wszystkich prawidłowych elementów w pliku AndroidManifest.xml.

<action> Dodaje działanie do filtra intencji.
<activity> Deklaruje komponent aktywności.
<activity-alias> Deklaruje alias aktywności.
<application> Deklaruje aplikację.
<category> Dodaje nazwę kategorii do filtra intencji.
<compatible-screens> Określa każdą konfigurację ekranu, z którą aplikacja jest zgodna.
<data> Dodaje specyfikację danych do filtra intencji.
<grant-uri-permission> Określa podzbiory danych aplikacji, do których ma dostęp nadrzędny dostawca treści.
<instrumentation> Deklaruje klasę Instrumentation, która umożliwia monitorowanie interakcji aplikacji z systemem.
<intent-filter> Określa typy intencji, na które może reagować działanie, usługa lub odbiornik.
<manifest> Element główny pliku AndroidManifest.xml.
<meta-data> Para nazwa-wartość określająca element dodatkowych, dowolnych danych, które można przekazać do komponentu nadrzędnego.
<path-permission> Definiuje ścieżkę i wymagane uprawnienia do określonego podzbioru danych w ramach dostawcy treści.
<permission> Deklaruje uprawnienia dotyczące zabezpieczeń, które mogą być używane do ograniczenia dostępu do określonych komponentów lub funkcji tej lub innych aplikacji.
<permission-group> Deklaruje nazwę logicznej grupy powiązanych uprawnień.
<permission-tree> Deklaruje podstawową nazwę drzewa uprawnień.
<provider> Deklaruje komponent dostawcy treści.
<queries> Deklaruje zestaw innych aplikacji, do których aplikacja ma mieć dostęp. Więcej informacji znajdziesz w przewodniku na temat filtrowania widoczności pakietów.
<receiver> Deklaruje komponent odbiornika.
<service> Deklaruje komponent usługi.
<supports-gl-texture> Deklaruje format kompresji tekstur pojedynczego GL, który jest obsługiwany przez aplikację.
<supports-screens> Deklaruje rozmiary ekranów, które obsługuje Twoja aplikacja, i włącza tryb zgodności ekranu w przypadku ekranów większych niż obsługiwane przez Twoją aplikację.
<uses-configuration> Wskazuje funkcje wejściowe wymagane przez aplikację.
<uses-feature> Deklaruje pojedynczą funkcję sprzętu lub oprogramowania, które są używane przez aplikację.
<uses-library> Określa bibliotekę współdzieloną, z którą musi być połączona aplikacja.
<uses-native-library> Określa dostarczoną przez dostawcę natywną bibliotekę współdzieloną, z którą aplikacja musi być połączona.
<uses-permission> Określa uprawnienie systemowe, które użytkownik musi przyznać, aby aplikacja mogła działać prawidłowo.
<uses-permission-sdk-23> Określa, że aplikacja potrzebuje określonych uprawnień, ale tylko wtedy, gdy jest zainstalowana na urządzeniu z Androidem 6.0 (poziom interfejsu API 23) lub nowszym.
<uses-sdk> Umożliwia określenie zgodności aplikacji z jedną lub wieloma wersjami platformy Android za pomocą liczby całkowitej poziomu interfejsu API.

Przykładowy plik manifestu

Poniższy kod XML to prosty przykładowy AndroidManifest.xml, który deklaruje 2 działania dla aplikacji.

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

    <!-- Beware that these values are overridden by the build.gradle file -->
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- This name is resolved to com.example.myapp.MainActivity
             based on the namespace property in the build.gradle file -->
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DisplayMessageActivity"
            android:parentActivityName=".MainActivity" />
    </application>
</manifest>