Home > database >  How To Send Intent Back using ActivityLauncher API?
How To Send Intent Back using ActivityLauncher API?

Time:04-05

I've been using this method to try to send data between Activities, but Google don't show you how to send the data back from the other Activity. So I started looking for other methods that might work, and the only thing I could find was Activity.setResult(), but every time I try to run it, the intent doesn't return with anything, or that it does, but not in time for me to use it. I'm thinking I need an asynchronous method, but once again, Google doesn't tell you.

So I have two activities, MainActivity and Second Activity, and in Main, I have the registerForActivityResult() wherein I use the generic Intent version of the Contract to make the registration (explained here) Then in Second, I have a method that, on click of a TextView, makes a new Intent object, and sends the data back.

Main Activity:

class MainActivity : AppCompatActivity() {
    private var data: String = ""


    private val activityLauncher: ActivityResultLauncher<Intent> =
        registerForActivityResult<Intent, ActivityResult>(
            StartActivityForResult()
        ) { result: ActivityResult ->
            onActivityResult(result)
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    /**
     * Switches to a different Activity
     * @return Nothing: do you see :Unit anywhere?
     * @param view: The view to Use
     */
    fun onClickSwitchActivity(view: View) {
        val editText: EditText = findViewById<EditText>(R.id.etText)
        val text: String = editText.text.toString()
        val intent: Intent = Intent(this, SecondActivity::class.java)
        intent.putExtra(REQUEST_RESULT, text)
        activityLauncher.launch(intent)
    }

    fun onActivityResult(result: ActivityResult) {
        if (result.resultCode == Activity.RESULT_OK) {
            var intent:Intent?=null
            if (result.data == null)
                Toast.makeText(this, "Intent was null: nothing returned", Toast.LENGTH_LONG).show()
            else{
                intent = result.data
            }
            val tvReturn: TextView = findViewById<TextView>(R.id.tvReturn)
            tvReturn.text = intent?.getStringExtra(REQUEST_RESULT) ?: "-1"
            Toast.makeText(
                this, "Greetings from event result handler! This was returned: ${tvReturn.text}",
                Toast.LENGTH_LONG
            ).show()
        }
    }

    companion object {
        const val REQUEST_RESULT: String = "REQUEST_RESULT"
    }

}

SecondActivity:

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
    }

    fun closeActivity(view: View) {
        injectIntent(42, true)
        finish()
    }

    fun injectIntent(value: Int, send: Boolean = false): Intent {
        val intent = Intent(this, MainActivity::class.java)
        intent.apply {
            putExtra(MainActivity.REQUEST_RESULT, value)
        }
        if (send) setResult(RESULT_OK, intent)
        return intent
    }

}

Now, I want to clarify that I cannot use the startActivityForResult version of this, as that is now deprecated.

What should I do to make this work? Am I missing something on the docs, because I've been staring at them for a week now, trying to get them to make sense.

UPDATE: I updated the kotlin files for the activities to better show what I'm doing or have done. Also, as per request, here's the TextView from the second activity that's controlling the return:

<TextView
        android:id="@ id/tvFinish"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="closeActivity"
        android:text="Close"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/llInput" />

and here's the one for MainActivity:

<TextView
        android:id="@ id/tvSwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickSwitchActivity"
        android:text="To Second Activity"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/llReturn" />

CodePudding user response:

After recreating your app, debugging it and confusing myself thoroughly, I have an answer. For what it's worth, here is a full, minimum, working example of what you're looking for.

Here's the bug:

  • SecondActivity is putting an int into the intent
  • MainActivity is calling getStringExtra

This will always return null, as there is no String extra with that key. getIntExtra is what you want.

CodePudding user response:

You are finishing the activity in closeActivity instead of finish() just call onBackPressed() in closeActivity it will work

  • Related