【问题标题】:Utilise Android Navigation component to handle deep links with a splash screen activity利用 Android Navigation 组件处理带有初始屏幕活动的深层链接
【发布时间】:2020-01-12 16:03:53
【问题描述】:

我有一个包含两个活动的应用程序,一个启动屏幕活动,另一个包含应用程序的主导航图。

我想利用 Android 导航组件附带的新的深度链接处理。但是,按照 Google 教程,单击链接时会跳过启动屏幕并直接进入应用程序的导航图。

有什么方法可以使用这些新功能,同时仍然强制在导航到应用程序的正确部分之前先显示初始屏幕?

【问题讨论】:

  • 您是否要在应用程序的正确部分之前显示启动画面(使用导航组件)?
  • 感谢您的回复@HemantSharma。要求是先显示初始屏幕(没有导航组件),然后将深层链接传递到主要活动(具有导航组件)。最终找到了解决方案(见下文)。

标签: android navigation components splash-screen deep-linking


【解决方案1】:

发布我来到这里的解决方案,以防其他人有相同的要求。

最后其实很简单!在启动屏幕活动中,如下所示捕获 pendingDynamicLinkData:

private fun decideNextDestination() {
       FirebaseDynamicLinks.getInstance()
          .getDynamicLink(intent)
          .addOnSuccessListener(this) { pendingDynamicLinkData ->
              val deepLink = pendingDynamicLinkData?.link
              if (deepLink == null) navigateToMain() else deepLinkToDestination(deepLink)
          }
          .addOnFailureListener(this) { navigateToMain() }
}

然后在 deepLinkToDestination 方法中,构建一个意图并添加一个带有深度链接 URI 的捆绑包以传递(Android Uri 实现了 parcelable,因此可以毫无问题地传递):

private fun deepLinkToDestination(deepLink: Uri) {
    val bundle = Bundle().apply { putParcelable(DEEP_LINK_PARAM_KEY, deepLink) }
    val intent = Intent(this, NavHostActivity::class.java).apply { putExtras(bundle) }
    startActivity(intent)
    finish()
}

然后在目标 Activity 的 onCreate 中,抓取深层链接,投射到 Uri 并使用隐式深层链接导航(参见文档https://developer.android.com/guide/navigation/navigation-deep-link#implicit),如下所示:

private fun handleDeepLink() {
    val deepLink = intent.extras?.getParcelable(DEEP_LINK_PARAM_KEY) as? Uri
    deepLink?.let { navController.safeNavigateToDeepLink(deepLink) }
}

我为 NavController 创建了一个扩展函数 safeNavigateToDeepLink(deepLink),以检查 navGraph 是否引用了该深层链接(如导航组件源代码中所建议的那样),如果找不到,则导航到默认目的地:

fun NavController.safeNavigateToDeepLink(uri: Uri) {
    if (graph.hasDeepLink(uri)) navigate(uri)
    else safeNavigateTo(R.id.home)
}

如果它对其他人有帮助,则其中的另一个扩展功能如下,它只是检查在导航之前是否可以找到导航到该目的地的操作:

fun NavController.safeNavigateTo(id: Int) {
    val action = currentDestination?.getAction(id)
    action?.let { navigate(id) }
}

【讨论】:

  • 那么在相同场景下的显式深度链接呢?
  • 这样你需要在你启动活动的清单中手动声明一个意图过滤器,对吧?因为 不起作用。
猜你喜欢
  • 2020-04-07
  • 2021-09-21
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
相关资源
最近更新 更多