Omówienie pliku manifestu aplikacji

Każdy projekt aplikacji musi zawierać plik AndroidManifest.xml o tej nazwie w katalogu głównym zbioru źródeł projektu. Plik manifestu zawiera najważniejsze informacje o aplikacji, które są potrzebne narzędziom do kompilacji Androida, systemowi operacyjnemu Android i Google Play.

Plik manifestu jest wymagany m.in. do deklarowania:

  • Komponenty aplikacji, w tym wszystkie czynności, usługi, odbiorniki transmisji i dostawcy treści. Każdy komponent musi definiować podstawowe właściwości, takie jak nazwa klasy Kotlin lub Java. Może też deklarować możliwości, np. które konfiguracje urządzeń może obsługiwać, oraz filtry intencji, które opisują, jak można uruchomić komponent. Więcej informacji o komponentach aplikacji znajdziesz w następnej sekcji.
  • Uprawnienia, których aplikacja potrzebuje, aby uzyskać dostęp do chronionych części systemu lub innych aplikacji. Zawiera ona również deklarację wszystkich uprawnień, które muszą mieć inne aplikacje, aby uzyskać dostęp do treści z tej aplikacji. Więcej informacji o uprawnieniach znajdziesz w następnej sekcji.
  • funkcje sprzętowe i programowe, których wymaga aplikacja, co wpływa na to, na jakich urządzeniach można zainstalować aplikację z Google Play; Więcej informacji o zgodności urządzeń znajdziesz w następnej sekcji.

Jeśli do kompilowania aplikacji używasz Android Studio, plik manifestu zostanie utworzony automatycznie, a większość jego najważniejszych elementów zostanie dodana podczas kompilowania aplikacji, zwłaszcza jeśli używasz szablonów kodu.

Funkcje plików

W poniższych sekcjach opisano, jak niektóre z najważniejszych właściwości aplikacji są odzwierciedlane w pliku manifestu.

Komponenty aplikacji

W pliku manifestu zadeklaruj odpowiedni element XML dla każdego elementu aplikacji, który utworzysz w aplikacji:

Jeśli utworzysz podklasę któregoś z tych komponentów bez zadeklarowania go w pliku manifestu, system nie będzie mógł go uruchomić.

Określ nazwę podklasy za pomocą atrybutu name, używając pełnej nazwy pakietu. Na przykład podklasa Activity jest deklarowana 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 to kropka, przed nazwą zostanie dodany prefiks z przestrzeni nazw aplikacji z elementu namespace w pliku build.gradle na poziomie modułu. Jeśli na przykład przestrzeń nazw to "com.example.myapp", nazwa aktywności com.example.myapp.MainActivity zostanie przekształcona w com.example.myapp.MainActivity:

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

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

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

Filtry intencji

Aktywności aplikacji, usługi i odbiorniki transmisji są aktywowane przez intencje. Intencja to wiadomość zdefiniowana przez obiekt Intent, która opisuje działanie do wykonania, w tym dane, na których ma ono polegać, kategorię komponentu, który ma je wykonać, oraz inne instrukcje.

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

Komponent aplikacji może mieć dowolną liczbę filtrów intencji (zdefiniowanych za pomocą elementu <intent-filter>), z których każdy opisuje inną funkcję tego komponentu.

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

Ikony i etykiety

Niektóre elementy pliku manifestu mają atrybuty iconlabel, które służą do wyświetlania użytkownikom odpowiedniego elementu aplikacji odpowiednio w postaci małej ikony lub etykiety tekstowej.

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

Ikona i etykieta ustawione w komponencie<intent-filter>są wyświetlane użytkownikowi, gdy komponent jest prezentowany jako opcja realizacji zamiaru. Domyślnie ta ikona jest dziedziczona z ikony zadeklarowanej dla komponentu nadrzędnego, czyli z elementu <activity> lub <application>.

Możesz zmienić ikonę filtra intencji, jeśli zawiera ono unikalne działanie, które chcesz lepiej przedstawić w oknie wyboru. Więcej informacji znajdziesz w artykule Zezwalanie innym aplikacjom na uruchamianie aktywności.

Uprawnienia

Aplikacje na Androida muszą prosić o dostęp do danych wrażliwych użytkownika, takich jak kontakty i SMS-y, lub do określonych funkcji systemu, takich jak aparat i dostęp do internetu. Każde uprawnienie jest oznaczone unikalną etykietą. Na przykład aplikacja, która musi wysyłać SMS-y, musi zawierać w pliku manifestu tę linię:

<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. Niezależnie od tego, którą wersję Androida obsługuje Twoja aplikacja, musisz zadeklarować wszystkie żądania uprawnień za pomocą elementu <uses-permission> w manifeście. Jeśli użytkownik przyzna takie uprawnienia, aplikacja będzie mogła korzystać z funkcji chronionych. W przeciwnym razie próby uzyskania dostępu do tych funkcji się nie powiedzie.

Aplikacja może też chronić swoje komponenty za pomocą uprawnień. Może ona używać dowolnych uprawnień zdefiniowanych przez Androida (wymienionych w sekcji android.Manifest.permission) lub uprawnień zadeklarowanych w innej aplikacji. Aplikacja może też definiować własne uprawnienia. Nowe uprawnienie jest deklarowane za pomocą elementu <permission>.

Więcej informacji znajdziesz w artykule Uprawnienia na Androidzie.

Zgodność urządzeń

W pliku manifestu możesz też zadeklarować, jakich funkcji sprzętowych lub oprogramowania wymaga Twoja aplikacja, a zarazem określić, z jakimi urządzeniami jest zgodna. Sklep Google Play nie pozwala użytkownikom instalować aplikacji na urządzeniach, które nie mają funkcji lub wersji systemu wymaganych przez aplikację.

Istnieje kilka tagów pliku manifestu, które określają, z jakimi urządzeniami jest zgodna aplikacja. Oto kilka najczęstszych:

<uses-feature>

Element <uses-feature> umożliwia zadeklarowanie funkcji sprzętu i oprogramowania, których potrzebuje aplikacja. Jeśli na przykład Twoja aplikacja nie może uzyskać podstawowej funkcjonalności na urządzeniu bez czujnika kompasu, możesz zadeklarować ten czujnik jako wymagany za pomocą tego tagu w pliku manifestu:

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

Uwaga: jeśli chcesz udostępnić aplikację na Chromebookach, musisz wziąć pod uwagę niektóre ważne ograniczenia funkcji sprzętowych i programowych. Więcej informacji znajdziesz w artykule Kompatybilność pliku manifestu aplikacji na Chromebookach.

<uses-sdk>

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

Pamiętaj jednak, że atrybuty w elemencie <uses-sdk> są zastępowane przez odpowiadające im właściwości w pliku build.gradle. Jeśli używasz Android Studio, zamiast tego podaj tam wartości minSdkVersiontargetSdkVersion:

Groovy

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 Jak skonfigurować kompilację.

Więcej informacji o deklarowaniu obsługi różnych urządzeń przez aplikację znajdziesz w artykule Omówienie zgodności z urządzeniami.

Konwencje dotyczące plików

W tej sekcji opisano konwencje i zasady, które ogólnie dotyczą wszystkich elementów i atrybutów w pliku manifestu.

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

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

Elementy na tym samym poziomie nie są zwykle uporządkowane. Na przykład elementy <activity>, <provider><service> można umieścić w dowolnej kolejności. Istnieją 2 kluczowe wyjątki od tej reguły:

  • Element <activity-alias> musi znajdować się po elemencie <activity>, którego jest aliasem.
  • Element <application> musi być ostatnim elementem w elemencie <manifest>.
Atrybuty
Formalnie wszystkie atrybuty są opcjonalne. Jednak wiele atrybutów musi być określonych, aby element mógł spełniać swoje zadanie. W przypadku atrybutów opcjonalnych dokumentacja podaje wartości domyślne.

Z wyjątkiem niektórych atrybutów elementu <manifest> wszystkie nazwy atrybutów zaczynają się od prefiksu android:, na przykład android:alwaysRetainTaskState. Ponieważ prefiks jest uniwersalny, w dokumentacji zazwyczaj pomija się go, gdy mowa o atrybutach według nazwy.

Wiele wartości
Jeśli można podać więcej niż jedną wartość, element jest prawie zawsze powtarzany, a nie podaje się kilku wartości w ramach jednego elementu. Filtr intencji może na przykład zawierać kilka 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 wyświetlane użytkownikom, np. tytuł aktywności lub ikonę aplikacji. Wartości tych atrybutów mogą się różnić w zależności od języka użytkownika lub innych konfiguracji urządzenia (np. aby zapewnić inny rozmiar ikony w zależności od gęstości pikseli urządzenia). Dlatego wartości powinny być ustawiane w zasobach lub motywie, a nie zakodowane na stałe w pliku manifestu. Rzeczywista wartość może się zmieniać w zależności od zasobów alternatywnych, które udostępniasz dla różnych konfiguracji urządzeń.

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

"@[package:]type/name"

Możesz pominąć nazwę package, jeśli zasób jest dostarczany przez Twoją aplikację (w tym przez bibliotekę zależną, ponieważ zasoby biblioteki są scalane z Twoimi). Jeśli chcesz użyć zasobu z ramy Androida, jedyną prawidłową nazwą pakietu jest 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 zastosować wartość zdefiniowaną w motywie, pierwszym znakiem musi być ?, a nie @:

"?[package:]type/name"

Wartości ciągu znaków
Jeśli wartość atrybutu jest ciągiem znaków, użyj podwójnego ukośnika wstecznego (\\), aby uciec od znaków, takich jak \\n dla znaku końca wiersza lub \\uxxxx dla znaku Unicode.

Odwołania do elementów pliku manifestu

Tabela poniżej zawiera linki do dokumentów referencyjnych wszystkich prawidłowych elementów w pliku AndroidManifest.xml.

<action> Dodaje działanie do filtra intencji.
<activity> Deklaruje komponent aktywności.
<activity-alias> Określa 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 dostawca treści nadrzędnych ma uprawnienia dostępu.
<instrumentation> Deklaruje klasę Instrumentation, która umożliwia monitorowanie interakcji aplikacji z systemem.
<intent-filter> Określa typy intencji, na które może odpowiadać aktywność, usługa lub odbiornik transmisji.
<manifest> Element główny pliku AndroidManifest.xml.
<meta-data> Para nazwa-wartość dla elementu dodatkowych, dowolnych danych, które można podać do komponentu nadrzędnego.
<path-permission> Określa ścieżkę i wymagane uprawnienia dla określonego podzbioru danych w ramach dostawcy treści.
<permission> Opisuje uprawnienie zabezpieczające, które może służyć do ograniczania dostępu do określonych komponentów lub funkcji tej lub innych aplikacji.
<permission-group> Określa nazwę logicznego grupowania powiązanych uprawnień.
<permission-tree> Deklaruje nazwę podstawową dla drzewa uprawnień.
<provider> Deklaruje komponent dostawcy treści.
<queries> Określa zestaw innych aplikacji, do których Twoja aplikacja ma uzyskiwać dostęp. Więcej informacji znajdziesz w przewodniku na temat filtrowania widoczności pakietu.
<receiver> Deklaruje komponent odbiornika transmisji.
<service> Deklaruje komponent usługi.
<supports-gl-texture> Określa pojedynczy format kompresji tekstur GL, który obsługuje aplikacja.
<supports-screens> Deklaruje rozmiary ekranów obsługiwane przez aplikację i włącza tryb zgodności ekranu na ekranach większych niż obsługiwane przez aplikację.
<uses-configuration> Wskazuje, jakich funkcji wejściowych wymaga aplikacja.
<uses-feature> Zadeklaruj pojedynczą funkcję sprzętową lub programową, z której korzysta aplikacja.
<uses-library> Określa wspólną bibliotekę, z którą aplikacja musi być powiązana.
<uses-native-library> Określa natywną bibliotekę udostępnioną przez dostawcę, z którą aplikacja musi być połączona.
<uses-permission> Określa uprawnienie systemowe, które użytkownik musi przyznać, aby aplikacja działała prawidłowo.
<uses-permission-sdk-23> Określa, że aplikacja chce uzyskać określone uprawnienie, 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 co najmniej 1 wersją platformy Android za pomocą liczby całkowitej poziomu interfejsu API.

Limity

W pliku manifestu można użyć określonej liczby wystąpień tych tagów:

Nazwa tagu Limit
<package> 1000
<meta-data> 1000
<uses-library> 1000

Maksymalna długość tych atrybutów jest ograniczona:

Atrybut Limit
name 1024
versionName 1024
host 255
mimeType 255

Przykładowy plik manifestu

Poniżej znajduje się prosty przykład kodu XML AndroidManifest.xml, który deklaruje 2 aktywności w 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>