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

Android kotlin通知功能完整实现指南:从基础到高级功能

本文将详细介绍如何在Android应用中实现通知功能,包括基础通知、动作按钮和内联回复等高级特性。

一、基础通知实现

1. 基本通知发送方法

fun sendBasicNotification(context: Context, title: String, message: String) {// 1. 创建通知渠道(Android 8.0+必需)val channelId = "default_channel"val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val channel = NotificationChannel(channelId,"默认通知",NotificationManager.IMPORTANCE_DEFAULT).apply {description = "普通优先级通知"}notificationManager.createNotificationChannel(channel)}// 2. 创建点击Intentval intent = Intent(context, MainActivity::class.java).apply {flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK}val pendingIntent = PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)// 3. 构建并发送通知val notification = NotificationCompat.Builder(context, channelId).setSmallIcon(R.drawable.ic_notification).setContentTitle(title).setContentText(message).setPriority(NotificationCompat.PRIORITY_DEFAULT).setContentIntent(pendingIntent).setAutoCancel(true).build()notificationManager.notify(System.currentTimeMillis().toInt(), notification)
}

2. 检查并请求通知权限(Android 13+)

fun checkAndRequestNotificationPermission(activity: Activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {when {ContextCompat.checkSelfPermission(activity,Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED -> {// 已有权限}activity.shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS) -> {// 解释为什么需要权限showPermissionRationaleDialog(activity)}else -> {// 直接请求权限ActivityCompat.requestPermissions(activity,arrayOf(Manifest.permission.POST_NOTIFICATIONS),REQUEST_CODE_NOTIFICATION_PERMISSION)}}}
}

二、带动作按钮的通知

1. 完整实现代码

fun sendNotificationWithActions(context: Context,title: String,message: String,notificationId: Int = System.currentTimeMillis().toInt()
) {// 1. 创建通知渠道val channelId = "actions_channel"val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val channel = NotificationChannel(channelId,"交互通知",NotificationManager.IMPORTANCE_HIGH).apply {description = "包含操作按钮的通知"enableVibration(true)vibrationPattern = longArrayOf(0, 100, 200, 300)}notificationManager.createNotificationChannel(channel)}// 2. 创建主内容Intentval mainIntent = Intent(context, MainActivity::class.java).apply {flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASKputExtra("notification_id", notificationId)}val mainPendingIntent = PendingIntent.getActivity(context,0,mainIntent,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)// 3. 创建动作按钮val actions = listOf(createNotificationAction(context,"ACTION_REPLY","回复",R.drawable.ic_reply,1,notificationId),createNotificationAction(context,"ACTION_ARCHIVE","归档",R.drawable.ic_archive,2,notificationId))// 4. 构建通知val notification = NotificationCompat.Builder(context, channelId).setSmallIcon(R.drawable.ic_notification).setContentTitle(title).setContentText(message).setPriority(NotificationCompat.PRIORITY_HIGH).setContentIntent(mainPendingIntent).setAutoCancel(true).apply {actions.forEach { addAction(it) }}.build()// 5. 发送通知notificationManager.notify(notificationId, notification)
}private fun createNotificationAction(context: Context,action: String,title: String,iconRes: Int,requestCode: Int,notificationId: Int
): NotificationCompat.Action {val intent = Intent(context, NotificationActionReceiver::class.java).apply {this.action = actionputExtra("notification_id", notificationId)}val pendingIntent = PendingIntent.getBroadcast(context,requestCode,intent,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)return NotificationCompat.Action.Builder(iconRes, title, pendingIntent).build()
}

2. 广播接收器实现

class NotificationActionReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent?) {val notificationId = intent?.getIntExtra("notification_id", -1) ?: returnwhen(intent.action) {"ACTION_REPLY" -> handleReplyAction(context, notificationId)"ACTION_ARCHIVE" -> handleArchiveAction(context, notificationId)// 添加更多动作处理...}}private fun handleReplyAction(context: Context, notificationId: Int) {// 启动回复Activityval intent = Intent(context, ReplyActivity::class.java).apply {flags = Intent.FLAG_ACTIVITY_NEW_TASKputExtra("notification_id", notificationId)}context.startActivity(intent)}private fun handleArchiveAction(context: Context, notificationId: Int) {// 取消通知val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagernotificationManager.cancel(notificationId)// 显示归档成功提示Toast.makeText(context, "通知已归档", Toast.LENGTH_SHORT).show()// 这里可以添加实际归档逻辑...}
}

三、高级功能实现

1. 内联回复功能

fun sendNotificationWithInlineReply(context: Context,title: String,message: String,conversationId: Int
) {// ...前面的渠道创建等代码与之前相同...// 1. 创建远程输入val remoteInput = RemoteInput.Builder("key_text_reply").setLabel("输入回复内容").build()// 2. 创建回复动作val replyIntent = Intent(context, NotificationActionReceiver::class.java).apply {action = "ACTION_REPLY"putExtra("conversation_id", conversationId)}val replyPendingIntent = PendingIntent.getBroadcast(context,conversationId,replyIntent,PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_reply,"回复",replyPendingIntent).addRemoteInput(remoteInput).build()// 3. 构建消息样式通知val messagingStyle = NotificationCompat.MessagingStyle("Me").addMessage(message, System.currentTimeMillis(), null)// 4. 构建完整通知val notification = NotificationCompat.Builder(context, channelId).setSmallIcon(R.drawable.ic_notification).setStyle(messagingStyle).addAction(replyAction).build()// 5. 发送通知notificationManager.notify(conversationId, notification)
}

2. 处理内联回复

private fun handleInlineReply(intent: Intent) {val remoteInput = RemoteInput.getResultsFromIntent(intent)val replyText = remoteInput?.getCharSequence("key_text_reply")replyText?.let {val conversationId = intent.getIntExtra("conversation_id", -1)// 处理回复文本,如保存到数据库saveReplyToDatabase(conversationId, it.toString())// 更新通知显示已回复updateNotificationAsReplied(conversationId)}
}

四、最佳实践与优化建议

  1. 通知分组

    .setGroup("messages_group")
    .setGroupSummary(true)
    
  2. 大图标和样式

    .setLargeIcon(bitmap)
    .setStyle(NotificationCompat.BigTextStyle().bigText(longText))
    
  3. 通知重要性分级

    • IMPORTANCE_MIN:只在通知栏显示,无声音或提示
    • IMPORTANCE_LOW:显示并可能发出声音
    • IMPORTANCE_DEFAULT:显示并发出声音
    • IMPORTANCE_HIGH:显示为弹出式通知
  4. 适配不同厂商

    // 针对小米设备
    if (Build.MANUFACTURER.equals("xiaomi", ignoreCase = true)) {builder.setPriority(NotificationCompat.PRIORITY_MAX)
    }
    
  5. 测试建议

    • 测试不同Android版本的表现
    • 测试应用处于前台和后台时的行为
    • 测试设备锁定状态下的显示

五、常见问题解决方案

  1. 通知不显示

    • 检查Android 13+的通知权限
    • 验证通知渠道重要性设置
    • 确保提供了有效的小图标
  2. 动作按钮不工作

    • 检查PendingIntent的flag设置
    • 验证广播接收器是否正确注册
    • 确保没有重复使用相同的requestCode
  3. 内联回复问题

    • 使用FLAG_MUTABLE创建PendingIntent
    • 确保RemoteInput的key与处理时一致
    • 为Android 12+添加适当的PendingIntent flag

通过本文介绍的方法,您可以实现从基础到高级的各种通知功能,为用户提供丰富的交互体验。记得根据您的应用具体需求进行调整和优化。

相关文章:

  • 京东商品详情数据 API 接口讨论学习
  • 《让机器人读懂你的心:情感分析技术融合奥秘》
  • 微服务 RabbitMQ 组件的介绍、安装与使用详解
  • 智能电网第3期 | 配电房巡检机器人通信升级方案
  • 数据库MySQL学习——day2(插入数据与基本查询)
  • Fragment重叠
  • 基于PaddleOCR对图片中的excel进行识别并转换成word(一)
  • 时序约束 记录
  • 【Flutter高效开发】GetX指南:一文学会状态管理、路由与依赖注入
  • 金融租赁质检的三重业务困境 质检LIMS系统的四大价值赋能场景
  • Reactor编程模型介绍
  • vue3:十一、主页面布局(修改顶部导航栏样式-左侧,页面名称设置)
  • 扣子空间 (Coze Space) 使用入门,邀请码获取指南
  • Leetcode98、230:二叉搜索树——递归学习
  • 第十章: User Interface Integration
  • Hive 多表查询案例
  • Python-MCPServer开发-模拟版本
  • ShenNiusModularity项目源码学习(20:ShenNius.Admin.Mvc项目分析-5)
  • OpenCV 中的角点检测方法详解
  • 动态贴纸+美颜SDK的融合实现:底层架构与性能优化技术全解析
  • 钟芳玲|戴耳环的莎士比亚
  • 特斯拉季度利润暴跌71%,马斯克下月开始大幅减少为政府工作时间
  • 具身智能资本盛宴:3个月37笔融资,北上深争锋BAT下场,人形机器人最火
  • 美国务卿宣布将对美国务院进行全面重组
  • 海南一季度GDP为1904.17亿元,同比增长4.0%
  • 云南城投去年营收约19.29亿元,亏损4945万元