当前位置: 首页 > news >正文

【Android】Notification 的基本使用

文章目录

  • 【Android】Notification的基本使用
    • 权限
    • 通知的基本使用
      • 1. 获取通知管理器(用于发送、更新、取消通知)
      • 2. 创建通知渠道(Android 8.0+ 必须)
      • 3. 使用通知
        • 3.1 发送通知
        • 3.2 更新通知
        • 3.3 取消通知
    • 通知的进阶技巧
      • 通知显示样式
        • 1. BigTextStyle — 显示大段文本(长消息)
        • 2. BigPictureStyle — 显示大图
        • 3. InboxStyle — 多条汇总(像邮件列表)
        • 3. InboxStyle — 多条汇总(像邮件列表)

【Android】Notification的基本使用

权限

Android 13(API 33)新增了POST_NOTIFICATIONS权限,这是一个危险权限,危险权限在 Android 6.0+ 必须运行时动态申请。

  1. 首先在AndroidManifest.xml中声明权限。
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
  1. 在尝试发送通知前,必须先检查并请求权限。
// Android 13(API 33+)需要动态申请通知权限
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}, REQUEST_CODE);} else {showNotification();}
} else {// Android 13 以下不需要权限,直接发通知showNotification();
}
  • ContextCompat.checkSelfPermission(...)——检查当前是否已经有权限

    • 返回值是PackageManager.PERMISSION_GRANTED,说明用户之前已经允许(或系统已授予)
    • 返回值是PackageManager.PERMISSION_DENIED,说明还没授权,需要发起申请
  • ActivityCompat.requestPermissions(...) —— 发起权限请求(触发系统对话框)

    • 作用:向系统请求权限。系统会(或不会)弹出系统权限对话框,用户选择「允许/拒绝」
    • 参数:
      • this:Activity(请求结果会回调到该 Activity 的 onRequestPermissionsResult
      • String[]:要请求的权限数组(这里只请求一个)
      • REQUEST_CODE:你自己定义的请求码,用于回调时区分是哪一次请求(常量,例:private static final int REQUEST_CODE = 1001;
    • 注意:如果用户之前勾选了“不再询问(Don’t ask again)”,调用 requestPermissions 可能不会弹对话框,而会直接在回调里返回 DENIED
  1. 重写 onRequestPermissionsResult(...)方法——处理用户的选择(回调)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == REQUEST_CODE) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 用户同意了通知权限,可以发通知showNotification();} else {// 用户拒绝了通知权限,无法发通知Toast.makeText(this, "没有通知权限", Toast.LENGTH_SHORT).show();}}
}

在Android 13(API 33)之前,通知不需要运行时申请权限(只要应用正常安装,系统默认允许通知)。

通知的基本使用

1. 获取通知管理器(用于发送、更新、取消通知)

  1. NotificationManager(系统服务类)

    // 从当前上下文(Context)获取系统服务
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// API 23+ 推荐(避免强转,更安全)
    NotificationManager notificationManager = getSystemService(NotificationManager.class);// 在 Fragment 里(没有直接的 getSystemService)
    NotificationManager notificationManager = requireContext().getSystemService(NotificationManager.class);
    

    缺点:不同 Android 版本的 API 差异较大。比如 Android 8.0 开始必须使用 通知渠道(NotificationChannel),而老版本没有,需要自己写兼容逻辑。

  2. NotificationManagerCompat(兼容类,来自 AndroidX 库)

    NotificationManagerCompat manager = NotificationManagerCompat.from(context);
    

    是对 NotificationManager 的一个 封装,主要作用是 屏蔽 Android 不同版本的差异

2. 创建通知渠道(Android 8.0+ 必须)

// Android 8.0(API 26+)开始需要创建通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {CharSequence name = "Channel Name";               String description = "Channel Description";int importance = NotificationManager.IMPORTANCE_HIGH;NotificationChannel channel = new NotificationChannel("my_channel_id", name, importance);channel.setDescription(description);notificationManager.createNotificationChannel(channel);
}
  1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { … }

    • Build.VERSION.SDK_INT 是当前设备的 API 等级(整数)。
    • Build.VERSION_CODES.O 是 Android 8.0(API 26)。
    • NotificationChannel 及通知渠道机制从 API 26 开始引入,所以这段代码只在 API ≥ 26 时执行,避免在旧设备上因类/方法不存在而崩溃。
  2. CharSequence name = "Channel Name";

    • 这是渠道的可见名称(会显示在系统的“应用通知设置 → 渠道”界面)。
    • 使用 CharSequence 而不是 String 是因为系统允许富文本/本地化。建议用字符串资源getString(R.string.xxx))以便本地化。
  3. String description = "Channel Description";

    • 渠道的描述,用户在系统设置里可以看到,说明这个渠道里的通知是什么用途,同样建议放入资源以支持多语言。
  4. int importance = NotificationManager.IMPORTANCE_DEFAULT;

    渠道的重要性(importance)决定通知的行为:是否有声音、是否在锁屏显示、是否会弹出(heads-up)等。常见取值(从低到高):

    • IMPORTANCE_NONE:不展示(等于关闭这个渠道)。
    • IMPORTANCE_MIN:最不显眼,只在通知面板很靠后的位置显示,不震动、不响声、不显示图标。
    • IMPORTANCE_LOW:不响、不震动,但会在状态栏有较低优先级展示。
    • IMPORTANCE_DEFAULT:有声音/震动(默认行为)。
    • IMPORTANCE_HIGH(或更高):会产生 Heads-up(弹出)提示,通常用于紧急或需即时注意的通知。
  5. NotificationChannel channel = new NotificationChannel("my_channel_id", name, importance);

    创建 NotificationChannel 对象。参数:

    • "my_channel_id"渠道 ID,是你在代码里标识该渠道的唯一字符串(在同一应用内应唯一)。
      • 这个 ID 后续发通知时要在 NotificationCompat.Builder 中使用:new NotificationCompat.Builder(context, "my_channel_id")
      • 一旦创建并发布给系统,渠道 ID 不可变(你不能重命名 ID)。若需不同设置应新建不同 ID。
    • name:用户可见的名称。
    • importance:重要性等级(如上)。
  6. channel.setDescription(description);

    • 给渠道设置描述(在系统设置里显示),帮助用户理解该渠道的用途。
  7. notificationManager.createNotificationChannel(channel);

    将渠道注册到系统(通过 NotificationManager)。注册后:

    • 系统会把该渠道显示在“应用通知设置”里,让用户可以单独开关或调整声音/振动/优先级等。
    • 如果相同 ID 的渠道已存在,系统不会随意覆盖用户已修改的设置(比如用户改变了重要性或声音),但应用可以通过再次调用 createNotificationChannel 更新可变字段(name、description 等)。重要性、声音等用户设置通常不会被覆盖。
    • 这方法是幂等的——多次调用不会导致重复创建(对于同 ID,系统只会保持一个渠道)。

可以在手机应用设置中找到:

3. 使用通知

3.1 发送通知
Notification notification = new NotificationCompat.Builder(this, "my_channel_id").setSmallIcon(R.drawable.ic_launcher_background)   // 小图标(必须有).setContentTitle("新消息提醒")              // 标题.setContentText("你有一条新的消息,请查收。") // 内容.setPriority(NotificationCompat.PRIORITY_HIGH) // 优先级(7.1以下).setCategory(NotificationCompat.CATEGORY_MESSAGE) // 通知类别.setWhen(System.currentTimeMillis())      // 时间戳.build();
notificationManager.notify(1, notification);

3.2 更新通知
Notification notification = new NotificationCompat.Builder(this, "my_channel_id").setSmallIcon(R.drawable.ic_qq).setContentTitle("通知已更新").setContentText("newContent").setPriority(NotificationCompat.PRIORITY_HIGH).setAutoCancel(true).build();notificationManager.notify(1, notification); // 同 id 会覆盖之前的

3.3 取消通知
notificationManager.cancel(1); // 取消指定 id 的通知

这里主要有两个方法:notify()cancel()

  1. notify —— 发送/更新通知

    重载与参数:

    • notify(int id, Notification n)
    • notify(@Nullable String tag, int id, Notification n)

    系统用 (tag, id) 作为唯一键:

    • 只传 id ⇒ 等价于 (null, id)
    • 同一 (tag, id) 再次调用会覆盖/更新已有通知(而不是再叠一条)。
    • 不同 id ⇒ 并列显示多条通知(常用于聊天多会话、下载多任务)。

    建议:id 用稳定且可复现的数(如会话ID哈希);需要“堆叠多条”时用不同 id。

    注意:

    1. 渠道(Android 8.0+):通知所属的 Channel 决定重要级别、声音、震动等;用户一旦改了渠道设置,你在代码里改 importance不会生效,除非创建新渠道 ID
    2. 权限(Android 13+):没有 POST_NOTIFICATIONS 权限时,notify 调用不会崩不会显示。可先用 NotificationManagerCompat.areNotificationsEnabled() 检测。
    3. 小图标必须有setSmallIcon(...) 缺失会导致通知不显示/崩溃(部分系统)。
    4. 更新 vs 新发:要“更新”同一条,用同一个 (tag,id);要“多条并列”,用不同 id 或不同 tag。
    5. 前台服务:前台服务的通知由 startForeground(id, notification) 管理。要更新用 notify(id, ...);要移除必须 stopForeground(true)不要直接 cancel(id) 试图偷撤)。
    6. ID 取值int 任意,但前台服务 id 需 > 0。不建议复用 0
    7. 主线程调用:可以在主线程调用,但构建通知时的重资源操作(如大图 decode)最好放到后台,避免卡顿。

    使用示例:

    // 覆盖更新同一条:固定 id
    notificationManager.notify(1001, build("下载中 30%"));
    notificationManager.notify(1001, build("下载中 60%"));// 多条并列:不同 id
    notificationManager.notify(2001, build("张三:你好"));
    notificationManager.notify(2002, build("李四:在吗"));// 使用 tag 区分业务线
    notificationManager.notify("chat-zhangsan", 1, build("张三:你好"));
    notificationManager.notify("chat-lisi",     1, build("李四:在吗"));
    
  2. cancel —— 取消/移除通知

    把已经显示(或排队)的某条通知移除。参数与 notify 一致,(tag, id) 必须匹配到同一条通知。

通知的进阶技巧

通知显示样式

Android 有一套“可扩展样式(expanded styles)”,可以让通知在下拉或通知抽屉中显示更多内容或图像。常用几种:

1. BigTextStyle — 显示大段文本(长消息)
setStyle(new NotificationCompat.BigTextStyle().bigText("这是很长的文字... \n\n\n\n可以完整显示多行内容"))

场景:长消息预览、日志摘要等。

2. BigPictureStyle — 显示大图
setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.datu)))

注意:如果同时设置了 BigPictureStyle 与 BigTextStyle,某些设备/系统版本会以图片样式为主(长文可能不会全部展开)。如果你既要图又要长文本,需设计展示优先级或把长文本放在点击后进入的详情页。

3. InboxStyle — 多条汇总(像邮件列表)
setStyle(new NotificationCompat.InboxStyle().addLine("第一条消息").addLine("第二条消息").setSummaryText("+2 条"))

设备/系统版本会以图片样式为主(长文可能不会全部展开)。如果你既要图又要长文本,需设计展示优先级或把长文本放在点击后进入的详情页。

[外链图片转存中…(img-7ViMmcqh-1756631003433)]

3. InboxStyle — 多条汇总(像邮件列表)
setStyle(new NotificationCompat.InboxStyle().addLine("第一条消息").addLine("第二条消息").setSummaryText("+2 条"))

http://www.xdnf.cn/news/1411255.html

相关文章:

  • [线上问题排查]深度剖析:一条MySQL慢查询的全面优化实战
  • Cesium 入门教程(十四):鼠标键盘交互
  • 设置Ubuntu 22.04 LTS上的rsync同步服务
  • 提取动漫图像轮廓并拟合为样条曲线(MATLAB)
  • WEB漏洞挖掘篇(一) 基本概念、十大常見WEB漏洞
  • Python训练营打卡Day49-神经网络调参指南
  • 赵玉平《刘备谋略》读书笔记(上部)
  • 如何通过 AI IDE 集成开发工具快速生成简易留言板系统
  • 链表OJ做题报告
  • 批量修改用户密码的命令chpasswd
  • 使用组合子构建抽象语法树
  • vsgCs显示谷歌全球倾斜模型-数据转换
  • 打工人日报#20250831
  • pyinstaller打包后失败问题记录
  • 贝叶斯分类(Bayes Classify)
  • Java面试-微服务(spring cloud篇)
  • 网络:相比于HTTP,HTTPS协议到底安全在哪?
  • 【HarmonyOS】天气预报 UI 的基本实现
  • 基于Echarts+HTML5可视化数据大屏展示-惠民服务平台
  • 一文理清TCP协议的通讯流程
  • 【车载开发系列】CAN与CANFD下篇
  • Linux-驱动积累
  • docker安装tomcat
  • 1.2 操作系统发展历程
  • dify docker compose操作命令指南
  • 【不懂就问】-手机相关学习
  • 内核等待队列以及用户态的类似机制
  • 基于Spring Cloud Sleuth与Zipkin的分布式链路追踪实战指南
  • 机器学习基础-day01-机器学习介绍
  • syn与quote的简单使用——实现debug