type
status
date
slug
summary
tags
category
icon
password
由于不同版本API兼容性问题,我们通常使用NotificationCompact去创建通知.

注册NotificationChannel

一般在应用启动的时候注册通知channel:
private const val channelIdNormal = "ktools_channel_normal" /** * 应用启动时调用 */ fun createNotificationChannel(context: Context){ val channel = NotificationChannel(channelIdNormal, channelIdNormal,NotificationManager.IMPORTANCE_HIGH).apply { description = "应用中的普通通知" } context.notificationManager.createNotificationChannel(channel) }

点击动作

使用PenddingIntent:
PendingIntent.getActivity() PendingIntent.getService() PendingIntent.getBroadcast() PendingIntent.getActivities() PendingIntent.getForegroundService()

显示/更新通知

context.notificationManager.notify(id, notification)

移除通知

除非发生以下情况之一,否则通知仍然可见:
  • 用户关闭通知。
  • 用户点击通知,且您在创建通知时调用了 setAutoCancel()
  • 您针对特定的通知 ID 调用了 cancel()。此方法还会删除当前通知。
  • 您调用了 cancelAll() 方法,该方法将移除之前发出的所有通知。
  • 如果您在创建通知时使用 setTimeoutAfter() 设置了超时,系统会在指定持续时间过后取消通知。如果需要,您可以在指定的超时持续时间过去之前取消通知。

勿扰模式与通知类别

notification.setCategory(NotificationCompat.CATEGORY_MESSAGE)
用来确定用户在勿扰模式下通知是否打扰用户.(并不是必须的)

通知的样式

  • 普通的通知
    • fun createNotification(context: Context, @DrawableRes smallIconID: Int, title: String, content: String, intent: Intent): Int { val pendingIntent = PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT) val notification = NotificationCompat.Builder(context, channelIdNormal) .setContentTitle(title) .setContentText(content) .setSmallIcon(smallIconID) .setContentIntent(pendingIntent) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .addAction(android.R.drawable.ic_btn_speak_now,"Voice",pendingIntent) .build() val id = Random(System.currentTimeMillis()).nextInt() context.notificationManager.notify(id, notification) return id }
  • 带进度条
    • notification.setProgress(0,0,true)
      最后一个参数表示是否未具体的进度和无限循环的样式.
  • 应用图标上的红点通知
    • notification.setShowBadge(true)
  • 可展开的通知
    • 大图
    • notification.setStyle(NotificationCompat.BigPictureStyle() .bigPicture(myBitmap))
    • 大段文本
      • notification.setStyle(NotificationCompat.BigTextStyle() .bigText(emailObject.getSubjectAndSnippet()))
    • 收件箱样式
      • notification.setStyle(NotificationCompat.InboxStyle() .addLine(messageSnippet1) .addLine(messageSnippet2))
    • 对话框样式
      • var message1 = NotificationCompat.MessagingStyle.Message(messages[0].getText(), messages[0].getTime(), messages[0].getSender()) var message2 = NotificationCompat.MessagingStyle.Message(messages[1].getText(), messages[1].getTime(), messages[1].getSender()) var notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.new_message) .setStyle(NotificationCompat.MessagingStyle(resources.getString(R.string.reply_name)) .addMessage(message1) .addMessage(message2)) .build()
    • 媒体类型样式
      • import android.support.v4.app.NotificationCompat import android.support.v4.media.app.NotificationCompat as MediaNotificationCompat var notification = NotificationCompat.Builder(context, CHANNEL_ID) // Show controls on lock screen even when user hides sensitive content. .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setSmallIcon(R.drawable.ic_stat_player) // Add media control buttons that invoke intents in your media service .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0 .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1 .addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2 // Apply the media style template .setStyle(MediaNotificationCompat.MediaStyle() .setShowActionsInCompactView(1 /* #1: pause button \\*/) .setMediaSession(mediaSession.getSessionToken())) .setContentTitle("Wonderful music") .setContentText("My Awesome Band") .setLargeIcon(albumArtBitmap) .build()
  • 自定义布局
    • 直接使用setCustomBigContentView,但是不使用setStyle
    • 使用setStyle + RemoteView:
      • // Get the layouts to use in the custom notification val notificationLayout = RemoteViews(packageName, R.layout.notification_small) val notificationLayoutExpanded = RemoteViews(packageName, R.layout.notification_large) // Apply the layouts to the notification val customNotification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setStyle(NotificationCompat.DecoratedCustomViewStyle()) .setCustomContentView(notificationLayout) .setCustomBigContentView(notificationLayoutExpanded) .build()

打开通知设置页

val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply { putExtra(Settings.EXTRA_APP_PACKAGE, packageName) putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId()) } startActivity(intent)

参考文档

  1. https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=zh-cn
  1. https://developer.android.com/training/notify-user/expanded?hl=zh-cn
Android系统启动流程-桌面程序的启动Android启动流程-init进程分析
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏