首页 / Android 入门教程 / AndroidManifest 详解

Android 入门教程

AndroidManifest 详解

本教程共 100 篇 · 第 22 篇 · 更新于 2026-07-28 · 约 9 分钟阅读

AndroidAndroid 入门教程AndroidManifest清单文件权限声明组件注册intent-filter

22. AndroidManifest 详解

本节目标:看懂 AndroidManifest.xml 的每个标签和属性,会注册组件、声明权限、配置应用元数据,知道 Manifest 在构建和运行时干什么。

Manifest 是什么

AndroidManifest.xml 是应用的「身份证」和「说明书」,每个应用必须有一个,放在 app/src/main/ 下。它告诉系统和 Google Play:

  • 应用有哪些组件(Activity、Service、Receiver、Provider)。
  • 需要什么权限。
  • 需要什么硬件软件特性(影响哪些设备能装)。
  • 应用图标、名称、主题等元数据。
  • 最低 SDK 版本(虽然现在主要在 build.gradle 声明)。

没在 Manifest 声明的组件,系统不认,启动会崩溃。

整体结构

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 权限声明 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />

    <!-- 硬件软件特性 -->
    <uses-feature android:name="android.hardware.camera" android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApp">

        <!-- 四大组件 -->
        <activity android:name=".MainActivity" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".DetailActivity" />

        <service android:name=".DownloadService" />

        <receiver android:name=".BootReceiver" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

        <!-- meta-data -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="YOUR_API_KEY" />
    </application>

</manifest>

下面逐块拆解。

manifest 根标签

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">
  • xmlns:android:声明 android 命名空间,必须。
  • package旧版本写包名的地方。新版 Gradle 项目改用 build.gradlenamespace,Manifest 里不写 package

权限声明 uses-permission

应用要访问系统功能必须声明权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

权限分两类:

  • 普通权限:安装时自动授权,如 INTERNET
  • 危险权限:运行时要用户授权,如 CAMERAREAD_CONTACTSPOST_NOTIFICATIONS。第 83 章细讲。

maxSdkVersion 表示这个权限只在某个 SDK 以下需要。比如分区存储后,READ_EXTERNAL_STORAGE 在 API 33+ 不再需要。

硬件软件特性 uses-feature

声明应用需要或可选的硬件特性,影响 Google Play 上哪些设备能看到应用:

<!-- 必须有相机,否则装不了 -->
<uses-feature android:name="android.hardware.camera" android:required="true" />

<!-- 可选,有则用,没有也能装 -->
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="false" />
Tip
  • 想让应用在没相机的设备也能装,把相机设 required="false",代码里运行时判断 PackageManager.hasSystemFeature()

application 标签

应用级别的配置,一个 Manifest 只有一个:

<application
    android:name=".MyApplication"               <!-- 自定义 Application 类 -->
    android:allowBackup="true"                  <!-- 允许备份 -->
    android:icon="@mipmap/ic_launcher"          <!-- 应用图标 -->
    android:label="@string/app_name"            <!-- 应用名称 -->
    android:roundIcon="@mipmap/ic_launcher_round"  <!-- 圆形图标 -->
    android:supportsRtl="true"                  <!-- 支持 RTL(阿拉伯语等) -->
    android:theme="@style/Theme.MyApp"          <!-- 默认主题 -->
    android:usesCleartextTraffic="false">       <!-- 是否允许 HTTP 明文 -->

常用属性:

  • android:name:自定义 Application 子类,应用启动时最先创建。需要全局初始化(如 SDK、日志)时用。
  • android:usesCleartextTraffic:默认 false,禁止 HTTP 明文,强制 HTTPS。要联老服务器 HTTP 接口设 true
  • android:networkSecurityConfig:更精细的网络安全配置(XML 文件)。

Activity 声明

每个 Activity 都要声明:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.MyApp">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

属性:

  • android:name:类名,. 开头表示相对 namespace。
  • android:exported:是否能被其他应用启动。Android 12+ 必须显式声明,启动 Activity 要设 trueMAIN+LAUNCHER 的入口 Activity 必须 true
  • android:launchMode:启动模式(第 27 章讲)。
  • android:screenOrientation:屏幕方向。

intent-filter

声明这个 Activity 能响应什么 Intent。入口 Activity 的 filter:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

MAIN + LAUNCHER 表示这是桌面图标启动的入口。第 30 章细讲 intent-filter。

Service 声明

<service
    android:name=".MusicService"
    android:exported="false"
    android:foregroundServiceType="mediaPlayback" />
Warning
  • Android 14(API 34)起,所有前台服务必须声明 foregroundServiceType,类型有 mediaPlaybackdataSynclocationcameramicrophone 等,启动时要对应权限。不声明直接崩溃。第 33 章细讲。

Receiver 声明

<receiver
    android:name=".BootReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

静态注册的 Receiver 在 Manifest 声明。Android 8.0 起大部分系统广播只能动态注册,只有少数(如 BOOT_COMPLETED)能静态注册。

Provider 声明

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
  • authorities:唯一标识,通常用包名加后缀。${applicationId} 是 Manifest 占位符,编译时替换。
  • grantUriPermissions:是否允许临时授权给其他应用访问 URI。

FileProvider 是最常用的 Provider,分享文件给其他应用时用。

meta-data

给组件或应用附加任意键值对配置,第三方 SDK 常用:

<application>
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="AIzaSy..." />

    <meta-data
        android:name="com.facebook.sdk.ApplicationId"
        android:value="@string/facebook_app_id" />
</application>

代码里读取:

val ai = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
val apiKey = ai.metaData.getString("com.google.android.geo.API_KEY")

Manifest 占位符

build.gradle 里定义占位符,Manifest 里用 ${} 引用:

defaultConfig {
    manifestPlaceholders["appLabel"] = "我的应用"
    manifestPlaceholders["appAuth"] = "com.example.app.provider"
}
<application android:label="${appLabel}">
<provider android:authorities="${appAuth}" />

不同 flavor 用不同值时很有用。

Manifest 合并

最终 APK 里只有一个 Manifest,但项目有多个来源:

  • 主源集 src/main/AndroidManifest.xml
  • 各 flavor 的 src/free/AndroidManifest.xml
  • 各 BuildType 的 src/debug/AndroidManifest.xml
  • 依赖库的 Manifest。

构建时 Gradle 把它们合并成一个。合并规则:标签按属性合并,冲突时用 merge 规则标记解决(tools:replacetools:remove)。

<uses-permission android:name="android.permission.INTERNET"
    tools:node="remove" />   <!-- 移除依赖库带来的这个权限 -->

Android Studio 点 Merged Manifest 能看合并结果,排查冲突很方便。

常见踩坑

组件没声明

ActivityNotFoundException: Unable to find explicit activity class

新建 Activity 忘了在 Manifest 声明。Android Studio 用向导新建会自动加,手动建文件要自己加。

exported 没声明

Android 12+ 报错:

Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined

所有带 intent-filter 的组件必须显式声明 android:exported

权限没声明就用了

调相机没声明 CAMERA 权限,运行时请求权限失败或直接崩溃。危险权限不仅要声明,还要运行时请求。

小结

Manifest 声明应用组件、权限、特性、元数据。application 配置全局属性,四大组件各有对应标签,intent-filter 描述能响应的 Intent,meta-data 附加配置,占位符和合并机制支持多 flavor。组件必须声明才能用,Android 12+ 要显式 exported。下一节学资源体系。