ActivityResultLauncher with Fragment - onActivityResult is not being called on return

Viewed 1003

app hierarchy

I hope the diagram above gives a rough idea of the current design hierarchy of my app. MainFragment shows the current account level of the user. There is a progression map with each section containing a list of tasks. User clicks a section, task list is displayed. For example, such task is to watch a video in its entirety. Once that's done, a level up dialog is displayed which is acknowledged by the user with a button click. The user is then returned to MainFragment with an update of the account level.

I created a test app beforehand to understand the basic functionality of ActivityResultLauncher since startActivityResult is now deprecated. The test app is a little different than the diagram for which instead of a fragment calling TaskList, it is an activity. It worked well nonetheless.

So now I am implementing it in my main project. The issue I am having is that while the launcher works correctly to launch the activity for a task, the onActivityResult in MainFragment is not being called. Is there something that I missed out?

Here is the ActivityResultLauncher code I am using in MainFragment. It is placed as a global variable.

ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            if (result.getResultCode() == VideoViewer.RESULT_OK) {
                // Level Up
                int level = result.getData().getIntExtra("level", 0);
                Toast.makeText(activity, "LEVEL UP! :D" + level + 1, Toast.LENGTH_SHORT).show();
                Log.i(TAG, "onActivityResult: Called");
            }
        }
    });

I then pass the launcher as a parameter into TaskListDialogFragment like so

TaskListDialog taskListDialog = new TaskListDialog(taskItemList.get(0), level, launcher);
taskListDialog.show(fm, "tasklist");

In TaskListDialog

// Constructor
public TaskListDialog(TaskItem taskItem, int level, ActivityResultLauncher<Intent> launcher) {
        this.taskItem = taskItem;
        this.level = level;
        this.launcher = launcher;
}

// Launch Intent section
Intent watchVideo = new Intent(TaskListDialog.this.getActivity(), VideoViewer.class);
watchVideo.putExtra("media", response.body());
launcher.launch(watchVideo);

In VideoViewer

// onButtonClick is from DialogListener Interface
@Override
public void onButtonClick() {
    // Task done. Return to MainFragment
    Intent levelReturn = new Intent();
    levelReturn.putExtra("level", accountLevel);
    setResult(VideoViewer.RESULT_OK, levelReturn);
    finish();
}

private void levelUp(int level) {
    FragmentManager fm = getSupportFragmentManager();
    LevelUpDialog levelUpDialog = new LevelUpDialog("Level Up!", level, taskItem);
    levelUpDialog.show(fm, "fragment_level_up");
}

In LevelUpDialog

public interface DialogListener {
    void onButtonClick();
}

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       // User acknowledges level up. Dismiss and return to MainFragment
       DialogListener dialogListener = (DialogListener) getActivity();
       assert dialogListener != null;
       dialogListener.onButtonClick();
       dismiss();
    }
});

EDIT UPDATE As stated in my comment reply, I missed out on an important difference between the test app and main project. The test app flow is Activity > DialogFragment > VideoViewer. Main project flow is Fragment > DialogFragment > PreviewActivity > VideoViewer. It worked when I removed PreviewActivity from the flow. However, I would like for the user to preview the task before doing it. I suppose the issue now is how can I retrieve the activity result after passing through multiple activities.

0 Answers
Related