拒绝踩坑!Android 11/12 升级必看的 Manifest 适配指南
一、Manifest 是什么
AndroidManifest.xml 位于 src/main/ 下,是每个 Android 应用必须有且唯一的声明文件。它在应用还没运行时就被系统读取,用来回答几个关键问题:
- 这个应用有哪些组件(Activity / Service / BroadcastReceiver / ContentProvider)?
- 它需要哪些权限(网络、相机、定位……)?
- 哪个 Activity 是启动入口?
- 哪些组件允许被其他应用调用?
- 兼容哪些设备和系统版本?
一个最小示例:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.HelloWorld">
<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=".DetailsActivity"
android:exported="false" />
</application>
</manifest>
二、核心元素逐个拆
1. <manifest> 根元素
<manifest xmlns:android="..." xmlns:tools="...">
xmlns:android:Android 属性命名空间,必需。xmlns:tools:工具命名空间,用于 Manifest 合并控制、抑制 Lint 警告等(仅构建期生效,不打包进 APK)。
AGP 7+ 之后,包名通过 Gradle 的
namespace声明,不再写在 Manifest 顶部的package属性里。老项目里残留的package="..."可以删掉。
2. <application> 应用级配置
常用属性:
| 属性 | 作用 |
|---|---|
android:icon / android:roundIcon |
应用图标 |
android:label |
应用名称 |
android:theme |
全局默认主题 |
android:supportsRtl |
是否支持从右到左布局(阿拉伯语等) |
android:allowBackup |
是否允许系统自动备份用户数据 |
android:networkSecurityConfig |
网络安全配置(如禁止明文 HTTP) |
android:usesCleartextTraffic |
是否允许明文流量 |
3. 组件声明与 android:exported(重点)
四大组件都必须在 Manifest 里声明(动态注册的广播除外)。其中最关键、也最容易踩坑的是 android:exported:
true:组件可被外部应用启动或访问。false:仅本应用内部可用。
从 Android 12(API 31)起:只要组件包含
<intent-filter>,就必须显式声明android:exported,否则应用直接安装失败。这是一项强制安全要求。很多人升级
targetSdk后第一个遇到的就是这个"装不上"的报错。
原则:默认 false,只有确实需要被外部调用的组件才设 true。一个含 intent-filter 却误设 exported="true" 的内部组件,可能被恶意应用利用,造成越权调用。
4. Intent Filter 与启动入口
<intent-filter> 决定组件能响应哪些 Intent:
- 启动入口:必须同时含
MAINaction 和LAUNCHERcategory,应用才会出现在桌面。 - 深度链接:用
VIEW+<data>声明 scheme/host/path,让网页或其他应用能直接跳到你的指定页面。
<activity android:name=".DeepLinkActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" android:host="example.com" android:pathPrefix="/product"/>
</intent-filter>
</activity>
延伸阅读:Intent 与组件通信
5. 权限与特性
<!-- 声明需要的权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 声明硬件特性,required=false 表示没有也能装 -->
<uses-feature android:name="android.hardware.camera" android:required="false"/>
Manifest 里声明权限只是"申请名额"。从 Android 6.0(API 23)起,危险权限(相机、定位、读写存储等)还必须在运行时动态请求,光在 Manifest 里写是不够的。
6. 包可见性(Android 11+)
从 Android 11(API 30)开始,出于隐私考虑,你的应用默认看不到设备上装了哪些其他应用。如果你要查询、跳转到特定应用,需要用 <queries> 声明:
<queries>
<!-- 我要查询能处理"分享图片"的应用 -->
<intent>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="image/*" />
</intent>
<!-- 我要查询某个特定包 -->
<package android:name="com.example.otherapp"/>
</queries>
忘了声明
<queries>,会出现"在低版本能跳转、升到 Android 11 就跳不动"的诡异 bug。
三、备份与数据迁移规则
android:allowBackup="true" 很方便,但也意味着用户数据可能被备份到云端。敏感数据(令牌、密钥、PII)必须排除。
Auto Backup(Android 6.0+)
通过 android:fullBackupContent="@xml/backup_rules" 指定规则:
<!-- res/xml/backup_rules.xml -->
<full-backup-content>
<exclude domain="sharedpref" path="debug_prefs.xml"/>
<include domain="file" path="user/"/>
</full-backup-content>
数据提取规则(Android 12+)
android:dataExtractionRules="@xml/data_extraction_rules",分别控制"云备份"和"设备间迁移":
<!-- res/xml/data_extraction_rules.xml -->
<data-extraction-rules>
<cloud-backup>
<exclude domain="database" path="cache.db"/>
</cloud-backup>
<device-transfer>
<include domain="sharedpref" path="user_prefs.xml"/>
</device-transfer>
</data-extraction-rules>
注意:永远不要把密钥、令牌、加密材料放进可备份目录。 含个人信息的日志和缓存默认应排除备份,否则可能造成隐私泄露。
四、Manifest 合并与 tools: 命名空间
最终的 Manifest 是"主工程 + 所有依赖库的 Manifest"合并而成的。冲突时用 tools: 干预:
| 属性 | 作用 |
|---|---|
tools:node="remove" |
移除某个从库里合并进来的节点 |
tools:replace="label,icon" |
用本工程的值覆盖库的同名属性 |
tools:ignore="..." |
抑制特定 Lint 警告 |
排查合并冲突:打开 AndroidManifest.xml,切到底部 Merged Manifest 标签页,能看到每个属性最终来自哪个文件。
参考来源:
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)