Omówienie pliku manifestu aplikacji

Każdy projekt aplikacji musi zawierać plik AndroidManifest.xml o dokładnie takiej nazwie w katalogu głównym zbioru źródeł projektu. Plik manifestu zawiera podstawowe informacje o aplikacji, które są przekazywane do narzędzi do kompilacji Androida, systemu operacyjnego Android i Google Play.

Plik manifestu musi zawierać m.in. te deklaracje:

  • Komponenty aplikacji, w tym wszystkie aktywności, usługi, odbiorniki i mechanizmy dostarczania 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, takie jak konfiguracje urządzeń, które 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. Deklaruje też uprawnienia, 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 wymagane przez aplikację, które wpływają na to, na jakich urządzeniach można ją zainstalować z Google Play. Więcej informacji o zgodności urządzeń znajdziesz w następnej sekcji.

Jeśli do tworzenia aplikacji używasz Android Studio, plik manifestu jest tworzony automatycznie, a większość podstawowych elementów manifestu jest dodawana podczas tworzenia aplikacji, zwłaszcza gdy używasz szablonów kodu.

Funkcje plików

W sekcjach poniżej opisano, jak niektóre z najważniejszych cech aplikacji są odzwierciedlane w pliku manifestu.

Komponenty aplikacji

Dla każdego komponentu aplikacji, który tworzysz w aplikacji, zadeklaruj odpowiedni element XML w pliku manifestu:

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

Określ nazwę podklasy za pomocą atrybutu name, używając pełnego oznaczenia 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 pierwszym znakiem w wartości name jest kropka, do nazwy jest dodawana przestrzeń nazw aplikacji z właściwości namespace pliku build.gradle na poziomie modułu. Jeśli na przykład przestrzeń nazw to "com.example.myapp", ta nazwa aktywności 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, 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 musisz użyć pełnej nazwy pakietu.

Filtry intencji

Aktywności, usługi i odbiorniki komunikatów aplikacji są aktywowane przez intencje. Intencja to komunikat zdefiniowany przez obiekt Intent, który opisuje działanie do wykonania, w tym dane, na których ma zostać wykonane, kategorię komponentu, który ma wykonać działanie, oraz inne instrukcje.

Gdy aplikacja wysyła intencję do systemu, system lokalizuje komponent aplikacji, który może obsłużyć intencję na podstawie deklaracji filtra intencji w pliku manifestu każdej aplikacji. System uruchamia instancję pasującego komponentu i przekazuje do niego obiekt Intent. Jeśli intencję może obsłużyć więcej niż 1 aplikacja, użytkownik może wybrać, której aplikacji chce 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 dokumencie Intencje i filtry intencji.

Ikony i etykiety

Wiele elementów pliku manifestu ma atrybuty icon i label, które służą do wyświetlania użytkownikom odpowiednio małej ikony i etykiety tekstowej dla danego komponentu aplikacji.

W każdym przypadku ikona i etykieta ustawione w elemencie nadrzędnym stają się domyślną wartością icon i label 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 aktywności.

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

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

Uprawnienia

Aplikacje na Androida muszą prosić o zezwolenie na dostęp do poufnych danych użytkownika, takich jak kontakty i SMS-y, lub do niektórych funkcji systemowych, takich jak aparat i dostęp do internetu. Każde uprawnienie jest identyfikowane przez 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. Niezależnie od tego, którą wersję Androida obsługuje Twoja aplikacja, musisz zadeklarować wszystkie prośby o uprawnienia za pomocą elementu <uses-permission> w pliku manifestu. Jeśli uprawnienie zostanie przyznane, aplikacja będzie mogła korzystać z chronionych funkcji. Jeśli nie, próby uzyskania dostępu do tych funkcji nie powiodą się.

Aplikacja może też chronić swoje komponenty za pomocą uprawnień. Może używać dowolnych uprawnień zdefiniowanych przez Androida, które są wymienione w android.Manifest.permission, lub uprawnień zadeklarowanych w innej aplikacji. Twoja 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 programowych wymaga Twoja aplikacja, a tym samym, z jakimi typami urządzeń jest zgodna. Sklep Google Play nie pozwala użytkownikom instalować aplikacji na urządzeniach, które nie obsługują funkcji lub wersji systemu wymaganych przez aplikację.

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

<uses-feature>

Element <uses-feature> umożliwia zadeklarowanie funkcji sprzętowych i programowych, których wymaga aplikacja. Jeśli na przykład aplikacja nie może realizować podstawowych funkcji na urządzeniu bez czujnika kompasu, możesz zadeklarować, że jest on wymagany, za pomocą tego tagu 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ę pewne istotne ograniczenia dotyczące sprzętu i oprogramowania. Więcej informacji znajdziesz w artykule Zgodność manifestu aplikacji z Chromebookami.

<uses-sdk>

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

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

Dynamiczny

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

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

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

Kotlin

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

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

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

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

Więcej informacji o tym, jak zadeklarować obsługę różnych urządzeń przez aplikację, znajdziesz w omówieniu zgodności urządzeń.

Konwencje dotyczące plików

W tej sekcji opisano konwencje i reguły, które zwykle dotyczą wszystkich elementów i atrybutów w pliku manifestu.

Elements
Wymagane są tylko elementy <manifest> i <application>. Każdy z nich może wystąpić tylko raz. Większość pozostałych elementów może występować 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> i <service> można umieścić w dowolnej kolejności. Od tej reguły są 2 główne wyjątki:

  • Element <activity-alias> musi następować po elemencie <activity>, którego jest aliasem.
  • Element <application> musi być ostatnim elementem wewnątrz elementu <manifest>.
Atrybuty
Technicznie rzecz biorąc, wszystkie atrybuty są opcjonalne. Jednak wiele atrybutów musi być określonych, aby element mógł spełniać swoje zadanie. W przypadku atrybutów, które są naprawdę opcjonalne, wartości domyślne są podane 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. Prefiks jest uniwersalny, dlatego w dokumentacji zwykle pomija się go, gdy odwołuje się do atrybutów według nazwy.

Wiele wartości
Jeśli można podać więcej niż jedną wartość, element jest prawie zawsze powtarzany, a nie wymieniany wielokrotnie w ramach jednego elementu. Na przykład filtr intencji może 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, które są wyświetlane użytkownikom, np. tytuł aktywności lub ikona aplikacji. Wartość tych atrybutów może 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 na podstawie zasobu lub motywu, a nie kodowane 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żone jako wartości w tym formacie:

"@[package:]type/name"

Możesz pominąć nazwę package, jeśli zasób jest dostarczany przez aplikację (w tym jeśli jest dostarczany przez zależność biblioteki, ponieważ zasoby biblioteki są scalane z Twoimi). Jedyną inną prawidłową nazwą pakietu jest android, gdy chcesz użyć zasobu z platformy Androida.

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ść zdefiniowaną w motywie, pierwszym znakiem musi być ? zamiast @:

"?[package:]type/name"

Wartości typu ciąg znaków
Jeśli wartość atrybutu jest ciągiem znaków, użyj podwójnych ukośników lewych (\\) jako znaków modyfikacji, np. \\n dla nowego wiersza lub \\uxxxx dla znaku Unicode.

Dokumentacja elementów pliku manifestu

Tabela poniżej zawiera 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 nadrzędny mechanizm dostarczania treści 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 komunikatów.
<manifest> Element główny pliku AndroidManifest.xml.
<meta-data> Para nazwa-wartość dla elementu dodatkowych, dowolnych danych, które można dostarczyć do komponentu nadrzędnego.
<path-permission> Definiuje ścieżkę i wymagane uprawnienia do określonego podzbioru danych w mechanizmie dostarczania treści.
<permission> Deklaruje uprawnienia zabezpieczeń, które mogą służyć do ograniczania dostępu do określonych komponentów lub funkcji tej lub innych aplikacji.
<permission-group> Deklaruje nazwę grupy logicznej powiązanych uprawnień.
<permission-tree> Deklaruje nazwę podstawową drzewa uprawnień.
<provider> Deklaruje komponent mechanizmu dostarczania treści.
<queries> Deklaruje zestaw innych aplikacji, do których Twoja aplikacja chce uzyskać 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 pojedynczy format kompresji tekstur GL obsługiwany przez aplikację.
<supports-screens> Deklaruje rozmiary ekranu obsługiwane przez aplikację i włącza tryb zgodności z ekranem w przypadku ekranów większych niż obsługiwane przez aplikację.
<uses-configuration> Wskazuje konkretne funkcje wejściowe wymagane przez aplikację.
<uses-feature> Deklaruje pojedynczą funkcję sprzętową lub programową, która jest używana przez aplikację.
<uses-library> Określa bibliotekę udostępnioną, z którą aplikacja musi być połączona.
<uses-native-library> Określa dostarczoną przez dostawcę natywną bibliotekę udostępnioną, z którą aplikacja musi być połączona.
<uses-permission> Określa uprawnienia systemowe, które użytkownik musi przyznać, aby aplikacja działała prawidłowo.
<uses-permission-sdk-23> Określa, że aplikacja wymaga określonego uprawnienia, 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 jedną wersją platformy Androida za pomocą liczby całkowitej poziomu interfejsu API.

Ograniczenia

Liczba wystąpień tych tagów w pliku manifestu jest ograniczona:

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

Te atrybuty mają limit maksymalnej długości:

Atrybut Limit
name 1024
versionName 1024
host 255
mimeType 255

Przykładowy plik manifestu

Poniższy kod XML to prosty przykład pliku AndroidManifest.xml, który deklaruje 2 aktywności 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>