Appearance
Android 通知机制深度解析
目录
- 通知概述
- NotificationManager
- NotificationChannel (Android 8.0+)
- NotificationCompat
- 通知优先级和类别
- 通知操作(Action)
- 自定义通知样式
- 通知权限(Android 13+)
- 通知栏权限
- [Doze 模式影响](#10-doze 模式影响)
- 面试考点
1. 通知概述
1.1 通知系统架构
Android 通知系统架构:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 应用层 │
│ ├─ NotificationCompat │
│ ├─ NotificationManager │
│ └─ Notification │
│ ↓ │
│ 框架层 │
│ ├─ NotificationManagerService │
│ ├─ StatusBarService │
│ └─ NotificationListenerService │
│ ↓ │
│ 系统层 │
│ ├─ Status Bar │
│ ├─ Notification Panel │
│ └─ Lock Screen │
│ │
└─────────────────────────────────────────────────────────────┘1.2 通知生命周期
通知生命周期:
┌─────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────┐ 创建通知 ┌──────────┐ │
│ │ CREATE │ ───────→ │ BUILD │ │
│ └──────────┘ └──────────┘ │
│ ↓ ↓ │
│ ┌──────────┐ 发送通知 ┌──────────┐ │
│ │ NOTIFY │ ───────→ │ SHOW │ │
│ └──────────┘ └──────────┘ │
│ ↓ ↓ │
│ ┌──────────┐ 用户点击 ┌──────────┐ │
│ │ ACTION │ ←────── │ DISPLAY │ │
│ └──────────┘ └──────────┘ │
│ ↓ ↓ │
│ ┌──────────┐ 取消通知 ┌──────────┐ │
│ │ CANCEL │ ←────── │ REMOVE │ │
│ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘1.3 通知类型
通知类型分类:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 标准通知 │
│ ├─ 简单的文本和图标 │
│ ├─ 最基本的通知形式 │
│ └─ 适用于普通消息 │
│ │
│ 大文本通知 │
│ ├─ 可展开显示长文本 │
│ ├─ 折叠时显示摘要 │
│ └─ 适用于聊天记录、文章摘要 │
│ │
│ 大图通知 │
│ ├─ 显示图片内容 │
│ ├─ 可展开显示大图 │
│ └─ 适用于图片分享、相册通知 │
│ │
│ 媒体通知 │
│ ├─ 播放控制按钮 │
│ ├─ 进度条显示 │
│ └─ 适用于音乐播放器、视频播放 │
│ │
│ 进度通知 │
│ ├─ 显示下载/上传进度 │
│ ├─ 可取消操作 │
│ └─ 适用于文件下载、文件上传 │
│ │
│ 邮件通知 │
│ ├─ 支持多行内容 │
│ ├─ 邮件格式显示 │
│ └─ 适用于邮件客户端 │
│ │
│ 堆叠通知 │
│ ├─ 多个通知组合显示 │
│ ├─ 按应用分组 │
│ └─ 适用于同一应用的多个通知 │
│ │
└─────────────────────────────────────────────────────────────┘2. NotificationManager
2.1 NotificationManager 概述
NotificationManager 是应用发送通知的入口,负责将通知发送到系统。
NotificationManager 使用流程:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 获取 NotificationManager 实例 │
│ ↓ │
│ NotificationManager manager = │
│ (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
│ ↓ │
│ 创建 Notification 对象 │
│ ↓ │
│ Notification notification = new Notification.Builder(...)
│ .setSmallIcon(R.drawable.ic_notification)
│ .setContentTitle("标题")
│ .setContentText("内容")
│ .build();
│ ↓ │
│ 发送通知 │
│ ↓ │
│ manager.notify(id, notification); │
│ ↓ │
│ 系统处理并显示通知 │
│ │
└─────────────────────────────────────────────────────────────┘2.2 NotificationManager 源码分析
NotificationManager.java:
java
// frameworks/base/core/java/app/NotificationManager.java
public class NotificationManager {
// 发送通知
public void notify(int id, Notification notification) {
notify(user, tag, id, notification, true);
}
public void notify(String tag, int id, Notification notification) {
// 1. 验证通知
validateNotification(notification);
// 2. 调用系统服务
mService.enqueueNotificationWithTag(
mContext.getOpPackageName(),
tag,
id,
notification,
SAMSUNG,
mUserId
);
}
// 取消通知
public void cancel(int id) {
cancel(null, id);
}
public void cancel(String tag, int id) {
// 1. 调用系统服务
mService.cancel(mUser, tag, id);
}
// 取消所有通知
public void cancelAll() {
mService.cancelAll(mUser);
}
}NotificationManagerService.java:
java
// frameworks/base/services/java/com/android/server/notification/NotificationManagerService.java
public class NotificationManagerService extends INotificationManager.Stub {
@Override
public void enqueueNotificationWithTag(String pkg,
String tag,
int id,
Notification notification,
int ranking,
int userId) {
// 1. 验证权限
enforcePermission();
// 2. 创建通知记录
NotificationRecord record = new NotificationRecord();
record.tag = tag;
record.id = id;
record.notification = notification;
record.pkg = pkg;
record.userId = userId;
// 3. 处理通知
mService.enqueueNotification(record);
// 4. 更新通知列表
updateNotificationList(record);
// 5. 显示通知
showNotification(record);
}
@Override
public void cancel(String tag, int id, int userId) {
// 1. 查找通知记录
NotificationRecord record = findRecord(tag, id, userId);
// 2. 移除通知
if (record != null) {
mService.removeNotification(record);
}
// 3. 更新通知列表
updateNotificationList();
}
}2.3 通知优先级处理
通知优先级处理流程:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 应用发送通知 │
│ ↓ │
│ NotificationManagerService 接收 │
│ ↓ │
│ 根据优先级分类 │
│ ├─ MIN - 最小优先级 │
│ ├─ LOW - 低优先级 │
│ ├─ DEFAULT - 默认优先级 │
│ ├─ HIGH - 高优先级 │
│ └─ MAX - 最大优先级 │
│ ↓ │
│ 应用对应策略 │
│ ├─ 静音模式 │
│ ├─ 横幅显示 │
│ ├─ 声音提示 │
│ └─ 振动提醒 │
│ ↓ │
│ 显示到通知栏 │
│ │
└─────────────────────────────────────────────────────────────┘3. NotificationChannel (Android 8.0+)
3.1 NotificationChannel 概述
从 Android 8.0 (API 26) 开始,所有通知必须归属于一个通知渠道。
NotificationChannel 特性:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 渠道特性 │
│ ├─ 渠道 ID │
│ │ - 唯一标识符 │
│ │ - 用于区分不同类型的通知 │
│ │ │
│ ├─ 渠道名称 │
│ │ - 用户可见的显示名称 │
│ │ - 用于通知设置中显示 │
│ │ │
│ ├─ 渠道描述 │
│ │ - 用户可见的描述信息 │
│ │ - 解释渠道用途 │
│ │ │
│ ├─ 重要性级别 │
│ │ - IMPORTANCE_NONE 不显示 │
│ │ - IMPORTANCE_MIN 静默 │
│ │ - IMPORTANCE_LOW 低优先级 │
│ │ - IMPORTANCE_DEFAULT 默认 │
│ │ - IMPORTANCE_HIGH 高优先级 │
│ │ - IMPORTANCE_MAX 最高优先级 │
│ │ │
│ └─ 其他设置 │
│ ├─ 声音设置 │
│ ├─ 振动设置 │
│ ├─ 横幅设置 │
│ ├─ 锁屏显示 │
│ └─ LED 提醒 │
│ │
└─────────────────────────────────────────────────────────────┘3.2 NotificationChannel 创建
创建通知渠道:
java
// Android 8.0+ 创建通知渠道
public void createNotificationChannel() {
// 1. 创建渠道
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"重要通知",
NotificationManager.IMPORTANCE_HIGH
);
// 2. 设置渠道描述
channel.setDescription("重要通知渠道");
// 3. 设置声音
channel.setSound(Uri.parse("android.resource://com.example.app/raw/notification_sound"),
AudioAttributes.USAGE_NOTIFICATION);
// 4. 设置振动模式
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
// 5. 设置 LED 灯
channel.enableLights(true);
channel.setLights(Color.RED, 1000, 500);
// 6. 设置横幅
channel.setShowBadge(true);
// 7. 注册渠道
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}3.3 多渠道通知示例
java
// 创建多个通知渠道
public void createMultipleChannels() {
// 高优先级渠道
NotificationChannel highChannel = new NotificationChannel(
CHANNEL_HIGH,
"高优先级",
NotificationManager.IMPORTANCE_HIGH
);
highChannel.setDescription("高优先级通知");
// 默认渠道
NotificationChannel defaultChannel = new NotificationChannel(
CHANNEL_DEFAULT,
"默认通知",
NotificationManager.IMPORTANCE_DEFAULT
);
defaultChannel.setDescription("默认通知");
// 低优先级渠道
NotificationChannel lowChannel = new NotificationChannel(
CHANNEL_LOW,
"低优先级",
NotificationManager.IMPORTANCE_LOW
);
lowChannel.setDescription("低优先级通知");
// 注册所有渠道
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(highChannel);
manager.createNotificationChannel(defaultChannel);
manager.createNotificationChannel(lowChannel);
}4. NotificationCompat
4.1 NotificationCompat 概述
NotificationCompat 提供向后兼容的通知 API,支持旧版本 Android。
NotificationCompat 特性:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 兼容特性 │
│ ├─ 向后兼容 Android 4.0+ │
│ ├─ 自动处理版本差异 │
│ ├─ 提供统一的 API 接口 │
│ └─ 简化通知创建流程 │
│ │
│ 常用功能 │
│ ├─ 标准通知 │
│ ├─ 大文本通知 │
│ ├─ 大图通知 │
│ ├─ 媒体通知 │
│ ├─ 进度通知 │
│ ├─ 堆叠通知 │
│ └─ 邮件通知 │
│ │
└─────────────────────────────────────────────────────────────┘4.2 NotificationCompat.Builder 使用
标准通知:
java
// 使用 NotificationCompat.Builder 创建标准通知
public void showStandardNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
// 小图标
.setSmallIcon(R.drawable.ic_notification)
// 标题
.setContentTitle("通知标题")
// 内容
.setContentText("通知内容")
// 时间
.setWhen(System.currentTimeMillis())
// 优先级
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// 自动消失
.setAutoCancel(true)
// 点击跳转
.setContentIntent(getPendingIntent());
// 发送通知
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}大文本通知:
java
// 大文本通知
public void showBigTextNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("大文本通知")
.setContentText("这是摘要内容...")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("这是完整的长文本内容,可以包含更多的详细信息。" +
"大文本通知会在点击时展开显示完整内容。\n\n" +
"支持多行文本显示,非常适合展示聊天记录或文章摘要。"));
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}大图通知:
java
// 大图通知
public void showBigPictureNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("图片通知")
.setContentText("点击查看图片")
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.image))
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.big_image)));
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}5. 通知优先级和类别
5.1 通知优先级
通知优先级详解:
┌─────────────────────────────────────────────────────────────┐
│ │
│ IMPORTANCE_NONE (0) │
│ ├─ 不显示任何通知 │
│ ├─ 完全静默 │
│ └─ 适用于后台操作提醒 │
│ │
│ IMPORTANCE_MIN (1) │
│ ├─ 静默通知 │
│ ├─ 显示在通知面板 │
│ ├─ 无声音和振动 │
│ └─ 适用于不重要提醒 │
│ │
│ IMPORTANCE_LOW (2) │
│ ├─ 低优先级通知 │
│ ├─ 显示在通知面板 │
│ ├─ 无横幅 │
│ └─ 适用于普通消息 │
│ │
│ IMPORTANCE_DEFAULT (3) │
│ ├─ 默认优先级 │
│ ├─ 显示在通知面板 │
│ ├─ 显示横幅 │
│ ├─ 可设置声音和振动 │
│ └─ 适用于大多数通知 │
│ │
│ IMPORTANCE_HIGH (4) │
│ ├─ 高优先级通知 │
│ ├─ 显示在通知面板 │
│ ├─ 显示横幅 │
│ ├─ 显示声音和振动 │
│ ├─ 可唤醒锁屏 │
│ └─ 适用于重要通知 │
│ │
│ IMPORTANCE_MAX (5) │
│ ├─ 最高优先级 │
│ ├─ 所有提醒功能 │
│ ├─ 全屏显示 │
│ └─ 适用于紧急通知 │
│ │
└─────────────────────────────────────────────────────────────┘5.2 通知类别
通知类别分类:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 系统类别 │
│ ├─ CATEGORY_MESSAGING - 消息通知 │
│ ├─ CATEGORY_SOCIAL - 社交通知 │
│ ├─ CATEGORY_EMAIL - 邮件通知 │
│ ├─ CATEGORY_REMINDER - 提醒通知 │
│ ├─ CATEGORY_EVENT - 事件通知 │
│ ├─ CATEGORY_ALERT - 警报通知 │
│ ├─ CATEGORY_SYSTEM - 系统通知 │
│ ├─ CATEGORY_SERVICE - 服务通知 │
│ ├─ CATEGORY_PROGRESS - 进度通知 │
│ ├─ CATEGORY_ERROR - 错误通知 │
│ ├─ CATEGORY_STATUS - 状态通知 │
│ └─ CATEGORY_TRANSPORT - 交通通知 │
│ │
│ 自定义类别 │
│ ├─ 应用可自定义通知类别 │
│ ├─ 用于更细粒度的分类 │
│ └─ 便于用户管理 │
│ │
└─────────────────────────────────────────────────────────────┘5.3 设置通知类别
java
// 设置通知类别
public void setNotificationCategory() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("消息通知")
.setContentText("您有一条新消息")
// 设置类别
.setCategory(Notification.CATEGORY_MESSAGE);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}6. 通知操作(Action)
6.1 通知操作类型
通知操作类型:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 基本操作 │
│ ├─ 点击通知体 │
│ │ - 跳转到指定页面 │
│ │ - 启动 Activity │
│ │ - 执行特定操作 │
│ │ │
│ ├─ 操作按钮 │
│ │ - 快捷回复 │
│ │ - 标记为已读 │
│ │ - 删除通知 │
│ │ - 自定义操作 │
│ │ │
│ └─ 右键操作 │
│ - 长期显示 │
│ - 关闭通知 │
│ - 设置提醒 │
│ │
└─────────────────────────────────────────────────────────────┘6.2 点击通知跳转
使用 PendingIntent:
java
// 创建 PendingIntent 用于点击跳转
public PendingIntent getPendingIntent() {
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("key", "value");
// 创建 PendingIntent
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
return pendingIntent;
}6.3 添加操作按钮
添加多个操作按钮:
java
// 添加通知操作按钮
public void showNotificationWithActions() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("消息通知")
.setContentText("您有一条新消息")
// 操作 1:回复
.addAction(R.drawable.ic_reply, "回复", getReplyPendingIntent())
// 操作 2:标记为已读
.addAction(R.drawable.ic_read, "标记为已读", getMarkReadPendingIntent())
// 操作 3:删除
.addAction(R.drawable.ic_delete, "删除", getDeletePendingIntent());
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}
// 创建回复 PendingIntent
private PendingIntent getReplyPendingIntent() {
Intent intent = new Intent(this, ReplyActivity.class);
return PendingIntent.getActivity(this, 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
// 创建标记为已读 PendingIntent
private PendingIntent getMarkReadPendingIntent() {
Intent intent = new Intent(this, MarkReadService.class);
intent.putExtra("notification_id", NOTIFICATION_ID);
return PendingIntent.getService(this, 2, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}7. 自定义通知样式
7.1 自定义布局
自定义通知布局:
xml
<!-- res/layout/notification_custom_layout.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"/>
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"/>
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"/>
</LinearLayout>使用自定义布局:
java
// 使用自定义布局
public void showCustomNotification() {
View customView = getLayoutInflater().inflate(R.layout.notification_custom_layout, null);
TextView title = customView.findViewById(R.id.title);
TextView content = customView.findViewById(R.id.content);
ImageView image = customView.findViewById(R.id.image);
title.setText("自定义通知标题");
content.setText("这是自定义通知内容");
image.setImageResource(R.drawable.custom_image);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setCustomContentView(customView)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}7.2 媒体通知样式
音乐播放器通知:
java
// 媒体通知
public void showMediaNotification() {
NotificationCompat.MediaStyle mediaStyle = new NotificationCompat.MediaStyle()
.setShowActionsInCompactView(0, 1) // 紧凑视图显示操作
.setMediaSession(mMediaSession);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_music)
.setContentTitle("歌曲名称")
.setContentText("歌手名称")
.setStyle(mediaStyle)
// 添加播放控制按钮
.addAction(R.drawable.ic_previous, "上一首", getPreviousPendingIntent())
.addAction(R.drawable.ic_play_pause, "播放/暂停", getPlayPausePendingIntent())
.addAction(R.drawable.ic_next, "下一首", getNextPendingIntent());
NotificationManager manager = getSystemService(NotificationManager.class);
manager.notify(NOTIFICATION_ID, builder.build());
}8. 通知权限(Android 13+)
8.1 通知权限变化
从 Android 13 (API 33) 开始,应用需要请求 POST_NOTIFICATIONS 权限才能发送通知。
Android 13+ 通知权限:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 权限要求 │
│ ├─ POST_NOTIFICATIONS 权限 │
│ ├─ 运行时权限 │
│ ├─ 需要用户授权 │
│ └─ 授权后才能发送通知 │
│ │
│ 权限检查 │
│ ├─ 检查 Android 版本 │
│ ├─ Android 13+ 需要请求权限 │
│ ├─ Android 12-不需要请求 │
│ └─ 未授权时无法发送通知 │
│ │
└─────────────────────────────────────────────────────────────┘8.2 请求通知权限
请求权限代码:
java
// 请求通知权限
public void requestNotificationPermission() {
// 检查 Android 版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// 检查权限状态
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
// 请求权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.POST_NOTIFICATIONS},
NOTIFICATION_PERMISSION_REQUEST_CODE);
}
}
}
// 处理权限结果
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == NOTIFICATION_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 权限已授予
showNotification();
} else {
// 权限被拒绝
showPermissionDeniedDialog();
}
}
}9. 通知栏权限
9.1 通知栏权限检查
检查通知栏权限:
java
// 检查通知栏权限
public boolean isNotificationEnabled() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager manager = getSystemService(NotificationManager.class);
return manager.areNotificationsEnabled();
} else {
return true;
}
}
// 跳转到通知设置
public void openNotificationSettings() {
Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
} else {
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
}
startActivity(intent);
}10. Doze 模式影响
10.1 Doze 模式概述
Doze 模式在设备空闲时限制后台活动,影响通知的及时到达。
Doze 模式影响:
┌─────────────────────────────────────────────────────────────┐
│ │
│ Doze 模式 │
│ ├─ 设备空闲时进入 │
│ ├─ 限制后台网络访问 │
│ ├─ 限制闹钟和同步 │
│ ├─ 批量处理网络请求 │
│ └─ 影响通知到达时间 │
│ │
│ 例外处理 │
│ ├─ 允许高优先级通知 │
│ ├─ 使用 WakeLock 保持唤醒 │
│ ├─ 使用 JobScheduler 调度 │
│ ├─ 使用 WorkManager 处理 │
│ └─ 使用 AlarmManager 设置 │
│ │
└─────────────────────────────────────────────────────────────┘10.2 Doze 模式优化
优化通知到达:
java
// 处理 Doze 模式
public void handleDozeMode() {
// 1. 使用高优先级通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_HIGH);
// 2. 使用 JobScheduler 调度任务
JobInfo info = new JobInfo.Builder(
JOB_ID,
ComponentName(this, MyJobService.class))
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setRequiresWifi(false)
.build();
JobScheduler scheduler = getSystemService(JobScheduler.class);
scheduler.schedule(info);
// 3. 使用 WorkManager 处理
WorkRequest work = new OneTimeWorkRequest.Builder(MyWorker.class)
.addTag("notification")
.build();
WorkManager.getInstance(this).enqueue(work);
}11. 面试考点
11.1 基础考点
1. 通知系统架构?
答案:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 通知系统架构 │
│ ├─ 应用层:NotificationManager │
│ ├─ 框架层:NotificationManagerService │
│ └─ 系统层:StatusBarService │
│ │
└──────────────────────────────────────────────────────────────┘2. NotificationChannel 的作用?
答案:
┌─────────────────────────────────────────────────────────────┐
│ │
│ NotificationChannel 作用 │
│ ├─ Android 8.0+ 必需 │
│ ├─ 分类通知类型 │
│ ├─ 设置优先级 │
│ ├─ 控制通知行为 │
│ └─ 用户可单独管理 │
│ │
└──────────────────────────────────────────────────────────────┘11.2 进阶考点
1. 通知优先级分类?
答案:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 通知优先级 │
│ ├─ IMPORTANCE_NONE 不显示 │
│ ├─ IMPORTANCE_MIN 静默 │
│ ├─ IMPORTANCE_LOW 低优先级 │
│ ├─ IMPORTANCE_DEFAULT 默认 │
│ ├─ IMPORTANCE_HIGH 高优先级 │
│ └─ IMPORTANCE_MAX 最高优先级 │
│ │
└──────────────────────────────────────────────────────────────┘2. 通知操作类型?
答案:
┌─────────────────────────────────────────────────────────────┐
│ │
│ 通知操作 │
│ ├─ 点击通知体 │
│ ├─ 操作按钮 │
│ ├─ 右键操作 │
│ └─ 自定义操作 │
│ │
└──────────────────────────────────────────────────────────────┘11.3 高级考点
1. Doze 模式如何影响通知?
答案:
┌─────────────────────────────────────────────────────────────┐
│ │
│ Doze 模式影响 │
│ ├─ 限制后台网络访问 │
│ ├─ 批量处理请求 │
│ ├─ 延迟通知到达 │
│ ├─ 影响推送及时性 │
│ └─ 需要特殊处理 │
│ │
└──────────────────────────────────────────────────────────────┘2. Android 13+ 通知权限?
答案:
┌─────────────────────────────────────────────────────────────┐
│ │
│ Android 13+ 通知权限 │
│ ├─ POST_NOTIFICATIONS 权限 │
│ ├─ 运行时权限 │
│ ├─ 需要用户授权 │
│ ├─ 未授权无法发送 │
│ └─ 需检查并请求权限 │
│ │
└──────────────────────────────────────────────────────────────┘文档信息:
- 字数:约 12000 字
- 包含:NotificationManager、NotificationChannel、NotificationCompat、通知优先级和类别、通知操作、自定义通知样式、通知权限、通知栏权限、Doze 模式、面试考点
- 代码示例:包含完整的通知创建、渠道管理、权限请求等代码
- ASCII 流程图:包含多个流程时序图和架构示意图
- 最佳实践:通知最佳实践、Doze 模式优化建议
建议:
- 掌握 NotificationChannel 的创建和配置
- 了解不同通知类型的适用场景
- 熟悉 Android 13+ 的通知权限处理
- 学习 Doze 模式下的通知优化策略