本文最后更新于:1 个月前
通知是指 Android 在应用的界面之外显示的消息,旨在向用户提供提醒、来自他人的通信信息或应用中的其他实时信息。
通知刨析
setSmallIcon()
- 应用名称
- 时间戳:由系统提供,但可以通过
setWhen()
将其替换掉或者通过setShowWhen(false)
将其隐藏。 setLargeIcon()
setContentTitle()
setContentText()
创建通知
添加支持库
implementation "com.android.support:support-compat:28.0.0"
创建基本通知
设置通知内容
- 见上通知刨析
setPriority()
设置通知优先级。优先级确定通知在 Android 7.1 和更低版本上的干扰程度。
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle(textTitle)
.setContentText(textContent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
创建渠道并设置重要性
向 createNotificationChannel()
传递 NotificationChannel
的实例在系统中注册应用的通知渠道。
private fun createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = getString(R.string.channel_name)
val descriptionText = getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationManager: NotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
设置通知的点按操作
指定通过 PendingIntent
对象定义的内容 Intent,并将其传递给 setContentIntent()
。
// Create an explicit intent for an Activity in your app
val intent = Intent(this, AlertDetails::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true) // 点按通知后自动移除通知
setFlags()
方法可帮助保留用户在通过通知打开应用后的预期导航体验。
- 专用于响应通知的 Activity。启动一个新任务,而不是添加到应用的现有任务和返回堆栈。
- 应用的常规应用流程中存在的 Activity。启动 Activity 时应创建返回堆栈,以便保留用户对返回和向上按钮的预期。
显示通知
NotificationManagerCompat.notify()
方法参数为:通知 ID 和 NotificationCompat.Builder.build()
。
创建折叠式通知
- 创建视图布局
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_name);
notification.bigContentView = remoteViews;
ornotification.contentView = remoteViews;
添加操作按钮
将 addAction()
传递给 PendingIntent
方法。
val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
action = ACTION_SNOOZE
putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_snooze, getString(R.string.snooze),
snoozePendingIntent)
添加直接回复操作
添加进度条
如果可以估算操作在任何时间点的完成进度,可以通过调用 setProgress(mamx, progress, false)
。移除进度条 setProgress(0, 0, false)
。
如果需要显示不确定性进度条,可以调用 setProgress(0, 0, true)
。移除进度条同样使用 setProgress(0, 0, false)
。
设置系统范围的类别
setCategory()
CATEGORY_ALARM
、CATEGORY_REMINDER
、CATEGORY_EVENT
、CATEGORY_CALL
显示紧急信息
如果应用的目标平台是 Android 10(API29)或更高版本,必须在应用清单文件中请求 USE_FULL_SCREEN_INTENT
权限,以便系统启动与时效性通知关联的全屏 Activity。
val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)
var builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setFullScreenIntent(fullScreenPendingIntent, true)
设置锁定屏幕的公开范围
setVisibility()
VISIBILITY_PUBLIC
显示通知的完整内容。VISIBILITY_SECRET
不在锁定屏幕上显示该通知的任何部分。VISIBILITY_PRIVATE
显示基本信息,但隐藏通知的完整内容。当设置为此级别时,可以通过setPublicVersion()
方法提供通知内容的备用版本。
更新和移除通知
NotificationManagerCompat.notify()
更新通知,传入参数为之前使用的具有同一 ID 的通知,如果之前的通知已被关闭,系统会创建一个新通知。调用setOnlyAlertOnce()
方法会使得通知只在首次出现时打断用户。cancel(ID)
、cancelAll()
、setTimeoutAfter()
创建展开式通知
NotificationCompat.BigPictureStyle
添加大图片,如需使该图片仅在通知收起时显示为缩略图,调用setLargeIcon()
并向其传递图片,同时调用BigPictureStyle.bigLargeIcon(null)
,这样大图标就会在通知展开时消失。NotificationCompat.BigTextStyle
添加一大段文本NotificationCOmpat.InboxStyle
创建收件箱样式的通知。如需添加新行,最多可调用addLine()
6 次,若超过 6 次,仅显示前 6 行。var notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.new_mail) .setContentTitle("5 New mails from " + sender.toString()) .setContentText(subject) .setLargeIcon(aBitmap) .setStyle(NotificationCompat.InboxStyle() .addLine(messageSnippet1) .addLine(messageSnippet2)) .build()
从通知启动 Activity
设置常规 Activity PendingIntent
使用 TaskStackBuilder
设置 PendingIntent
。
定义应用的 Activity 层次结构
通过应用清单文件为每个<activity>
元素添加android:parentActivityName
属性来定义 Activity 的自然层次结构。构建包含返回堆栈的 PendingIntent
创建TaskStackBuilder
的实例并调用addNextIntentWithParentStack()
,向其传递需要启动的 Activity 的Intent
。只要为每个 Activity 定义了父 Activity,就可以调用getPendingIntent()
来接收包含整个返回堆栈的PendingIntent
。// Create an Intent for the activity you want to start val resultIntent = Intent(this, ResultActivity::class.java) // Create the TaskStackBuilder val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run { // Add the intent, which inflates the back stack addNextIntentWithParentStack(resultIntent) // Get the PendingIntent containing the entire back stack getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) }
设置特殊 Activity PendingIntent
在清单中将以下属性添加到
<activity>
元素。android:taskAffinity=""
结合FLAG_ACTIVITY_NEW_TASK
标记使用,将此属性设置为空,可确保这类 Activity 不会进入应用的默认任务。android:excludeFromRecents="true"
用于从“最近”中排除新任务,以免用户意外返回它。
构建并发出通知
a. 创建可启动Activity
的Intent
。
b. 通过使用FLAG_ACTIVITY_NEW_TASK
和FLAG_ACTIVITY_CLEAR_TASK
标记调用setFlags()
,将Activity
设置为在新的空任务中启动。
c. 通过调用getActivity()
创建PendingIntent
val notifyIntent = Intent(this, ResultActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val notifyPendingIntent = PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT )
将
PendingIntent
传递到通知中。val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(notifyPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
创建一组通知
- 调用
setGroup()
方法,传入参数为一个唯一标识符字符串。 setSortKey()
更改通知顺序,默认根据发布时间排序setGroupAlertBehavior()
通知组的提醒应由其他通知处理。如果只希望通知组摘要发出提醒,那么通知组中的所有子级都应具有通知组提醒行为GROUP_ALERT_SUMMARY
。其他选项包括GROUP_ALERT_ALL
和GROUP_ALERT_CHILDREN
。setGroupSummary(true)
设置通知组摘要。
创建和管理通知渠道
从 Android 8.0(API 级别 26)开始,所有通知都必须分配到相应的渠道。
创建通知渠道
- 构建一个具有唯一渠道 ID、用户可见名称和重要性级别的
NotificationChannel
对象。 - (可选)使用
setDescription()
指定用户在系统设置中看到的说明。 - 注册通知渠道,方法是将该渠道传递给
createNotificationChannel()
。
设置重要性级别
渠道重要性会影响在渠道中发布的所有通知的干扰级别,包括从 IMPORTANCE_NONE(0)
到 IMPORTANCE_HIGH(4)
5 个重要性级别。
读取通知渠道设置
- 通过调用
getNotificationChannel()
或getNotificationChannels()
来获取NotificationChannel
对象。 - 查询特定的渠道设置,例如
getVibrationPattern()
、getSound()
和getImportance()
。
打开通知渠道设置
创建通知渠道后,无法以编程方式更改通知渠道的视觉和听觉行为,只有用户可以通过系统设置更改渠道行为。为了让用户轻松访问这些通知设置,应在应用的设置界面中添加一个用于打开这些系统设置的项。
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId())
}
startActivity(intent)
删除通知渠道
可以通过调用 deleteNotificationChannel()
删除通知渠道。
创建通知渠道分组
创建新渠道分组
// The id of the group.
val groupId = "my_group_01"
// The user-visible name of the group.
val groupName = getString(R.string.group_name)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannelGroup(NotificationChannelGroup(groupId, groupName))
创建分组后,可以调用 setGroup()
将 NotificationChannel
对象与该分组相关联。
修改通知标志
创建自定义通知
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!