打开具有多个内部意图的应用程序并等待结果

Open app with multiple inner Intents and wait for result

我有一个应用程序 (APP1),它应该打开另一个应用程序 (APP2) 并等待结果。我是这样做的。

private fun startBridgeActivity(fileName: String, isProduction: Boolean) {
        val intent = Intent(Intent.ACTION_MAIN)
        when (isProduction) {
            true -> {
                intent.component = ComponentName(
                    "com.myapp",
                    "com.myapp.view.ui.ItemSelectionActivity"
                )
            }
            else -> {
                intent.component = ComponentName(
                    "com.myapp.dev",
                    "com.myapp.view.ui.ItemSelectionActivity"
                )
            }
        }
        try {
            startActivityForResult(intent, REQUEST_CODE)
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this@MainActivity, "This activity does not exist", Toast.LENGTH_LONG).show()
        }
    }

然后APP2收到这个intent,自己打开。这个APP2的启动方式是标准的。 APP2里面的导航如下:

ReceiverActivity - Step1Activity - Step2Activity - LastActivity

我试过设置结果并完成 LastActivity,但它不起作用。还尝试使用 finishAffinityfinishAndRemoveTasks,但它们也没有用。

然后我所做的就是从 LastActivity 调用 ReceiverActivity 并在那里设置结果并完成它。但这让我留在主屏幕上,结果不会到达 APP1。

val receiverActivityIntent = Intent(this@LastActivity, ReceiverActivity::class.java)
        receiverActivityIntent.putExtra("end", true)
        TaskStackBuilder.create(this@ReceiverActivity)
                .addParentStack(ReceiverActivity::class.java)
                .addNextIntent(receiverActivityIntent)
                .startActivities()
        finish()

我读了一些其他的 SO 答案,其中有人写道,来自 APP1 的 Activity 将被添加到 APP2 的堆栈中,这可能就是应用程序进入主屏幕的原因。

我们将不胜感激。

谢谢。

您的应用启动 ItemSelectionActivity 使用 startActivityForResult()。当 ItemSelectionActivity 完成时,您的应用程序将获得回调 onActivityResult()。它会在调用 setResult().

时收到 ItemSelectionActivity 设置的结果

如果 ItemSelectionActivity 需要启动其他活动才能将结果发送回您的应用程序,您可以通过以下几种可能的方式执行此操作:

  1. 使用FLAG_ACTIVITY_FORWARD_RESULT

ItemSelectionActivity 启动另一个 Activity 时,它应该在 Intent 中设置标志 Intent.FLAG_ACTIVITY_FORWARD_RESULT 并调用 startActvity() (do不要调用 startActivityForResult()。正在启动的 Activity 必须随后调用 setResult() 并返回结果,数据将传回您的应用程序。您基本上是 "forwarding" 一个 Activity 对结果的请求到下一个。由于你似乎有几个活动要经过才能得到结果,你可以继续将责任从一个 Activity 转发到下一个 Activity。链中的最后一个应该调用 setResult(),这些结果将在 onActivityResult().

中传回您的应用程序
  1. startActivityForResult()调用:

ItemSelectionActivity 启动另一个 Activity 时,它应该调用 startActvityForResult()。正在启动的 Activity 然后必须用结果调用 setResult(),并且该数据将传回 onActivityResult() 中的 ItemSelefctionActivityItemSelectionActivity 本身应该用数据和 finish() 调用 setResult()。结果将传回您的应用程序。由于在获得结果之前似乎要完成多项活动,因此您可以继续链接这些调用,以便每个 Activity 使用 starActivityForResult() 启动下一个 Activity 和被调用的 Activity needs to pass the results back usingsetResult()`.

  1. LastActivity将结果传递给ItemSelectionActivity:

这是您已经尝试实施的解决方案。 LastActivity returns 结果直接给ItemSelectionActivity。但是,您的实施已损坏。 请勿使用 TaskStackBuilder 来完成此操作! TaskStackBuilder 有很多副作用会破坏任务中的 Activity 堆栈。你想要做的是:

val receiverActivityIntent = Intent(this@LastActivity, ReceiverActivity::class.java)
receiverActivityIntent.putExtra("end", true)
// add the results to the Intent
receiverActivityIntent.putExtra("results", results)
// Set the CLEAR_TOP and SINGLE_TOP flags (if necessary) to remove any
//  activities that are on the stack between ReceiverActivity and LastActivity
receiverActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
    Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(receiverActivityIntent)
// Calling finish() here isn't necessary if you set the Intent flags
finish()

注意:我的 Kotlin 语法可能不是 100% 正确,但希望你能理解。

使用此解决方案,结果将传送到 onNewIntent() 中的 ReceiverActivity。您将需要覆盖 onNewIntent(),从传递的 Intent 中获取结果,然后使用结果调用 setResult() 以将它们传回您的应用程序。