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 dla narzędzi do tworzenia aplikacji na Androida, systemu operacyjnego Android i Google Play.

Plik manifestu jest wymagany m.in. do zadeklarowania tych elementów:

  • Komponenty aplikacji, w tym wszystkie działania, 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. konfiguracje urządzeń, które może obsługiwać, oraz filtry intencji opisujące, 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, jeśli chcą 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 zainstalować aplikację z Google Play. Więcej informacji o zgodności urządzeń znajdziesz w następnej sekcji.

Jeśli do tworzenia aplikacji używasz Androida Studio, plik manifestu zostanie utworzony automatycznie, a większość podstawowych elementów manifestu zostanie dodana podczas tworzenia aplikacji, zwłaszcza gdy używasz szablonów kodu.

Funkcje pliku

W kolejnych sekcjach opisujemy, jak niektóre najważniejsze cechy aplikacji są odzwierciedlane w pliku manifestu.

Komponenty aplikacji

Każdy komponent aplikacji, który utworzysz w aplikacji, zadeklaruj w pliku manifestu za pomocą odpowiedniego elementu XML:

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ł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, do nazwy zostanie dodana przestrzeń nazw aplikacji z właściwości build.gradle w pliku namespace na poziomie modułu. Jeśli na przykład przestrzeń nazw to "com.example.myapp", nazwa działania `".MainActivity"` zostanie przekształcona na 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 użyć pełnej i jednoznacznej nazwy pakietu.

Filtry intencji

Działania, usługi i odbiorniki transmisji 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 działanie, kategorię komponentu, który ma wykonać działanie, oraz inne instrukcje.

Gdy aplikacja wysyła do systemu intencję, system wyszukuje komponent aplikacji, który może obsłużyć intencję, na podstawie deklaracji filtrów 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ą możliwość tego 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 służą odpowiednio do wyświetlania użytkownikom małej ikony i etykiety tekstowej dla odpowiedniego 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ą dla każdego komponentu aplikacji, np. wszystkich działań.

Ikona i etykieta ustawione w elemencie komponentu <intent-filter> są wyświetlane użytkownikowi, gdy ten komponent jest prezentowany jako opcja realizacji 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 Twojej aktywności.

Uprawnienia

Aplikacje na Androida muszą prosić o uprawnienia dostępu do danych wrażliwych użytkownika, takich jak kontakty i SMS-y, lub do niektórych funkcji systemu, 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 manifeście ten wiersz:

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

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ą <uses-permission> elementu w pliku manifestu. Jeśli uprawnienie zostanie przyznane, aplikacja będzie mogła korzystać z chronionych funkcji. W przeciwnym razie próby uzyskania dostępu do tych funkcji zakończą się niepowodzeniem.

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 uprawnienia zadeklarowanego 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 w 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 mają funkcji lub wersji systemu wymaganych przez aplikację.

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

<uses-feature>

Element <uses-feature> umożliwia deklarowanie funkcji sprzętowych i programowych, których potrzebuje Twoja aplikacja. Jeśli na przykład aplikacja nie może wykonywać podstawowych funkcji na urządzeniu bez czujnika kompasu, możesz zadeklarować, że czujnik kompasu jest 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 ważne ograniczenia dotyczące funkcji sprzętowych i programowych. 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ą 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 odpowiednie właściwości w pliku build.gradle. Jeśli więc używasz Androida Studio, określ wartości minSdkVersion i targetSdkVersion w tym pliku:

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 Konfigurowanie kompilacji.

Aby dowiedzieć się więcej o deklarowaniu obsługi różnych urządzeń przez aplikację, przeczytaj artykuł Omówienie zgodności urządzeń.

Konwencje dotyczące plików

W tej sekcji opisujemy konwencje i reguły, które ogólnie obowiązują w przypadku wszystkich elementów i atrybutów w pliku manifestu.

Elementy
Wymagane są tylko elementy <manifest> i <application>. Każdy z nich musi występować tylko raz. Większość pozostałych elementów może występować 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 dane znakowe w elemencie.

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

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

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 pomija go, gdy odwołuje się do atrybutów według nazwy.

Wiele wartości
Jeśli można określić więcej niż 1 wartość, element jest prawie zawsze powtarzany, a nie wymieniany w jednym elemencie. 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ł działania 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 należy ustawiać 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 alternatywnych zasobów, które udostępniasz w przypadku różnych konfiguracji urządzenia.

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

"@[package:]type/name"

Jeśli zasób jest udostępniany przez Twoją aplikację (w tym przez zależność biblioteki, ponieważ zasoby biblioteki są scalane z Twoimi), możesz pominąć nazwę package. Jedyną inną prawidłową nazwą pakietu jest android, gdy 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 zastosować wartość zdefiniowaną w motywie, pierwszy znak 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ójnego ukośnika lewego (\\), aby zmienić znaczenie znaków, np. \\n w przypadku nowego wiersza lub \\uxxxx w przypadku znaku Unicode.

Dokumentacja elementów 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 działania.
<activity-alias> Deklaruje alias działania.
<application> Deklaruje aplikację.
<category> Dodaje nazwę kategorii do filtra intencji.
<compatible-screens> Określa każdą konfigurację ekranu, z którą jest zgodna aplikacja.
<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 odpowiadać działanie, 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 przekazać do komponentu nadrzędnego.
<path-permission> Definiuje ścieżkę i wymagane uprawnienia dla określonego podzbioru danych w dostawcy treści.
<permission> Deklaruje uprawnienie zabezpieczeń, które można wykorzystać do ograniczenia dostępu do określonych komponentów lub funkcji tej lub innych aplikacji.
<permission-group> Deklaruje nazwę logicznego grupowania powiązanych uprawnień.
<permission-tree> Deklaruje nazwę podstawową drzewa uprawnień.
<provider> Deklaruje komponent dostawcy treści.
<queries> Deklaruje zbiór innych aplikacji, do których Twoja aplikacja ma mieć dostęp. Więcej informacji znajdziesz w przewodniku na temat filtrowania widoczności pakietów.
<receiver> Deklaruje komponent odbiornika transmisji.
<service> Deklaruje komponent usługi.
<supports-gl-texture> Deklaruje pojedynczy format kompresji tekstur GL, który obsługuje aplikacja.
<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ścia wymagane przez aplikację.
<uses-feature> Deklaruje pojedynczą funkcję sprzętową lub programową używaną przez aplikację.
<uses-library> Określa bibliotekę współdzieloną, z którą musi być połączona aplikacja.
<uses-native-library> Określa natywną bibliotekę współdzieloną dostarczoną przez dostawcę, z którą musi być połączona aplikacja.
<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 wyrażenie zgodności aplikacji z co najmniej jedną wersją platformy Android 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

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

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 działania 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>