Android Studio, java, onActivityResult не запускается с использованием намерения

У меня есть два вида деятельности:

Задание №1: SetListMasterViewActivity

Задание №2: SetListOpenViewActivity

Действие №1 изначально вызывает Действие №2 с переменными Intent, и это работает нормально. Задание №1 содержит List песен. Когда пользователь нажимает на любую песню в списке, песня открывается со всеми текстами песен из задания №2. Нажимая кнопку «Назад» в Действии № 2, пользователь снова возвращается к списку в Действии № 1, но на этот раз песня, ранее просматривавшаяся в Действии № 2, теперь выделяется (в списке в Действии № 1).

Когда пользователь нажимает "Back" из действия № 2 (отправка обработки обратно в действие № 1), у меня возникает проблема. Логика заключается в том, что в Упражнении №2 пользователь просматривает текст песни (текст песни). Когда пользователь нажимает кнопку "Back", обработка возвращается к действию № 1, и песня, которую пользователь просматривал в действии № 2, теперь выделена в списке.

В действии №2 внутри onCreate() приведен код "Back", где я установил намерение:

        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();
            }
        });

После запуска Intent обработка продолжается следующим методом:

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

Что вызывает этот метод:

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

В рамках действия № 1 здесь получен Intent:

    @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);
            }
        }
    }

Что происходит, так это то, что действие № 1 открывается, но ни одно из намерений из действия № 2 не получено. Все операторы Log.d в onActivityResult не выполняются, поэтому кажется, что onActivityResult пропускается целиком.

Я попытался переместить весь код из onActivityResult в onResume - в Упражнении № 1 - но обнаружил, что Intent не получен в onResume. Я просмотрел другие опубликованные проблемы, но не могу найти проблему, с которой столкнулся.

Что еще я пробовал:

  • setResult() - это то, что вам нужно, чтобы он позвонил onActivityResult() - да, я использую setResult()
  • В setResult я использую setResult(RESULT_OK, resultIntent);
  • изначально я пытался закодировать намерение с помощью startActivityForResult, который используется во многих старых ответах, однако это обесценивается, поскольку AS заявляет: 'startActivityForResult(android.content.Intent, int)' is deprecated

Меня немного смущает ваш поток данных между действиями. API результатов действий предназначен для возврата результатов к предыдущему действию, но вы, кажется, используете его, чтобы попытаться передать результаты в новое действие?

ianhanniballake 28.02.2024 04:12

Спасибо за ваше наблюдение @ianhanniballake — родительское действие (действие № 1) передает данные дочернему действию (действие № 2), а затем дочернее действие передает данные обратно родительскому действию. Я не начинаю новую деятельность – нет необходимости начинать новую деятельность; вместо этого я просто возвращаю данные родительскому действию.

kiteandwindsurfer 28.02.2024 06:08

Я возвращаюсь к родителю и не начинаю новую деятельность – это было залогом движения вперед. Я считаю, что проблема была решена путем изменения способа реализации дочерней активности и использования ActivityResultLauncher. После кодирования все работает! @ianhanniballake, твой комментарий помог мне пойти по абсолютно правильному пути. Если вы отправите свой комментарий в качестве ответа, я отдам вам должное и закрою это дело. Большое спасибо за помощь!

kiteandwindsurfer 28.02.2024 06:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
129
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

родительское действие (действие № 1) передает данные дочернему действию (действие № 2), а затем дочернее действие передает данные обратно родительскому действию.

Важная часть заключается в том, что API результатов активности предназначен только для возврата результата — передачи результата из вашей дочерней активности обратно в родительскую активность.

Это означает, что родительская активность отвечает за вызов registerForActivityResult с соответствующим контрактом. Он будет включать информацию о дочерней активности как часть Intent, которую вы запускаете.

Как только дочернее действие запускается, оно получает доступ к информации, переданной ему через дополнительные функции Intent, и вызывает setResult(), чтобы отправить информацию обратно, — вызывает finish(), чтобы вернуться к родительскому действию.

Только когда вы возвращаетесь к родительской активности, срабатывает обратный вызов result -> лямбда, прикрепленный к этому обратному вызову registerForActivityResult, возвращая результат.

Вы вообще не переопределяете onActivityResult. Вы вообще не звоните startActivityForResult. registerForActivityResult и вызов launch по возвращенному ActivityResultLauncher — это все, что вам действительно нужно сделать на стороне родительской активности.

В моем случае мой вызов startActivityForResult(intent, code); Ничего не сделал. Но я заметил, что это произошло потому, что в AndroidManifest я объявлял android:parentActivityName, поэтому действие, которое я пытался запустить, было проигнорировано, поскольку имя действия, объявленное в манифесте, было другим.

Ezequiel Adrian 27.03.2024 23:03

Другие вопросы по теме