每个应用项目都必须在项目源代码集的根目录下有一个 AndroidManifest.xml
文件,且文件名精确无误。清单文件会向 Android 构建工具、Android 操作系统和 Google Play 描述有关应用的基本信息。
清单文件必须声明以下内容(还有许多其他内容):
- 应用的组件,包括所有 activity、服务、广播接收器和 content provider。每个组件都必须定义一些基本属性,如该组件的 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、服务和广播接收器由 intent 激活。intent 是由 Intent
对象定义的消息,它描述了要执行的操作,包括作为操作对象的数据、应执行操作的组件类别,以及其他说明。
当应用向系统发出某个 intent 时,系统会根据每个应用的清单文件中的 intent 过滤器声明来查找可以处理该 intent 的应用组件。系统会启动符合条件的组件的实例,并将 Intent
对象传递给该组件。如果多个应用可以处理相应的 intent,则用户可以选择要使用哪个应用。
一个应用组件可以具有任意多个 intent 过滤器(使用 <intent-filter>
元素定义),每个 intent 过滤器描述该组件的不同功能。
如需了解详情,请参阅 intent 和 intent 过滤器文档。
图标和标签
许多清单元素具有 icon
和 label
属性,分别用于向用户显示相应应用组件的一个小图标和一个文本标签。
在每种情况下,在父元素中设置的图标和标签都会成为所有子元素的默认 icon
和 label
值。例如,在 <application>
元素中设置的图标和标签是应用的每个组件(如所有 activity)的默认图标和标签。
每当某个组件以实现 intent 的一个选项的形式呈现,系统就会向用户显示在该组件的 <intent-filter>
中设置的图标和标签。默认情况下,此图标从针对父组件(<activity>
或 <application>
元素)声明的图标继承而来。
但如果某个 intent 过滤器提供了独一无二的操作,而您希望在选择器对话框中更好地予以指示,那么您可能想要针对该 intent 过滤器更改图标。如需了解详情,请参阅允许其他应用启动您的 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 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
文件,请参阅如何配置 build。
如需详细了解如何声明应用对不同设备的支持,请参阅设备兼容性概览。
文件约定
本部分介绍了通常适用于清单文件中的所有元素和属性的约定和规则。
- 元素
- 只有
<manifest>
和<application>
元素是必需的。这两个元素都只能出现一次。大多数其他元素可以出现零次或多次。不过,为了使清单文件有用,其中某些元素必须存在。所有值均通过属性进行设置,而不是通过元素内的字符数据设置。
同一级别的元素通常不分先后顺序。例如,
<activity>
、<provider>
和<service>
元素可按任意顺序放置。此规则主要有两种例外情况:-
<activity-alias>
元素必须跟在它作为其别名的<activity>
后面。 -
<application>
元素必须是<manifest>
元素内的最后一个元素。
-
- 属性
- 严格意义上来说,所有属性都是可选的。不过,必须指定许多属性,这样元素才能实现其目的。对于真正可选的属性,参考文档中指明了默认值。
除了
<manifest>
根元素的某些属性之外,所有属性名称都以android:
前缀开头,例如android:alwaysRetainTaskState
。由于该前缀是通用的,因此在按名称引用属性时,文档中通常会将其省略。 - 多个值
- 如果可以指定多个值,元素几乎总是重复,而不是在单个元素中列出多个值。例如,一个 intent 过滤器可以列出多项操作:
<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> |
向 intent 过滤器添加操作。 |
<activity> |
声明 activity 组件。 |
<activity-alias> |
声明 activity 的别名。 |
<application> |
声明应用。 |
<category> |
向 intent 过滤器添加类别名称。 |
<compatible-screens> |
指定应用与之兼容的各种屏幕配置。 |
<data> |
向 intent 过滤器添加数据规范。 |
<grant-uri-permission> |
指定父 content provider 有权访问的应用数据的子集。 |
<instrumentation> |
声明用于监控应用与系统交互的 Instrumentation 类。 |
<intent-filter> |
指定 activity、服务或广播接收器可以响应的 intent 类型。 |
<manifest> |
AndroidManifest.xml 文件的根元素。 |
<meta-data> |
可以向父组件提供的其他任意数据项的名称值对。 |
<path-permission> |
定义 content provider 中特定数据子集的路径和所需权限。 |
<permission> |
声明可用于限制访问此应用或其他应用的特定组件或功能的安全权限。 |
<permission-group> |
声明相关权限的逻辑分组的名称。 |
<permission-tree> |
声明权限树的基名。 |
<provider> |
声明一个 content 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
示例,它为应用声明了两个 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>