我正在开发一个商店应用程序。用户可以通过消息、电子邮件等方式分享产品。我的任务是一旦收到共享链接的Oter用户点击该链接,我的应用程序应该打开并导航到产品详细信息页面,并使用URI中的产品ID来获取产品。
我使用Firebase动态链接来生成短链接。当我点击链接让说在消息应用程序.我的应用程序将在消息应用程序中打开,而不是作为单独的应用程序打开。我通过将活动启动模式更改为
android:launchMode="singleTask"
只有当我的应用程序没有启动时它才能工作。但是当应用程序在后台时,点击链接不会做任何事情。
我不确定如何在NewIntent(intent:Intent?)函数来正确处理深度链接。目前,我发现TEMP解决方案是工作,但我不知道如果它的正确的方式这样做。我的newIntent代码。
class MainActivity : ComponentActivity() {
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
val pendingIntent = TaskStackBuilder.create(applicationContext).run {
addNextIntentWithParentStack(intent)
getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
}
pendingIntent.send()
}
}
我的清单文件:
<activity android:launchMode="singleTask" android:name=".presentation.MainActivity" android:exported="true" android:theme="@style/Theme.B2CApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="*****.page.link" />
</intent-filter>
</activity>
这就是我如何使用deepLink导航
composable(
CategoryRoute.ProductDetail.route,
deepLinks = listOf(
navDeepLink {
uriPattern = "****.page.link/{$DEEP_LINK}"
action = Intent.ACTION_VIEW
}
),
arguments = listOf(
navArgument(PRODUCT_ID) {
type = NavType.StringType
defaultValue = ""
},
navArgument(DEEP_LINK) {
type = NavType.StringType
defaultValue = ""
}
)
)
我试图调用havController来处理newIntent func中的深层链接,但我无法访问MainActivity文件中的navHostController。
更新:@Watermelon建议之后:我的清单文件没有更改。我的主要活动现在看起来像这样:
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val newIntent by produceState(initialValue = null as Intent?) {
val consumer = androidx.core.util.Consumer<Intent> {
this.value = it
}
addOnNewIntentListener(consumer)
awaitDispose {
removeOnNewIntentListener(consumer)
}
}
B2CTheme {
MainScreen(newIntent)
}
}
}
}
我的主屏幕是:
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(newIntent: Intent?) {
val navController = rememberNavController()
val systemUiController = rememberSystemUiController()
val currentIntent = rememberUpdatedState(newValue = newIntent)
LaunchedEffect(Unit) {
snapshotFlow { currentIntent.value }.filterNotNull()
.map {
/* do extra jobs*/
println(it.dataString)
it
}
.collect{
navController.handleDeepLink(it)
}
}
SideEffect {
systemUiController.setStatusBarColor(
color = LightColorScheme.surface,
darkIcons = true
)
}
Scaffold(
bottomBar = {
B2CBottomBar(navController) {
navController.navigate(it.route) {
launchSingleTop = true
popUpTo(it.route) {
inclusive = true
}
}
}
}
) {
MainNavHost(
navController = navController,
Modifier.padding(top = it.calculateTopPadding()))
}
}
另外,我最初的解决方案有一个bug。当用户从外部单击链接时,我的应用程序会打开并在我的HomeTab中正确显示产品。如果我点击后退按钮,它会带我回到根主页选项卡。如果我从底部导航中选择任何其他选项卡并再次单击Home选项卡,我仍然可以看到从DeepLink获得的产品。
1条答案
按热度按时间xdyibdwo1#
1.如果您可以直接访问活动。
2.或者如果你想解耦它的一些方式。
FeatureApp可以像这样处理Intent
如果
handleDeepLink
没有像你预期的那样工作,考虑在你的intent过滤器中添加IntentFlags。或者配置它并通过调用
navigate
而不是handleDeepLink
自行导航到目的地。但是我不推荐这种方式,因为这会导致通过deeplink启动新活动与使用deeplink更新现有活动之间的不同行为