通知是Android应用与用户保持连接的重要手段,但Google从Android 13开始对通知能力动了大刀:应用必须先获得用户授权才能发送通知。如果你的项目targetSdkVersion已经升到33以上,却仍然按照老方式直接调用notify方法,很可能会发现通知根本不显示,而且没有任何报错。这篇文章把Android 12、13、14三个版本中与通知权限相关的变化串起来讲清楚,并给出可以直接落地的适配代码。

Android 12到14各版本通知行为有哪些变化
Android 12本身还没有引入通知运行时权限,但它做了一些前置调整,比如强制要求通知必须挂载到NotificationChannel上,废弃了部分自定义通知视图的行为,同时引入了通知截断(trampoline)限制,也就是说应用不能通过Service或BroadcastReceiver中转跳转,必须从通知直接跳转到Activity。这些变化虽然没有直接涉及权限,但会影响到后面版本的适配思路。
真正的分水岭在Android 13(API 33)。系统新增了POST_NOTIFICATIONS运行时权限,属于dangerous级别。对于新安装的应用,如果targetSdkVersion达到33,系统默认不授予该权限,应用调用notify后通知会被静默丢弃,日志中只有一行不起眼的提示。而对于升级安装的应用,系统会在首次进入通知渠道设置前临时保留授权状态,给开发者一个过渡窗口。
Android 14(API 34)进一步收紧了体验层面的控制,比如默认关闭了前台服务的通知展示折叠策略调整,并且对FULL_SCREEN_INTENT通知增加了使用场景限制,只有来电和闹钟类应用才能默认使用。理解这些版本差异,是制定适配方案的前提,否则很容易出现只在部分机型上通知丢失的问题。
如何申请POST_NOTIFICATIONS权限并创建通知渠道
适配的第一步是在AndroidManifest.xml中声明权限,然后通过Activity的权限申请流程向用户弹窗。需要注意权限弹窗一天最多出现一次,用户拒绝两次后再申请不会再弹窗,只能引导用户去系统设置手动开启。
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
接下来是完整的申请逻辑,建议封装成工具方法,在主界面可见时判断并申请:
public class NotificationHelper {
private static final int REQ_CODE = 1001;
public static void requestNotificationPermission(Activity activity) {
if (Build.VERSION.SDK_INT >= 33) {
if (ContextCompat.checkSelfPermission(activity,
Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQ_CODE);
}
}
}
public static boolean areNotificationsEnabled(Context context) {
NotificationManagerCompat nm = NotificationManagerCompat.from(context);
return nm.areNotificationsEnabled();
}
}权限拿到之后还要确保通知渠道存在,Android 8.0以后没有渠道的通知无法展示。渠道的importance要合理设置,如果用户手动把渠道调成了低优先级,代码里再怎么设置也不会生效。创建渠道的代码如下:
private void createChannel(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"main_channel",
"重要消息",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("接收订单和系统提醒");
NotificationManager manager = context.getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}发送通知前做一次双重校验是推荐的做法:既检查areNotificationsEnabled的总开关,也检查具体渠道的开关状态,两者任一关闭都会导致通知不可见。很多团队只查总开关,结果用户在设置里单独关掉某个渠道时问题就出现了。
权限被拒绝后的降级策略与引导方案
当权限被永久拒绝时,继续弹窗已经没有意义,正确做法是在业务界面提供醒目的入口,引导用户跳转系统设置页开启。跳转代码很简单,但要注意用FLAG_ACTIVITY_NEW_TASK避免栈结构问题:
private void jumpToNotificationSetting(Context context) {
Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= 26) {
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
} else {
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}对于通知能力被关闭时的消息触达,可以考虑降级方案。比如即时通讯类应用可以在应用内横幅展示消息,电商类应用可以在用户打开App时提示补看未读通知。还可以通过判断shouldShowRequestPermissionRationale的返回值,决定是展示解释弹窗还是直接引导去设置页,这种分层处理能明显提升权限授予率。
最后提醒一点,Android 14对前台服务类型做了强校验,如果应用使用前台服务展示常驻通知,必须在Manifest中声明对应的foregroundServiceType,否则在部分场景会抛出异常。通知权限适配不是孤立的点,它和前台服务、渠道管理、跳转限制是一套组合拳,建议在适配时统一梳理一遍,避免反复踩坑。
Android通知权限POST_NOTIFICATIONS权限通知权限适配修改时间:2026-09-13 23:36:47