每个应用项目都必须在其项目源集的根目录下拥有一个名为 AndroidManifest.xml
的文件,名称必须完全一致。此清单文件向 Android 构建工具、Android 操作系统和 Google Play 描述了关于应用的重要信息。
除其他许多事项外,清单文件还必须声明以下内容:
- 应用的组件,包括所有 Activity、Service、广播接收器和内容提供程序。每个组件必须定义基本属性,例如其 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 和广播接收器由 intent 激活。Intent 是由 Intent
对象定义的消息,它描述要执行的操作,包括要操作的数据、预期执行操作的组件类别以及其他指令。
当应用向系统发出 Intent 时,系统根据每个应用清单文件中的 Intent 过滤器声明,找到可以处理该 Intent 的应用组件。系统启动匹配组件的实例,并将 Intent
对象传递给该组件。如果有多个应用可以处理该 Intent,则用户可以选择要使用的应用。
应用组件可以有任意数量的 Intent 过滤器(使用 <intent-filter>
元素定义),每个过滤器描述该组件的不同功能。
有关更多信息,请参阅Intent 和 Intent 过滤器文档。
图标和标签
许多清单元素都具有 icon
和 label
属性,分别用于向用户显示对应应用组件的小图标和文本标签。
在任何情况下,在父元素中设置的图标和标签都会成为所有子元素的默认 icon
和 label
值。例如,在 <application>
元素中设置的图标和标签是应用每个组件(例如所有 Activity)的默认图标和标签。
当组件作为履行 Intent 的选项呈现给用户时,将显示在组件的 <intent-filter>
中设置的图标和标签。默认情况下,此图标继承自为其父组件(无论是 <activity>
还是 <application>
元素)声明的图标。
如果 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
文件的更多信息,请阅读有关如何配置构建的说明。
要了解有关如何声明应用对不同设备的支持的更多信息,请参阅设备兼容性概览。
文件约定
本节描述了通常适用于清单文件中所有元素和属性的约定和规则。
- 元素
- 只有
<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> |
指定父内容提供程序有权访问的应用数据子集。 |
<instrumentation> |
声明一个 Instrumentation 类,允许您监控应用程序与系统的交互。 |
<intent-filter> |
指定 activity、服务或广播接收器可以响应的 intent 类型。 |
<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
示例,它为应用声明了两个 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>