应用清单概述

每个应用项目都必须在项目源集的根目录下包含一个名为AndroidManifest.xml的文件,且名称必须完全一致。清单文件向 Android 构建工具、Android 操作系统和 Google Play 描述了有关您的应用的重要信息。

除许多其他事项外,清单文件还必须声明以下内容:

如果您使用Android Studio构建应用,则会为您创建清单文件,并且在您构建应用时会添加大多数基本清单元素,尤其是在使用代码模板时。

文件功能

以下部分介绍了应用的一些最重要特性如何在清单文件中体现。

应用组件

对于您在应用中创建的每个应用组件,请在清单文件中声明相应的 XML 元素:

如果您对这些组件中的任何一个进行子类化而未在清单文件中声明它,则系统无法启动它。

使用name属性指定子类的名称,使用完整的包名称。例如,Activity子类声明如下:

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

但是,如果name值的第一个字符是句点,则会将模块级build.gradle文件的namespace属性中的应用命名空间作为前缀添加到名称中。例如,如果命名空间是"com.example.myapp",则以下活动名称将解析为com.example.myapp.MainActivity

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

有关设置包名或命名空间的更多信息,请参阅设置命名空间

如果您的应用组件位于子包中,例如在com.example.myapp.purchases中,则name值必须添加缺少的子包名称,例如".purchases.PayActivity",或使用完全限定的包名称。

意图过滤器

应用活动、服务和广播接收器由意图激活。意图是由Intent对象定义的消息,该消息描述要执行的操作,包括要操作的数据、预期执行操作的组件类别以及其他指令。

当应用向系统发出意图时,系统会根据每个应用清单文件中的意图过滤器声明来查找可以处理该意图的应用组件。系统启动匹配组件的实例并将Intent对象传递给该组件。如果多个应用可以处理该意图,则用户可以选择要使用的应用。

应用组件可以具有任意数量的意图过滤器(使用<intent-filter>元素定义),每个过滤器描述该组件的不同功能。

有关更多信息,请参阅意图和意图过滤器文档。

图标和标签

许多清单元素具有iconlabel属性,分别用于向用户显示相应的应用组件的小图标和文本标签。

在每种情况下,在父元素中设置的图标和标签都将成为所有子元素的默认iconlabel值。例如,在<application>元素中设置的图标和标签是应用的每个组件(例如所有活动)的默认图标和标签。

在组件的<intent-filter>中设置的图标和标签会在将该组件作为满足意图的选项呈现给用户时显示。默认情况下,此图标继承自为父组件声明的任何图标,无论是<activity>还是<application>元素。

如果意图过滤器提供独特的操作,您可能希望更改其图标,以便在选择器对话框中更好地指示该操作。有关更多信息,请参阅允许其他应用启动您的活动

权限

Android 应用必须请求权限才能访问敏感用户数据(例如联系人、短信)或某些系统功能(例如相机和互联网访问)。每个权限都由唯一的标签标识。例如,需要发送短信的应用必须在清单中包含以下行:

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

从 Android 6.0(API 级别 23)开始,用户可以在运行时批准或拒绝某些应用权限。但是,无论您的应用支持哪个 Android 版本,都必须使用清单中的<uses-permission>元素声明所有权限请求。如果授予权限,则应用能够使用受保护的功能;如果没有,则其尝试访问这些功能将失败。

您的应用还可以使用权限保护其自身的组件。它可以使用 Android 定义的任何权限(如android.Manifest.permission中列出的权限),或另一个应用中声明的权限。您的应用还可以定义自己的权限。新的权限使用<permission>元素声明。

有关更多信息,请参阅Android 上的权限

设备兼容性

清单文件也是声明您的应用需要哪些类型的硬件或软件功能以及您的应用兼容哪些类型的设备的地方。Google Play 商店不允许用户在不提供您的应用所需的特性或系统版本的设备上安装您的应用。

有几个清单标签定义了您的应用兼容哪些设备。以下是其中一些最常见的标签。

<uses-feature>

<uses-feature> 元素允许您声明应用需要的硬件和软件功能。例如,如果您的应用在没有指南针传感器的设备上无法实现基本功能,则可以使用以下清单标签声明需要指南针传感器:

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

注意:如果您想让您的应用在 Chromebook 上可用,则需要考虑一些重要的硬件和软件功能限制。有关更多信息,请参阅Chromebook 的应用清单兼容性

<uses-sdk>

每个后续平台版本通常都会添加前一个版本中不可用的新 API。要指示您的应用兼容的最低版本,您的清单必须包含<uses-sdk>标签及其minSdkVersion属性。

但是,请注意,<uses-sdk>元素中的属性会被build.gradle文件中的相应属性覆盖。因此,如果您使用的是 Android Studio,请在其中指定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)
        ...
    }
}

有关build.gradle文件的更多信息,请阅读有关如何配置构建的内容。

要了解有关如何声明您的应用对不同设备的支持的更多信息,请参阅设备兼容性概述

文件约定

本节描述通常适用于清单文件中的所有元素和属性的约定和规则。

元素
只有<manifest><application>元素是必需的。它们每个都只能出现一次。大多数其他元素可以出现零次或多次。但是,其中一些元素必须存在才能使清单文件有用。

所有值都是通过属性设置的,而不是作为元素内的字符数据。

同一级别的元素通常没有顺序。例如,<activity><provider><service>元素可以按任何顺序放置。此规则有两个关键例外:

  • <activity-alias>元素必须跟随它是其别名的<activity>
  • <application>元素必须是<manifest>元素中的最后一个元素。
属性
从技术上讲,所有属性都是可选的。但是,必须指定许多属性才能使元素实现其目的。对于真正可选的属性,参考文档指示默认值。

除了根<manifest>元素的某些属性外,所有属性名称都以android:前缀开头,例如android:alwaysRetainTaskState。由于前缀是通用的,因此文档在按名称引用属性时通常会省略它。

多个值
如果可以指定多个值,则几乎总是重复该元素,而不是在单个元素内列出多个值。例如,意图过滤器可以列出多个操作。
<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>
资源值
某些属性的值会显示给用户,例如活动的标题或您的应用图标。这些属性的值可能会因用户的语言或其他设备配置而异(例如,根据设备的像素密度提供不同的图标大小),因此应从资源或主题设置这些值,而不是硬编码到清单文件中。然后,实际值可以根据您为不同的设备配置提供的替代资源而更改。

资源以以下格式表达值:

"@[package:]type/name"

如果资源由您的应用提供(包括由库依赖项提供,因为库资源会合并到您的资源中),您可以省略package名称。唯一其他有效的包名称是android,当您要使用来自 Android 框架的资源时。

type是资源类型,例如stringdrawable,而name是标识特定资源的名称。这是一个示例:

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

有关如何将资源添加到项目的更多信息,请阅读应用资源概述

要改为应用在主题中定义的值,第一个字符必须是?而不是@

"?[package:]type/name"

字符串值
如果属性值是字符串,请使用双反斜杠(\\)转义字符,例如\\n表示换行符或\\uxxxx表示 Unicode 字符。

清单元素参考

下表提供了指向AndroidManifest.xml文件中所有有效元素的参考文档的链接。

<action> 向意图过滤器添加操作。
<activity> 声明活动组件。
<activity-alias> 声明活动的别名。
<application> 声明应用程序。
<category> 向意图过滤器添加类别名称。
<compatible-screens> 指定应用程序兼容的每个屏幕配置。
<data> 向意图过滤器添加数据规范。
<grant-uri-permission> 指定父内容提供程序有权访问的应用程序数据的子集。
<instrumentation> 声明一个Instrumentation类,允许您监视应用程序与系统的交互。
<intent-filter> 指定活动、服务或广播接收器可以响应的意图类型。
<manifest> AndroidManifest.xml文件的根元素。
<meta-data> 可以提供给父组件的附加任意数据的项的名称-值对。
<path-permission> 定义内容提供程序内特定数据子集的路径和所需权限。
<permission> 声明安全权限,可用于限制对本应用程序或其他应用程序的特定组件或功能的访问。
<permission-group> 声明相关权限的逻辑分组的名称。
<permission-tree> 声明权限树的基名称。
<provider> 声明内容提供程序组件。
<queries> 声明您的应用打算访问的其他应用的集合。在有关包可见性筛选的指南中了解更多信息。
<receiver> 声明广播接收器组件。
<service> 声明服务组件。
<supports-gl-texture> 声明应用支持的单个 GL 纹理压缩格式。
<supports-screens> 指定您的应用支持的屏幕尺寸,并为大于应用支持的屏幕启用屏幕兼容模式。
<uses-configuration> 指示应用程序需要的特定输入功能。
<uses-feature> 声明应用程序使用的单个硬件或软件功能。
<uses-library> 指定应用程序必须链接到的共享库。
<uses-native-library> 指定应用程序必须链接到的供应商提供的本机共享库。
<uses-permission> 指定用户必须授予的系统权限,以便应用能够正常运行。
<uses-permission-sdk-23> 指定应用想要特定权限,但前提是应用安装在运行 Android 6.0(API 级别 23)或更高版本的设备上。
<uses-sdk> 允许您通过 API 级别整数表达应用程序与一个或多个 Android 平台版本的兼容性。

限制

以下标签在清单文件中的出现次数有限制:

标签名称 限制
<package> 1000
<meta-data> 1000
<uses-library> 1000

以下属性对其最大长度有限制:

属性 限制
name 1024
versionName 1024
host 255
mimeType 255

示例清单文件

下面的 XML 是一个简单的示例AndroidManifest.xml,它为应用声明了两个活动。

<?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>