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

Android 中使用通知(Kotlin 版)

1. 前置条件

  • Android Studio:确保使用最新版本(2023.3.1+)
  • 目标 API:最低 API 21,兼容 Android 8.0(渠道)和 13+(权限)
  • 依赖库:使用 WorkManagerNotificationCompat

2. 完整实现步骤

2.1 添加权限和依赖

AndroidManifest.xml
<!-- 通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android 13+ 必须 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- 若需网络请求 --><application><!-- 添加你的主 Activity --><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
</application>
build.gradle (Module)
dependencies {// WorkManager 用于后台任务implementation "androidx.work:work-runtime-ktx:2.7.1"// 通知兼容库implementation "androidx.core:core-ktx:1.12.0"
}

2.2 创建通知渠道(Android 8.0+ 必需)

NotificationHelper.kt
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Buildobject NotificationHelper {const val CHANNEL_ID = "dynamic_messages_channel"const val NOTIFICATION_ID = 101 // 用于更新同一通知fun createNotificationChannel(context: Context) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// 避免重复创建渠道val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerif (notificationManager.getNotificationChannel(CHANNEL_ID) != null) return// 配置渠道属性val name = "动态消息"val importance = NotificationManager.IMPORTANCE_HIGHval channel = NotificationChannel(CHANNEL_ID, name, importance).apply {description = "用于接收实时动态消息的推送"enableLights(true)lightColor = android.graphics.Color.RED}notificationManager.createNotificationChannel(channel)}}
}

2.3 构建动态通知

NotificationUtils.kt
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.example.myapp.R // 替换为你的包名object NotificationUtils {fun showDynamicNotification(context: Context,title: String,message: String) {// 创建点击跳转逻辑(示例跳转到 MainActivity)val 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)// 构建通知val builder = NotificationCompat.Builder(context, NotificationHelper.CHANNEL_ID).setSmallIcon(R.drawable.ic_notification) // 必须的图标(需在 res/drawable 添加).setContentTitle(title).setContentText(message).setPriority(NotificationCompat.PRIORITY_HIGH).setContentIntent(pendingIntent).setAutoCancel(true) // 点击后自动消失.setStyle(NotificationCompat.BigTextStyle().bigText(message)) // 长文本支持// 发送通知with(NotificationManagerCompat.from(context)) {if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {notify(NotificationHelper.NOTIFICATION_ID, builder.build())}}}// 更新通知(使用相同 ID)fun updateNotification(context: Context, newTitle: String, newMessage: String) {val builder = NotificationCompat.Builder(context, NotificationHelper.CHANNEL_ID).setSmallIcon(R.drawable.ic_notification).setContentTitle(newTitle).setContentText(newMessage)NotificationManagerCompat.from(context).notify(NotificationHelper.NOTIFICATION_ID, builder.build())}
}

2.4 后台任务调度(WorkManager)

NotificationWorker.kt
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import kotlinx.coroutines.delayclass NotificationWorker(context: Context,params: WorkerParameters
) : CoroutineWorker(context, params) {override suspend fun doWork(): Result {// 模拟网络请求延迟delay(3000)// 获取动态数据(此处为模拟数据,实际需替换为真实逻辑)val title = "您有新的消息!"val content = "当前时间:${System.currentTimeMillis()}"// 显示通知NotificationUtils.showDynamicNotification(applicationContext, title, content)return Result.success()}
}
调度任务(在 MainActivity 中)
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import java.util.concurrent.TimeUnitclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 初始化通知渠道NotificationHelper.createNotificationChannel(this)// 请求通知权限(Android 13+)requestNotificationPermission()// 启动周期性后台任务(每15分钟一次)val workRequest = PeriodicWorkRequestBuilder<NotificationWorker>(15, TimeUnit.MINUTES // 注意:最短间隔为15分钟).build()WorkManager.getInstance(this).enqueue(workRequest)}private fun requestNotificationPermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {if (checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) !=PackageManager.PERMISSION_GRANTED) {requestPermissions(arrayOf(android.Manifest.permission.POST_NOTIFICATIONS),REQUEST_CODE_NOTIFICATION)}}}companion object {private const val REQUEST_CODE_NOTIFICATION = 1001}
}

2.5 处理权限请求结果

MainActivity 中重写 onRequestPermissionsResult

override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<String>,grantResults: IntArray
) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {REQUEST_CODE_NOTIFICATION -> {if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 用户已授权} else {// 处理拒绝逻辑(例如显示提示)}}}
}

3. 扩展优化建议

3.1 结合网络请求

使用 Retrofit + Kotlin Coroutines 获取真实数据:

// 在 NotificationWorker 中替换模拟数据
val response = apiService.fetchMessages()
if (response.isSuccessful) {val message = response.body()?.latestMessagemessage?.let {NotificationUtils.showDynamicNotification(context, it.title, it.content)}
}

3.2 通知分组(Android 7.0+)

val builder = NotificationCompat.Builder(...).setGroup("messages_group").setGroupSummary(true) // 分组摘要

3.3 通知操作按钮

// 添加“标记已读”操作
val readIntent = Intent(context, MarkReadReceiver::class.java)
val readPendingIntent = PendingIntent.getBroadcast(...)
builder.addAction(NotificationCompat.Action.Builder(R.drawable.ic_check,"标记已读",readPendingIntent).build()
)

4. 常见问题解决

  1. 通知不显示

    • 检查是否在 Android 13+ 设备上授予了权限
    • 确保通知渠道已正确创建
    • 验证 setSmallIcon 使用了有效的资源 ID
  2. 后台任务不触发

    • 确保 WorkManager 依赖已添加
    • 检查设备是否处于 Doze 模式(测试时可暂时禁用)
  3. 通知点击无响应

    • 确认 PendingIntentFLAG_IMMUTABLE 正确使用
    • 检查目标 Activity 是否在 Manifest 中注册

可进一步结合 Firebase Cloud Messaging (FCM) 实现服务端消息推送,或添加更复杂的交互逻辑。

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

相关文章:

  • PPT 转高精度 PDF API 接口
  • 【流程控制结构】
  • Vue.js教学第一章: Vue 简介与环境搭建
  • neo4j框架:java安装教程
  • 《项目管理知行合一:知识体系构建与实战应用指南》
  • 十步法基于Vanna打造高效便捷的 SQL 生成与业务洞察工具
  • 消息队列与Kafka基础:从概念到集群部署
  • 文件上传Ⅲ
  • 基于React的高德地图api教程007:椭圆的绘制、编辑和删除
  • 【项目】自主实现HTTP服务器:从Socket到CGI全流程解析
  • C++ --- new与delete
  • upload-labs通关笔记-第8关 文件上传之点绕过
  • visio下载安装教程超详细图文教程(附完整安装包)|visio2024
  • 《解锁数字藏品交易系统的底层密码:区块链架构抉择》
  • HNUST湖南科技大学-安卓Android期中复习
  • WebRTC中的几个Channel
  • 【串流VR手势】Pico 4 Ultra Enterprise 在 SteamVR 企业串流中无法识别手势的问题排查与解决过程(Pico4UE串流手势问题)
  • uni-app 中适配 App 平台
  • UML活动图零基础入门:1 分钟掌握核心逻辑(附实战模板)
  • k8s部署grafana
  • Ai Agent革命:不是流程驱动,而是模型为魂
  • Perl语言深度考查:从文本处理到正则表达式的全面掌握
  • 地下停车场调频广播无线覆盖系统:融合精准选频光纤传输均匀覆盖于一体的创新型地下车库广播无线覆盖平台
  • 【数据开发】埋点体系的讲解 - 埋点方式、原理、优缺点
  • C#里使用Prism.Core的例子
  • 技术剖析|线性代数之特征值分解,支撑AI算法的数学原理
  • 掌握 LangChain 文档处理核心:Document Loaders 与 Text Splitters 全解析
  • 我设计的一个安全的 web 系统用户密码管理流程
  • GpuGeek 实操指南:So-VITS-SVC 语音合成与 Stable Diffusion 文生图双模型搭建,融合即梦 AI 的深度实践
  • 以项目的方式学QT开发C++(二)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!