Android前台点击FCM推送时,能否弹出跳转确认对话框?
实现方案
这个需求完全可以实现,核心是通过一个透明中转Activity拦截通知点击事件,先弹出确认对话框,再根据用户选择决定是否跳转目标页面。具体步骤如下:
1. 创建透明中转Activity
新建NotificationHandlerActivity,它仅负责接收通知点击事件、弹出确认框,不显示任何可见界面。
第一步:配置Activity主题(在AndroidManifest.xml中)
给该Activity设置透明主题,避免启动时出现界面闪烁:
<activity android:name=".NotificationHandlerActivity" android:theme="@style/TransparentActivityTheme" android:launchMode="singleTask" android:excludeFromRecents="true"/>
对应的透明主题(在res/values/styles.xml中添加):
<style name="TransparentActivityTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item> <item name="android:windowNoTitle">true</item> <item name="android:windowFullscreen">true</item> </style>
第二步:实现Activity逻辑
在NotificationHandlerActivity中完成前台判断、对话框展示及跳转逻辑:
class NotificationHandlerActivity : AppCompatActivity() { private var entityId: Int? = null private var entityType: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 接收通知传递的参数 entityId = intent.getIntExtra(ENTITY_ID, -1) entityType = intent.getStringExtra(ENTITY_TYPE) if (isAppInForeground()) { // 应用在前台,弹出确认对话框 showConfirmDialog() } else { // 应用在后台,直接跳转到目标页面 navigateToTargetPage() finish() } } // 判断应用是否处于前台 private fun isAppInForeground(): Boolean { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val runningProcesses = activityManager.runningAppProcesses ?: return false for (processInfo in runningProcesses) { if (processInfo.processName == packageName && processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return true } } return false } // 显示确认对话框 private fun showConfirmDialog() { AlertDialog.Builder(this) .setTitle("提示") .setMessage("即将离开当前页面,是否继续?") .setPositiveButton("前往") { _, _ -> navigateToTargetPage() finish() } .setNegativeButton("取消") { _, _ -> finish() // 直接关闭中转Activity,不跳转 } .setCancelable(false) .show() } // 跳转到原目标页面SplashActivity private fun navigateToTargetPage() { val intent = Intent(this, SplashActivity::class.java).apply { entityId?.let { putExtra(ENTITY_ID, it) } putExtra(ENTITY_TYPE, entityType) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) } startActivity(intent) } // 与原代码保持一致的常量定义 companion object { const val ENTITY_ID = "ENTITY_ID" const val ENTITY_TYPE = "ENTITY_TYPE" } }
2. 修改原通知构建代码中的PendingIntent
将原本指向SplashActivity的Intent替换为指向NotificationHandlerActivity,参数保持不变:
// 替换原Intent目标为中转Activity val intent = Intent(this, NotificationHandlerActivity::class.java).apply { putExtra(ENTITY_ID, entityId?.toInt()) putExtra(ENTITY_TYPE, entityType) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) } val pendingIntent: PendingIntent? = TaskStackBuilder.create(this).run { addNextIntentWithParentStack(intent) getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) } // 后续通知构建代码保持不变...
关键细节说明
- 透明Activity仅作为事件中转,不会干扰用户当前界面体验
- 仅在应用前台时弹出对话框,后台直接跳转,符合常规用户使用习惯
- 完整保留原通知的参数传递逻辑,确保原有跳转目标页面的功能不受影响
- 保留
PendingIntent.FLAG_UPDATE_CURRENT和FLAG_IMMUTABLE标记,适配Android 12+安全要求,避免重复创建PendingIntent
内容的提问来源于stack exchange,提问作者Jamal N
相关产品推荐
相关产品推荐

