每个应用项目必须在项目源集的根目录下包含一个名为 AndroidManifest.xml 的文件。 清单文件向 Android 构建工具、Android 操作系统和 Google Play 描述了应用的基本信息。
除其他事项外,清单文件还必须声明以下内容:
- 应用的组件,包括所有 Activity、Service、BroadcastReceiver 和 ContentProvider。每个组件都必须定义基本属性,例如其 Kotlin 或 Java 类的名称。它还可以声明能力,例如它可以处理哪些设备配置,以及描述如何启动该组件的 Intent 过滤器。在后续章节中阅读有关应用组件的更多信息。
- 应用为访问系统受保护部分或其他应用而需要的权限。它还声明了其他应用若要访问此应用的内容所必须具备的权限。在后续章节中阅读有关权限的更多信息。
- 应用所需的硬件和软件功能,这会影响哪些设备可以从 Google Play 安装该应用。在后续章节中阅读有关设备兼容性的更多信息。
如果您使用 Android Studio 构建应用,系统会为您创建清单文件,并且随着您构建应用(尤其是使用代码模板时),大部分必要的清单元素都会自动添加。
文件功能
以下章节介绍了您应用的一些最重要特征如何在清单文件中体现。
应用组件
对于您在应用中创建的每个应用组件,请在清单文件中声明一个对应的 XML 元素:
- 每个
Activity子类对应<activity> - 每个
Service子类对应<service> - 每个
BroadcastReceiver子类对应<receiver> - 每个
ContentProvider子类对应<provider>
如果您创建了这些组件的子类但未在清单文件中声明,系统将无法启动它。
使用 name 属性指定子类的名称,使用完整的包名。例如,Activity 子类的声明如下:
<manifest ... > <application ... > <activity android:name="com.example.myapp.MainActivity" ... > </activity> </application> </manifest>
但是,如果 name 值的第一个字符是句点,则会以前缀的形式将模块级 build.gradle 文件中 namespace 属性定义的应用命名空间添加到名称之前。例如,如果命名空间是 "com.example.myapp",则以下 Activity 名称解析为 com.example.myapp.MainActivity:
<manifest ... > <application ... > <activity android:name=".MainActivity" ... > ... </activity> </application> </manifest>
有关设置包名或命名空间的更多信息,请参阅设置命名空间。
如果您的应用组件位于子包中(例如 com.example.myapp.purchases),则 name 值必须添加缺失的子包名称(例如 ".purchases.PayActivity"),或者使用完全限定的包名。
Intent 过滤器
应用 Activity、Service 和 BroadcastReceiver 由意图 (Intent) 激活。Intent 是由 Intent 对象定义的消息,它描述了要执行的操作,包括要操作的数据、预期执行操作的组件类别以及其他指令。
当应用向系统发出 Intent 时,系统会根据每个应用清单文件中的意图过滤器 (Intent filter) 声明来定位可以处理该 Intent 的应用组件。系统会启动匹配组件的实例,并将 Intent 对象传递给该组件。如果多个应用可以处理该 Intent,则用户可以选择要使用的应用。
应用组件可以有任意数量的意图过滤器(使用 <intent-filter> 元素定义),每个过滤器都描述了该组件的不同功能。
有关详细信息,请参阅意图和意图过滤器文档。
图标和标签
许多清单元素都有 icon 和 label 属性,用于分别为用户显示相应应用组件的小图标和文本标签。
在每种情况下,父元素中设置的图标和标签都会成为所有子元素的默认 icon 和 label 值。例如,在 <application> 元素中设置的图标和标签是该应用每个组件(例如所有 Activity)的默认图标和标签。
组件的 <intent-filter> 中设置的图标和标签会在该组件作为满足 Intent 的选项呈现给用户时显示。默认情况下,此图标继承自为父组件(即 <activity> 或 <application> 元素)声明的图标。
如果您希望意图过滤器提供独特的动作,并且希望在选择器对话框中更好地指示它,则可能需要更改该过滤器的图标。有关详细信息,请参阅允许其他应用启动您的 Activity。
权限
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,请改为在那里指定 minSdkVersion 和 targetSdkVersion 值:
Groovy
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) ... } }
有关 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>
- 资源值
- 某些属性的值会显示给用户,例如 Activity 的标题或应用图标。这些属性的值可能会根据用户的语言或其他设备配置而有所不同(例如,根据设备的像素密度提供不同的图标大小),因此应从资源或主题设置这些值,而不是硬编码到清单文件中。实际值随后可以根据您为不同设备配置提供的替代资源而改变。
资源以以下格式的值表示:
"@[package:]type/name"如果资源由您的应用提供(包括由库依赖项提供,因为库资源会合并到您的应用中),您可以省略 package 名称。当您想要使用 Android 框架中的资源时,唯一有效的其他包名称是
android。type 是资源类型,例如
string或drawable,name 是标识特定资源的名称。这是一个示例:<activity android:icon="@drawable/smallPic" ... >
有关如何向项目添加资源的更多信息,请阅读应用资源概述。
要改为应用 主题中定义的值,第一个字符必须是
?而不是@:"?[package:]type/name" - 字符串值
- 如果属性值是字符串,请使用双反斜杠 (
\\) 来转义字符,例如使用\\n表示换行符,或使用\\uxxxx表示 Unicode 字符。
清单元素参考
下表提供了 AndroidManifest.xml 文件中所有有效元素的参考文档链接。
<action> |
向意图过滤器添加操作。 |
<activity> |
声明 Activity 组件。 |
<activity-alias> |
声明 Activity 的别名。 |
<application> |
声明应用程序。 |
<category> |
向意图过滤器添加类别名称。 |
<compatible-screens> |
指定应用程序兼容的每种屏幕配置。 |
<data> |
向意图过滤器添加数据规范。 |
<grant-uri-permission> |
指定父内容提供程序有权访问的应用数据子集。 |
<instrumentation> |
声明一个 Instrumentation 类,允许您监控应用程序与系统的交互。 |
<intent-filter> |
指定 Activity、Service 或 BroadcastReceiver 可以响应的意图类型。 |
<manifest> |
AndroidManifest.xml 文件的根元素。 |
<meta-data> |
用于可以提供给父组件的额外任意数据的名称-值对。 |
<path-permission> |
为内容提供程序内的数据特定子集定义路径和所需权限。 |
<permission> |
声明可用于限制对特定组件或此应用/其他应用功能的访问的安全权限。 |
<permission-group> |
为相关权限的逻辑分组声明名称。 |
<permission-tree> |
为权限树声明基本名称。 |
<provider> |
声明内容提供程序组件。 |
<queries> |
声明您的应用打算访问的一组其他应用。在关于软件包可见性过滤的指南中了解更多信息。 |
<receiver> |
声明广播接收器组件。 |
<service> |
声明 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 示例,它为应用声明了两个 Activity。
<?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>