Search code examples
javaandroidandroid-intentonactivityresult

Android Studio, java, onActivityResult is not being triggered using Intent


I have two activities:

Activity #1: SetListMasterViewActivity

Activity #2: SetListOpenViewActivity

Activity #1 initially calls Activity #2 with Intent variables, and this works fine. Activity #1 contains a List of songs, when the user clicks on any song in the List, the song opens with all song lyrics in Activity #2. By pressing back within Activity #2 the user is again returned to the List in Activity #1 but this time the song previously viewed in Activity #2 is now highlighted (in the List within Activity #1).

It is when the user clicks "Back", from Activity #2 - sending the processing back to Activity #1 - that I have a problem. The logic is that, in Activity #2 the user is viewing the text of a song (song lyrics). When the user clicks "Back" button, the processing goes back to Activity #1 with the song that the user was viewing in Activity #2 is now highlighted within the List.

In Activity #2, within onCreate(), here is the code for the "Back" where I set the Intent:

        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int currentPosition = getCurrentPosition(songName, songsList);
                String currentSongName = songsList.get(currentPosition);
                int currentSongId = getSongIdByName(currentSongName);
                Intent resultIntent = new Intent();
                resultIntent.putExtra("lastViewedSongId", currentSongId);
                resultIntent.putExtra("lastViewedSongName", currentSongName);
                setResult(RESULT_OK, resultIntent);
                finish();
                startSetListMasterViewActivity();
            }
        });

After Intent is started, processing then continues to this method:

    private void startSetListMasterViewActivity() {
        Intent intent = new Intent(SetListOpenViewActivity.this, SetListMasterViewActivity.class);
        Log.d("SttList", "(SetListOpenViewActivity) line #194 - Launching SetListMasterViewActivity");
        setListMasterViewLauncher.launch(intent);
    }

Which invokes this method:

    private final ActivityResultLauncher<Intent> setListMasterViewLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                Log.d("SttList", "(SetListOpenViewActivity) line #208 - ActivityResultLauncher");
                if (result.getResultCode() == Activity.RESULT_OK) {
                    // ...
                }
            }
    );

Within Activity #1, this is where the Intent is received:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d("SttList", "(SetListMasterViewActivity) line #191 - onActivityResult called");
        Log.d("SttList", "(SetListMasterViewActivity) line #192 - requestCode: " + requestCode + ", resultCode: " + resultCode);
        if (requestCode == REQUEST_CODE_SET_LIST_MASTER && resultCode == RESULT_OK && data != null) {
            // Retrieve the last viewed song information from the Intent
            int lastViewedSongId = data.getIntExtra("lastViewedSongId", -1);
            String lastViewedSongName = data.getStringExtra("lastViewedSongName");

            // Find the position of the last viewed song in list of song names
            int position = songNames.indexOf(lastViewedSongName);
            // Log the received data
            Log.d("SttList", "(SetListMasterViewActivity) line #201 - Received lastViewedSongId: " + lastViewedSongId);
            Log.d("SttList", "(SetListMasterViewActivity) line #202 - Received lastViewedSongName: " + lastViewedSongName);

            // Highlight the song
            if (position != -1) {
                // Highlight the song at the found position
                TextView songTextView = (TextView) songsListView.getChildAt(position);
                songTextView.setBackgroundColor(Color.YELLOW);
            }
        }
    }

What happens is that Activity #1 opens however none of the Intents from Activity #2 are received. All the Log.d statements in onActivityResult are not run, so it seems that onActivityResult is skipped all together.

I have tried moving all code in onActivityResult into onResume - in Activity #1 - but find that the Intent is not received within onResume. I have looked at other problems posted but cannot find the issue I am facing.

What else I have tried:

  • setResult() is what you need for it to call onActivityResult() - yes I am using setResult()
  • In setResult I am using setResult(RESULT_OK, resultIntent);
  • originally I tried coding the Intent with startActivityForResult, which a lot of the older answers use, however this is depreciated with AS stating: 'startActivityForResult(android.content.Intent, int)' is deprecated

Solution

  • the parent activity (Activity #1) passes data to the child activity (Activity #2), and then the child activity passes data back to the parent activity.

    The important part is that the Activity Result API is only for returning a result - passing a result from your child activity back to your parent activity.

    That means that the parent activity is responsible for calling registerForActivityResult with the appropriate contract. It would include the information for the child activity as part of the Intent that you launch.

    Once the child activity is started, it has access to the information passed to it via the Intent extras and it calls setResult() to send information back - calling finish() to return to the parent activity.

    It is only when you return to the parent activity that the result -> lambda callback attached to that registerForActivityResult callback is triggered, returning the result.

    You do not override onActivityResult at all. You do not call startActivityForResult at all. The registerForActivityResult and calling launch on the returned ActivityResultLauncher is all you actually need to do on the parent activity side.