0Pricing
Android Academy · 课时

推送通知

通过 Firebase Cloud Messaging 发送推送通知。设置 FCM,创建通知渠道,构建带操作的通知,并处理前台与后台投递。

推送通知 是 CoddyKit 上的免费 Android Academy 课时。 这是第 4 节课,共 6 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 6 节课。

什么是推送通知?

推送通知可以让您的服务器向用户发送消息,即使应用不在前台运行也可以。常见用途包括:

  • 新消息提醒
  • 订单状态更新
  • 突发新闻
  • 提醒和促销信息

在 Android 上,Firebase Cloud Messaging (FCM) 是标准的推送送达服务。

FCM 概览

Firebase Cloud Messaging (FCM) 的流程:

  1. 应用首次启动时向 FCM 注册 → 接收设备令牌
  2. 应用将令牌发送到您的服务器
  3. 您希望推送消息时,服务器将消息发送到 FCM
  4. FCM 将消息送达到设备

FCM 免费、可靠,即使应用被终止也能正常工作。

将 Firebase 添加到项目

添加 Firebase 的步骤:

  1. 打开 Firebase Console → 添加项目 → 添加 Android 应用
  2. 使用包名注册您的应用
  3. 下载 google-services.json,并将其放入 app/
  4. 添加插件和依赖项
// project/build.gradle:
buildscript {
    dependencies { classpath 'com.google.gms:google-services:4.4.1' }
}

// app/build.gradle:
plugins { id 'com.google.gms.google-services' }

dependencies {
    implementation platform('com.google.firebase:firebase-bom:32.7.4')
    implementation 'com.google.firebase:firebase-messaging-ktx'
}

FCM 权限(Android 13+)

从 Android 13(API 33)开始,您必须在运行时请求 POST_NOTIFICATIONS 权限,就像请求危险权限一样:

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

// In Activity (Android 13+):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}

FirebaseMessagingService

创建一个服务来处理收到的 FCM 消息和令牌刷新:

class MyFirebaseService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        // Send token to your backend to enable push delivery
        sendTokenToServer(token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
        val title = message.notification?.title ?: "New Message"
        val body  = message.notification?.body  ?: ""
        showNotification(title, body)
    }
}

在清单中注册服务

在 AndroidManifest.xml 中声明服务:

<service
    android:name=".MyFirebaseService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

通知渠道(Android 8+)

从 Android 8(Oreo)开始,通知必须分配到渠道。用户可以针对每个渠道控制声音、振动和重要性:

fun createNotificationChannel(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel(
            "messages_channel",           // channel ID
            "Messages",                   // user-visible name
            NotificationManager.IMPORTANCE_HIGH
        ).apply {
            description = "Incoming message notifications"
            enableVibration(true)
        }
        val manager = context.getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(channel)
    }
}

创建并显示通知

使用 NotificationCompat.Builder,确保兼容不同 Android 版本:

fun showNotification(context: Context, title: String, body: String) {
    val intent = Intent(context, MainActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        context, 0, intent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )

    val notification = NotificationCompat.Builder(context, "messages_channel")
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle(title)
        .setContentText(body)
        .setPriority(NotificationCompat.PRIORITY_HIGH)
        .setAutoCancel(true)             // dismiss on tap
        .setContentIntent(pendingIntent) // open app on tap
        .build()

    NotificationManagerCompat.from(context)
        .notify(System.currentTimeMillis().toInt(), notification)
}

带操作的通知

为通知添加操作按钮,让用户无需打开应用即可执行操作:

val replyIntent = Intent(context, ReplyReceiver::class.java)
val replyPending = PendingIntent.getBroadcast(
    context, 1, replyIntent,
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)

val notification = NotificationCompat.Builder(context, "messages_channel")
    .setSmallIcon(R.drawable.ic_notification)
    .setContentTitle("New message from Alice")
    .setContentText("Hey, are you coming?")
    .addAction(R.drawable.ic_reply, "Reply", replyPending)
    .addAction(R.drawable.ic_dismiss, "Dismiss", null)
    .build()

前台与后台处理

FCM 的行为取决于应用状态:

  • 应用在前台 — 调用 onMessageReceived();您需要自行创建并显示通知
  • 应用在后台或已被终止 — FCM 会根据 notification 载荷自动显示通知;不会调用 onMessageReceived

请将额外数据放入 data 载荷中(而不是 notification),这样就始终能在 onMessageReceived 中接收到这些数据。

获取 FCM 令牌

获取当前的 FCM 令牌,以便发送到您的服务器:

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w("FCM", "Fetching token failed", task.exception)
        return@addOnCompleteListener
    }
    val token = task.result
    Log.d("FCM", "Token: $token")
    // Send token to your server
    sendTokenToServer(token)
}

快速检查

当您的应用处于后台,并且 FCM 传送了带有“notification”载荷的消息时,会发生什么?

回顾:推送通知

在 Android 上使用 FCM 实现推送通知:

  • 添加 Firebase、google-services.json 和 firebase-messaging-ktx
  • 在 Android 13+ 上请求 POST_NOTIFICATIONS
  • 创建 FirebaseMessagingService → onNewToken + onMessageReceived
  • 为 Android 8+ 创建 NotificationChannel
  • 使用 NotificationCompat.Builder 创建通知
  • 使用 data 载荷,确保始终能在 onMessageReceived 中接收数据

接下来:使用 WorkManager 安排后台任务。

常见问题解答

「推送通知」课时是免费的吗?

是的 — 「推送通知」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 6 节课。

「推送通知」这节课中我会学到什么?

通过 Firebase Cloud Messaging 发送推送通知。设置 FCM,创建通知渠道,构建带操作的通知,并处理前台与后台投递。 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Android Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 6 节。

「推送通知」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Android Academy 课中编写并运行代码吗?

能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Retrofit 与 REST API
  2. 使用 Coil 加载图片
  3. 错误处理与用户体验
  4. 推送通知
  5. WorkManager 与后台任务
  6. 发布到 Play Store
← 返回 Android Academy