如何手动执行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中完成登录校验后再决定跳转方向:
- 创建中转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) } }
- 在Manifest中配置中转Activity
<activity android:name=".NotificationHandlerActivity" android:launchMode="singleTask" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
- 修改通知的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的全局监听器拦截目标页面的跳转:
- 在主Activity中设置跳转拦截
navController.addOnDestinationChangedListener { _, destination, _ -> // 当目标页面是需要校验的Fragment且用户未登录时,拦截跳转 if (destination.id == R.id.fragment && !isUserLoggedIn()) { navController.navigate(R.id.loginFragment) // 可保存目标页面信息,登录成功后自动跳转 AppPrefs.putInt("target_destination", R.id.fragment) } }
- 登录成功后跳转至原目标页面
在登录页的登录成功回调中,读取保存的目标页面并跳转:
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中处理:
- 修改Manifest中主Activity的启动模式
<activity android:name=".MainActivity" android:launchMode="singleTask"> ... </activity>
- 重写
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
相关产品推荐
相关产品推荐

