androidmanifest.xml 的 package 属性必须填与 gradle applicationid 完全一致的顶层包名,而非源码路径;uses-permission 用于全版本权限声明,uses-permission-sdk-23 仅在 api 23+ 编译校验;targetsdkversion ≥ 31 时 activity 必须显式设置 exported;meta-data 必须作为 application 或组件的直接子节点,位置错误将导致功能静默失效。

AndroidManifest.xml 的 package 属性到底填什么
填你应用的真正包名,不是 Gradle 里的 applicationId,也不是 Java/Kotlin 源码的顶层包路径。它必须和 android:sharedUserId、签名验证、ContentProvider authority 等底层机制对齐。
常见错误现象:PackageManagerException: Package com.example.app has no signature 或 SecurityException: Permission Denial,往往是因为 package 值和实际签名/声明不一致。
- Gradle 中的
applicationId "com.example.myapp"是最终发布包的唯一标识,AndroidManifest.xml的package必须与之完全相同 - 源码包路径(如
com.example.myapp.ui)可以更深,但package只能是顶层 ID,不能带子目录 - 如果用了
tools:replace="package",要小心多 module 依赖时 manifest 合并冲突,容易导致 runtimeNoClassDefFoundError
uses-permission 和 uses-permission-sdk-23 的区别在哪
前者声明所有 Android 版本都需要的权限;后者只在 API 23+ 上生效,且仅用于声明「可能需要但不强制请求」的运行时权限——但它本身不触发弹窗,也不替代 requestPermissions() 调用。
使用场景:适配 Android 6.0+ 时,既要兼容旧设备,又要避免在新设备上被系统误判为“未声明敏感权限”而拒绝安装或限制后台行为。
-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>→ 所有版本都声明,但 API 23+ 还需手动请求 -
<uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission-sdk-23>→ 仅在 API 23+ 编译时参与校验,不影响低版本 - 漏掉
uses-permission导致安装失败(targetSdkVersion ≥ 23 且权限属于危险组时);错用uses-permission-sdk-23替代主声明,会导致低版本直接崩溃或功能不可用
activity 的 exported 属性为什么在 targetSdkVersion ≥ 31 后必须显式设置
Android 12(API 31)起,默认禁止未声明 exported 的 <activity></activity> 被其他 App 启动,哪怕它有 intent-filter。不设会直接安装失败,报错:Installation failed with message: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED。
关键判断逻辑取决于是否含 intent-filter:
- 有
intent-filter→ 必须设android:exported="true"(公开入口,如 Launcher Activity)或"false"(私有但被 filter 匹配到,极少见) - 无
intent-filter→ 必须设android:exported="false",否则编译不过 - 混淆工具(R8)不会修改
exported值,但若通过 manifest merger 注入了隐式 filter,可能意外触发校验失败
meta-data 放错位置会导致 Application 类不初始化
<meta-data></meta-data> 必须作为 <application></application> 或具体组件(<activity></activity>、<service></service> 等)的直接子节点,不能嵌套在 <intent-filter></intent-filter> 里,也不能放在 <manifest></manifest> 根下。放错位置不会报错,但对应框架(如 Firebase、Room、Jetpack Compose Navigation)读不到配置,直接跳过初始化。
典型例子:Room 数据库要求 androidx.room:room-runtime 依赖的 androidx.room:room-compiler 会在编译期扫描 <meta-data android:name="androidx.room:databaseConfiguration" ...></meta-data>,位置不对就生成空 DAO 实现。
- 正确位置:
<application><meta-data android:name="..." android:value="..."></meta-data></application> - 错误位置:
<intent-filter><meta-data ...></meta-data></intent-filter>(被忽略) - 值类型别写错:
android:value是字符串,想传布尔或整数得靠android:resource引用@bool/xxx或@integer/xxx
最麻烦的是这类问题不报错、不崩溃,只是功能静默失效——比如通知收不到、数据库查不到数据、DeepLink 打不开页面。调试时得先确认 meta-data 是否被 PackageManager 正确解析,可以用 adb shell dumpsys package <your.package.name></your.package.name> 查看输出里的 meta-data 段。










