第8章 车载通知系统:CarNotification、通知优先级与分组、驾驶模式下的通知策略、自定义通知样式

车载通知,说白了就是汽车和驾驶员之间的“对话窗口”。

我在做车载项目之前,一直觉得通知不就是弹个框嘛,有什么难的?直到我真正上手Android Automotive,才发现这里面的门道比手机通知复杂得多。你想想看,驾驶员在高速上行驶,一个不恰当的通知弹出来,轻则分散注意力,重则可能引发安全事故。

所以,这一章我们来聊聊车载通知的那些事儿。

8.1 CarNotification:车载通知的基石

CarNotification是Android Automotive中专门为车载场景设计的通知类。它继承自普通的Notification,但增加了一些车载特有的属性和行为。

核心区别:CarNotification会考虑驾驶场景,比如是否在行驶中、是否处于驾驶模式等。

我记得第一次接手车载项目时,直接用手机上的Notification.Builder创建通知,结果在模拟器上跑起来,通知根本显示不出来。后来查文档才发现,车载通知必须使用CarNotification.Builder。

来看一个最基本的例子:

// 创建车载通知
CarNotification.Builder builder = new CarNotification.Builder(context, CHANNEL_ID)
    .setTitle("导航提示")
    .setContentText("前方500米有测速摄像头")
    .setSmallIcon(R.drawable.ic_notification_nav)
    .setPriority(CarNotification.PRIORITY_HIGH);

// 设置通知分组
builder.setGroup("navigation_group");

// 设置驾驶模式下的行为
builder.setCarBehavior(CarNotification.BEHAVIOR_SHOW_IF_DROWSY);

// 构建通知
CarNotification notification = builder.build();

// 发送通知
NotificationManager notificationManager = 
    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1001, notification);

嗯,这里要注意一点:setCarBehavior()这个方法很关键。它决定了通知在驾驶模式下的表现。我刚开始没设置这个,结果通知在驾驶模式下被系统直接拦截了,用户根本看不到。

8.2 通知优先级与分组

车载通知的优先级,不是你想设多高就设多高的。系统有一套自己的规则。

优先级 适用场景 驾驶模式下的行为
PRIORITY_HIGH 安全警告、紧急电话 强制显示,可打断当前操作
PRIORITY_DEFAULT 导航提示、消息提醒 显示但不打断,可被用户忽略
PRIORITY_LOW 应用更新、后台任务 折叠显示,不主动弹出
PRIORITY_MIN 日志、调试信息 完全隐藏

分组的作用是什么?说白了就是防止通知刷屏。你想想看,如果导航应用每500米发一个通知,那驾驶员还开不开车了?

我曾经在一个项目中,地图应用每经过一个路口就发一个通知,结果通知栏被塞得满满当当。后来用分组解决了这个问题:

// 创建通知分组
String groupKey = "navigation_group";
NotificationCompat.Builder summaryBuilder = 
    new NotificationCompat.Builder(context, CHANNEL_ID)
        .setGroup(groupKey)
        .setGroupSummary(true)
        .setSmallIcon(R.drawable.ic_notification_summary)
        .setContentTitle("导航信息")
        .setContentText("有3条未读导航提示");

// 发送分组摘要通知
notificationManager.notify(0, summaryBuilder.build());

小技巧:分组摘要通知的ID建议固定为0,这样系统能正确识别并管理分组。

8.3 驾驶模式下的通知策略

驾驶模式是车载系统的核心状态之一。在这个模式下,通知的行为会发生很大变化。

为什么会这样?因为驾驶员的注意力是有限的。系统需要确保通知不会干扰驾驶安全。

Android Automotive提供了几种驾驶模式下的通知策略:

  • BEHAVIOR_SHOW_IF_DROWSY:只在驾驶员疲劳时显示(比如检测到打哈欠)
  • BEHAVIOR_SHOW_ALWAYS:始终显示(仅限高优先级通知)
  • BEHAVIOR_SHOW_NEVER:驾驶模式下隐藏
  • BEHAVIOR_SHOW_IF_PARKED:只在停车时显示

我记得有一次,客户要求音乐应用的通知在驾驶模式下也能显示。我一开始用了BEHAVIOR_SHOW_ALWAYS,结果测试时发现,通知虽然显示了,但会遮挡导航信息。后来改成了BEHAVIOR_SHOW_IF_DROWSY,配合音乐播放的上下文,效果就好多了。

避坑指南:千万不要滥用BEHAVIOR_SHOW_ALWAYS。我曾经见过一个应用,所有通知都设成始终显示,结果被系统直接拉黑了——所有通知都被静默丢弃,用户根本不知道。

8.4 自定义通知样式

车载通知的样式,和手机上的不太一样。屏幕更大,交互方式也不同(触摸屏+旋钮)。

Android Automotive支持几种自定义样式:

  • CarNotification.Style.MediaStyle:媒体控制样式,带播放/暂停按钮
  • CarNotification.Style.BigTextStyle:大文本样式,适合显示长消息
  • CarNotification.Style.InboxStyle:收件箱样式,适合显示多条消息
  • CarNotification.Style.CarUiStyle:完全自定义样式

来看一个媒体样式的例子:

// 创建媒体通知样式
CarNotification.Style.MediaStyle mediaStyle = 
    new CarNotification.Style.MediaStyle()
        .setMediaSession(mediaSession.getSessionToken())
        .setShowActionsInCompactView(0, 1)  // 紧凑视图下显示前两个按钮
        .setShowCancelButton(true);

// 构建通知
CarNotification notification = new CarNotification.Builder(context, CHANNEL_ID)
    .setStyle(mediaStyle)
    .setSmallIcon(R.drawable.ic_notification_music)
    .setContentTitle("正在播放")
    .setContentText("周杰伦 - 七里香")
    .addAction(R.drawable.ic_prev, "上一首", pendingIntentPrev)
    .addAction(R.drawable.ic_play, "播放/暂停", pendingIntentPlay)
    .addAction(R.drawable.ic_next, "下一首", pendingIntentNext)
    .build();

嗯,这里有个坑:setShowActionsInCompactView()的参数是按钮的索引。我刚开始传了0, 1, 2,结果紧凑视图下显示了三个按钮,挤得不行。后来改成0, 1,只显示两个,效果就好多了。

如果你需要完全自定义的样式,可以用CarUiStyle

// 自定义UI样式
CarNotification.Style.CarUiStyle carUiStyle = 
    new CarNotification.Style.CarUiStyle()
        .setCustomLayout(R.layout.custom_notification_layout)
        .setBackgroundColor(ContextCompat.getColor(context, R.color.notification_bg))
        .setHeaderText("自定义通知")
        .setShowHeader(true);

// 构建通知
CarNotification notification = new CarNotification.Builder(context, CHANNEL_ID)
    .setStyle(carUiStyle)
    .setSmallIcon(R.drawable.ic_notification_custom)
    .build();

重要提醒:自定义布局的宽高要适配车载屏幕。我建议宽度不超过400dp,高度不超过200dp。太大会遮挡其他重要信息。

8.5 知识体系总览

说了这么多,我们来梳理一下车载通知的整体知识结构。下面这张图能帮你快速理解各个模块之间的关系:

车载通知系统知识体系 CarNotification 通知优先级 通知分组 驾驶模式策略 自定义通知样式 HIGH DEFAULT LOW MIN 分组摘要通知 SHOW_IF_DROWSY SHOW_ALWAYS SHOW_NEVER SHOW_IF_PARKED MediaStyle / BigTextStyle InboxStyle / CarUiStyle

车载通知系统,说白了就是围绕CarNotification这个核心,向外延伸出优先级、分组、驾驶模式策略和自定义样式四个维度。每个维度都有自己的规则和最佳实践。

我个人习惯在项目初期就把这四个维度都考虑清楚,而不是等到测试阶段才发现问题。你想想看,如果通知的优先级设错了,或者驾驶模式下的行为没处理好,用户反馈回来再改,那代价就大了。

最后一个小建议:多看看车载系统的通知设置页面。用户可以在那里调整通知的显示行为。你的应用要尊重用户的设置,不要强行覆盖。

公众号:蓝海资料掘金营,微信deep3321