You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:如何通过PendingIntent传参实现通知Action点击后取消并跳转?

解决通知Action按钮点击后跳转并取消通知的问题

我做了一个带Action按钮的通知,希望点击按钮后打开应用内指定页面,同时自动取消通知。点击通知主体时用setAutoCancel(true)就能取消,但Action按钮必须调用NotificationManager.cancel(id)才行。我尝试在Intent里传通知ID作为Extra,结果出现异常:应用后台时点击Action会拉到前台,但前台时点击没反应(跳不到目标页面),而且BroadcastReceiver接收不到任何参数。

现有代码

NotificationPublisher.kt

val intent = Intent(Intent.ACTION_VIEW).apply {
    //a uri to destination fragment
    data = intents.getDestination()
    flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
intent.putExtra("notification_id", idHashCode)
val pendingIntent = PendingIntent.getActivity(context,idHashCode,intent,PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
return NotificationCompat.Builder(context,CHANNEL)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle(title)
    .setContentText(subTitle)
    .setDefaults(Notification.DEFAULT_ALL)
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setVibrate(LongArray(2) { 1000 })
    .setNumber(1)
    .setOnlyAlertOnce(true)
    .setStyle(NotificationCompat.BigTextStyle())
    .setAutoCancel(true)
    .addAction(0,getActionTextWithColor(context, R.string.go_to_destination, R.color.primary), pendingIntent)

NotificationReceiver.kt

class NotificationReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val id = intent.getIntExtra("notification_id", -1)
        if(id > 0){
            val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.cancel(id)
        }
    }
}

AndroidManifest.xml

<receiver android:name="com.myApp.notification.NotificationReceiver"
          android:exported="false"
          android:enabled="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <data
            android:host="myApp.com"
            android:pathPrefix="/destination"
            android:scheme="myApp" />
    </intent-filter>
</receiver>

解决方案

方案一:用广播接收器串联取消通知+跳转逻辑

核心是给Action按钮绑定广播PendingIntent,在广播里先取消通知,再启动页面跳转:

  1. 修改NotificationPublisher.kt
// 1. 定义跳转页面的Intent
val pageIntent = Intent(Intent.ACTION_VIEW).apply {
    data = intents.getDestination()
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
}

// 2. 定义取消通知的广播Intent
val cancelIntent = Intent(context, NotificationReceiver::class.java).apply {
    putExtra("notification_id", idHashCode)
    action = "com.myApp.action.CANCEL_NOTIFICATION" // 自定义action避免冲突
}
val cancelPendingIntent = PendingIntent.getBroadcast(
    context,
    idHashCode + 1000, // 用不同requestCode区分PendingIntent
    cancelIntent,
    PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)

// 3. 给Action按钮绑定广播PendingIntent
return NotificationCompat.Builder(context, CHANNEL)
    // 保留原有其他配置
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle(title)
    .setContentText(subTitle)
    .setDefaults(Notification.DEFAULT_ALL)
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setVibrate(LongArray(2) { 1000 })
    .setNumber(1)
    .setOnlyAlertOnce(true)
    .setStyle(NotificationCompat.BigTextStyle())
    .setAutoCancel(true)
    .addAction(
        0,
        getActionTextWithColor(context, R.string.go_to_destination, R.color.primary),
        cancelPendingIntent
    )
  1. 修改NotificationReceiver.kt
class NotificationReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val id = intent.getIntExtra("notification_id", -1)
        if (id > 0) {
            // 先取消通知
            val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.cancel(id)
            
            // 再启动页面跳转
            val pageIntent = Intent(Intent.ACTION_VIEW).apply {
                data = intents.getDestination() // 复用原目标Uri
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
            }
            context.startActivity(pageIntent)
        }
    }
}
  1. 修改AndroidManifest.xml的接收器配置
<receiver android:name="com.myApp.notification.NotificationReceiver"
          android:exported="false"
          android:enabled="true">
    <intent-filter>
        <action android:name="com.myApp.action.CANCEL_NOTIFICATION"/>
    </intent-filter>
</receiver>

方案二:在目标页面Activity中取消通知

如果跳转目标是Activity,直接在Activity里处理通知取消,无需广播接收器:

  1. 修改NotificationPublisher.kt
val intent = Intent(context, TargetActivity::class.java).apply {
    putExtra("notification_id", idHashCode)
    // 确保前台状态下也能触发页面更新
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
}
val pendingIntent = PendingIntent.getActivity(
    context,
    idHashCode,
    intent,
    PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)

return NotificationCompat.Builder(context, CHANNEL)
    // 保留原有其他配置
    .addAction(
        0,
        getActionTextWithColor(context, R.string.go_to_destination, R.color.primary),
        pendingIntent
    )
  1. 在TargetActivity中处理取消逻辑
class TargetActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleNotificationCancel()
        // 切换到目标Fragment的逻辑
        supportFragmentManager.beginTransaction()
            .replace(R.id.container, TargetFragment())
            .commit()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleNotificationCancel()
    }

    private fun handleNotificationCancel() {
        intent.getIntExtra("notification_id", -1).takeIf { it > 0 }?.let { id ->
            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.cancel(id)
        }
    }
}

问题根源

之前的写法有两个核心问题:

  1. 用PendingIntent.getActivity()创建的是启动Activity的PendingIntent,广播接收器根本接收不到这个Intent,自然拿不到notification_id
  2. 应用前台时,仅设置FLAG_ACTIVITY_NEW_TASK不会触发Activity的重新创建,如果Activity未处理onNewIntent,就不会执行跳转逻辑

内容的提问来源于stack exchange,提问作者Joan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:12:04