1

I am getting confused on how to return data back to the previous activity. Perhaps because of previous experience with old styles like windows forms in dot-net.

Scenario: my simple android app starts with the MainActivity, showing some values in some units, e.g. 'you are 1.86 m tall', and having a tools icon in the menu bar. Clicking this icon starts the ToolsActivity where the user may select some settings, like wether she prefers american or metric units, e.g. meter versus foot. When done, the user clicks the back arrow in the top bar to return to the MainActivity, that should show the values in the selected units.

This is how I store the current setting of the units system:

const val EXTRA_UNITSYSTEM = ".UNITSYSTEM"
class MainActivity : AppCompatActivity() {
    var TheUnitSystem : String = "metric"

I found out how to use putExtra() in the intent to startActivity() in the MainActivity to start the ToolsActivity,:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.tools -> {
            val intent = Intent(this, ToolsActivity::class.java)                 
            intent.putExtra(EXTRA_UNITSYSTEM, TheUnitSystem)
            startActivity(intent)

and getStringExtra() to get the current value of TheUnitSystem in the ToolsActivity so the radiobutton can be initialized to the current setting:

class ToolsActivity : AppCompatActivity() {
  var TheUnitSystem: String = ""

  override fun onCreate(savedInstanceState: Bundle?) {
    ...
    this.TheUnitSystem = intent.getStringExtra(EXTRA_UNITSYSTEM)!!

This actually works, but leaves the problem of how to return the data, which is possibly changed to point at another units system, back to the MainActivity when the ToolsActivity ends (or stops, or finishes, or gets destroyed...)

Initially, my guess was that intents are used to go to another activity, and that it needs another intent to go back to the previous activity.

Another guess was that you use EXTRA data on the intent to get data to ToolsActivity, so somehow the EXTRA data is also to be used to get data back to the MainActivity.

Both guesses seem to be naive.

Then I found out about starting the ToolsActivity with startActivityForResults(), as this is designed to get a result back from the second activity. However, the stories that I kind of grasp are in java, and the stories from developer.android.com that use kotlin are much more abstract and seem to describe yet different methods.

Can someone point me at a basic kotlin example for returning a simple String back to MainActivity, preferably using startActivityForResults() ?

From programming in simple Windows apps, I would guess that it would be even simpler to use application global (static) data. If that were possible, we should not need EXTRA stuff and special ForResult() methods, so perhaps this is also a dead end street?


extra info:

What may make my simple project a bit special is that I don't have a button in the layout of the second activity for going back to the MainActivity. The second activity is started from clicking a MenuItem on the Toolbar widget, defined in the res/menu/menu_main.xml layout. The second activity is shown with a back arrow in the top bar which is not in the layout of the second activity. Advantage is that it is really a Settings screen. Disadvantage is that it is not a plain normal activity where you put a back button in the layout like in most coding examples.

Roland
  • 4,619
  • 7
  • 49
  • 81

1 Answers1

3

You are on the right track, thinking about using startActivityForResults and I'm guessing all that is missing is connecting the original activity to receive results.

In the original activity you need to override onActivityResult like this:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    // If you have multiple activities returning results then you should include unique request codes for each 
    if (requestCode == <pick a code>) {

        // The result code from the activity started using startActivityForResults 
        if (resultCode == Activity.RESULT_OK) {
        }
    }
}

Then, in the activity you want to return information from, do something like this:

val intent = Intent()
intent.putExtra("ActivityResult", "<Data to return>")
setResult(RESULT_OK, intent)
finish()

This is one example, but they are all similar: Example

Kenneth Argo
  • 1,697
  • 12
  • 19
  • This helps, will try it. But where to put the second block of code, with the `setResullt` ? I would guess in the callback for the activity lifecycle event `stop`, or `destroy`. The code on the Example site is not indented, but it seems to implement a callback listener on some `Back` button. Is my project so special that I am using a 2nd actitivity started as a menu option, with an implicit back button, which is not in the Layout? – Roland Aug 13 '20 at 06:49
  • The example should help, but yes, the setResult() would be placed into the second activity (the one you want to send back information from). Hope this helps and if so please accept the answer. – Kenneth Argo Aug 13 '20 at 22:52
  • This answers the question, but leaves the problem of how to return from the 2nd activity to the 1st with an intent. That problem is solved by realizing that we don't need a 2nd activity at all. Just create menuitems for international versus american units and handle menuitem clicks in the same activity. No need to pass data to and from another activity. Works, and is simple. – Roland Aug 16 '20 at 00:03