每个应用项目都必须在 AndroidManifest.xml
文件的根目录中有一个具有此确切名称的文件,位于 项目源集 中。 清单文件向 Android 构建工具、Android 操作系统和 Google Play 描述了有关您的应用的基本信息。
除了其他许多内容外,清单文件还必须声明以下内容
- 应用的组件,包括所有活动、服务、广播接收器和内容提供者。每个组件都必须定义基本属性,例如其 Kotlin 或 Java 类的名称。它还可以声明功能,例如它可以处理哪些设备配置以及描述如何启动组件的意图过滤器。 在后面的部分中详细了解应用组件。
- 应用需要访问系统或其他应用的受保护部分的权限。它还声明其他应用如果要访问此应用中的内容所需的权限。 在后面的部分中详细了解权限。
- 应用所需的硬件和软件功能,这将影响哪些设备可以从 Google Play 安装应用。 在后面的部分中详细了解设备兼容性。
如果您使用 Android Studio 构建应用,则会为您创建清单文件,并且在构建应用时会添加大多数基本清单元素,尤其是在使用 代码模板 时。
文件功能
以下部分介绍了应用的一些最重要特征如何在清单文件中反映出来。
应用组件
对于在应用中创建的每个 应用组件,请在清单文件中声明一个相应的 XML 元素
<activity>
,用于Activity
的每个子类<service>
,用于Service
的每个子类<receiver>
用于每个BroadcastReceiver
子类。<provider>
用于每个ContentProvider
子类。
如果您继承了这些组件的任何子类,但未在清单文件中声明它,则系统无法启动它。
使用 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>
元素定义),每个意图过滤器都描述该组件的不同功能。
有关更多信息,请参阅 意图和意图过滤器 文档。
图标和标签
许多清单元素具有 icon
和 label
属性,分别用于为用户显示对应应用程序组件的小图标和文本标签。
在所有情况下,在父元素中设置的图标和标签将成为所有子元素的默认 icon
和 label
值。例如,在 <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,请在其中指定 minSdkVersion
和 targetSdkVersion
值,而不是在清单文件中指定。
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 是资源类型,例如
string
或drawable
,而 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>