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

如何手动执行PendingIntent?需在触发前校验用户登录状态

问题:通知跳转前校验用户登录状态的实现方案

当前通过NavDeepLinkBuilder创建PendingIntent实现通知点击跳转指定Fragment,代码如下:

fun showNotification() {
    val pendingIntent = NavDeepLinkBuilder(this)
        .setGraph(R.navigation.nav_graph)
        .setDestination(R.id.fragment)
        .createPendingIntent()
    ...
}

跳转逻辑正常,但希望在跳转前校验用户登录状态,预期逻辑:

if (isLoggedIn) pendingIntent.execute()
else navigateToLoginPage()

但PendingIntent会在点击通知时立即触发,无法提前校验,且重写onNewIntent方法未生效,需要控制PendingIntent的执行时机。


解决方案

方法1:通过中转Activity做登录校验

不要直接将PendingIntent指向目标Fragment,而是指向一个专门的中转Activity,在该Activity中完成登录校验后再决定跳转方向:

  1. 创建中转Activity(无界面)
class NotificationHandlerActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 执行登录状态校验
        if (isUserLoggedIn()) {
            // 校验通过,启动目标Fragment的跳转逻辑
            val navIntent = NavDeepLinkBuilder(this)
                .setGraph(R.navigation.nav_graph)
                .setDestination(R.id.fragment)
                .createIntent()
            startActivity(navIntent)
        } else {
            // 未登录,跳转至登录页
            startActivity(Intent(this, LoginActivity::class.java))
        }
        
        // 中转Activity无需显示,直接销毁
        finish()
    }

    private fun isUserLoggedIn(): Boolean {
        // 替换为实际的登录状态判断逻辑
        return AppPrefs.getBoolean("is_logged_in", false)
    }
}
  1. 在Manifest中配置中转Activity
<activity
    android:name=".NotificationHandlerActivity"
    android:launchMode="singleTask"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
  1. 修改通知的PendingIntent指向
fun showNotification() {
    val pendingIntent = PendingIntent.getActivity(
        this,
        0,
        Intent(this, NotificationHandlerActivity::class.java),
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
    // 构建并显示通知的其他代码...
}

方法2:利用Navigation全局监听拦截跳转

如果不想新增中转Activity,可通过Navigation的全局监听器拦截目标页面的跳转:

  1. 在主Activity中设置跳转拦截
navController.addOnDestinationChangedListener { _, destination, _ ->
    // 当目标页面是需要校验的Fragment且用户未登录时,拦截跳转
    if (destination.id == R.id.fragment && !isUserLoggedIn()) {
        navController.navigate(R.id.loginFragment)
        // 可保存目标页面信息,登录成功后自动跳转
        AppPrefs.putInt("target_destination", R.id.fragment)
    }
}
  1. 登录成功后跳转至原目标页面
    在登录页的登录成功回调中,读取保存的目标页面并跳转:
val targetDest = AppPrefs.getInt("target_destination", -1)
if (targetDest != -1) {
    navController.navigate(targetDest)
    AppPrefs.remove("target_destination")
}

关于onNewIntent未触发的说明

onNewIntent仅在Activity为singleTop/singleTask启动模式,且当前Activity处于栈顶时才会触发。若要使用该方式,需先修改主Activity的启动模式,再在onNewIntent中处理:

  1. 修改Manifest中主Activity的启动模式
<activity
    android:name=".MainActivity"
    android:launchMode="singleTask">
    ...
</activity>
  1. 重写onNewIntent处理跳转
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    setIntent(intent)
    
    if (isUserLoggedIn()) {
        navController.handleDeepLink(intent)
    } else {
        startActivity(Intent(this, LoginActivity::class.java))
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:15:42