3. AndroidManifest.xml 权限声明:POST_NOTIFICATIONS

在 Android 13 (API 33) 中,通知权限从以往的“安装即授权”转变为“运行时权限”。应用必须先在 AndroidManifest.xml 中静态声明 POST_NOTIFICATIONS 权限,才能在实际运行时向系统请求用户授权。本章将围绕该声明的原理、标准写法、检查手段以及常见踩坑点展开。

3.1 原理:为何需要静态声明

Android 权限系统中,普通权限(Normal Permissions)在安装时自动授予;危险权限(Dangerous Permissions)则需运行时动态申请。Android 13 将 POST_NOTIFICATIONS 归类为危险权限,因此必须满足两个条件:

  • 在 AndroidManifest.xml 中使用 <uses-permission> 标签声明
  • 运行时调用 requestPermissions() 或 ActivityResultLauncher 获取用户同意

静态声明是动态请求的前提——若缺少声明,系统将在运行时直接拒绝授权,且不会弹出对话框。

Android 版本 通知权限管理方式 是否需声明 POST_NOTIFICATIONS
Android 12 及更低 安装即授权,应用可随时发送通知 否(声明会被忽略)
Android 13+ 运行时危险权限,需用户授权 是(必须声明)

3.2 实现流程

在项目的 src/main/AndroidManifest.xml 文件中,将权限声明放置在 <manifest> 根元素下、<application> 元素之前。标准写法如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        ...>
        ...
    </application>

</manifest>
提示: 若你的应用同时支持 Android 13 及以下版本,建议在声明时添加 android:maxSdkVersion 属性以避免低版本上无意义的权限声明(虽然并无副作用),但更常见的做法是直接声明,系统在低版本会自动忽略。

3.3 声明后的验证与调试

声明完成后,可以通过以下两种方式验证权限是否被正确识别:

  1. 编译检查: 运行 ./gradlew assembleDebug,Gradle 不会因权限声明报错;若存在拼写错误(如 POST_NOTIFICATIONS 写成 POST_NOTIFICATION),编译器会提示“Permission name not found”。
  2. ADB 命令检查: 安装应用后,使用 adb shell dumpsys package <包名> 查看权限列表:
adb shell dumpsys package com.example.yourapp | grep -A 10 "runtime-permissions"

输出中应出现类似如下条目:

  android.permission.POST_NOTIFICATIONS: granted=false, flags=[ REVOKE_WHEN_REQUESTED ]

若未出现该条目,说明 Manifest 中未正确声明或 targetSdkVersion 未升至 33+。

3.4 常见错误及规避

错误 1:声明位置错误 —— <uses-permission> 必须写在 <manifest> 的直接子级,不能放在 <application> 内部。否则编译期可能不报错,但运行时权限无法被识别。
错误 2:拼写错误或遗漏 —— 权限常量必须为 android.permission.POST_NOTIFICATIONS(注意复数 NOTIFICATIONS)。误写为 NOTIFICATION(单数)将导致编译失败。
错误 3:targetSdkVersion 低于 33 —— 若 build.gradle 中 targetSdkVersion 未设置到 33 或以上,即使声明了权限,系统也不会将其视为危险权限,用户将无法在设置中看到开关,应用也不会触发运行时授权流程。

3.5 性能与稳定性说明

静态权限声明本身对 APK 体积、启动时间、运行时性能无任何影响。它只是一个可被 PackageManager 解析的 XML 条目。唯一可能影响稳定性的场景是:忘记声明 会导致运行时 SecurityException,或 shouldShowRequestPermissionRationale() 返回 false 且无法弹出授权框。因此,在构建时加入 lint 检查规则可预先拦截遗漏:

android {
    lintOptions {
        check 'MissingPermission'
    }
}

3.6 章节核心流程示意

Android 13 通知权限适配流程中的声明环节 适配链条 设置 targetSdk = 33 声明 PERMISSION POST_NOTIFICATIONS 运行时请求 requestPermissions AndroidManifest.xml 内部结构 <manifest> <uses-permission android:name= "POST_NOTIFICATIONS"/> <application> ... 展开 关键:声明必须在 <manifest> 的直接子级,targetSdkVersion ≥ 33;缺少声明将导致运行时授权流程无法启动。

本图为本章(第 3 章)的核心内容——权限声明在整个适配流程中的位置,以及 AndroidManifest.xml 内部应如何组织标签。确保声明无误后,即可进入第 4 章的运行时授权实现。