onActivityResult не вызывается во фрагменте - PullRequest
797 голосов
/ 27 мая 2011

Активности, в которой размещен этот фрагмент, вызывается onActivityResult, когда возвращается активность камеры.

Мой фрагмент запускает действие для результата с намерением, посланным камерой, чтобы сделать снимок. Приложение для работы с изображениями загружается нормально, делает снимок и возвращается. Однако onActivityResult никогда не попадает в цель. Я установил точки останова, но ничего не сработало. Может ли фрагмент иметь onActivityResult? Я бы так подумал, поскольку это предоставленная функция. Почему это не срабатывает?

ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, 1888);
    }
});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( requestCode == 1888 ) {
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
    }
}

Ответы [ 32 ]

1 голос
/ 23 ноября 2014

Ваш код имеет вложенный фрагмент. Вызов super.onActivityForResult не работает

Вы не хотите изменять каждое действие, из которого может быть вызван ваш фрагмент, или выполнять обход всех фрагментов в цепочке фрагментов.

Вот одно из многих работающих решений. создайте фрагмент на лету и подключите его непосредственно к операции с помощью менеджера фрагментов поддержки. Затем вызовите startActivityForResult из вновь созданного фрагмента.

private void get_UserEmail() {

    if (view == null) {
        return;
    }
    ((TextView) view.findViewById(R.id.tvApplicationUserName))
            .setText("Searching device for user accounts...");

    final FragmentManager fragManager = getActivity().getSupportFragmentManager();

    Fragment f = new Fragment() {
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            startActivityForResult(AccountPicker.newChooseAccountIntent(null, null,
                    new String[]{"com.google"}, false, null, null, null, null), REQUEST_CODE_PICK_ACCOUNT);
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                                     Intent data) {
            if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
                String mEmail = "";
                if (resultCode == Activity.RESULT_OK) {
                    if (data.hasExtra(AccountManager.KEY_ACCOUNT_NAME)) {
                        mEmail = data
                                .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                    }
                }
                if (mActivity != null) {
                    GoPreferences.putString(mActivity, SettingApplication.USER_EMAIL, mEmail);
                }
                doUser();
            }
            super.onActivityResult(requestCode, resultCode, data);
            fragManager.beginTransaction().remove(this).commit();
        }
    };
    FragmentTransaction fragmentTransaction = fragManager
            .beginTransaction();
    fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
    fragmentTransaction.commit();
}
1 голос
/ 15 сентября 2014

У меня есть сильное подозрение, что все ответы здесь - не более чем взломы. Я перепробовал их всех и многих других, но без какого-либо достоверного заключения, поскольку всегда есть какая-то глупая проблема. Я, например, не могу полагаться на противоречивые результаты. Если вы посмотрите официальную документацию по Android API для фрагментов, вы увидите, что Google четко заявляет следующее:

Вызовите startActivityForResult (Intent, int) из фрагмента, содержащего Activity.

См .: API фрагментов Android

Таким образом, наиболее правильным и надежным подходом было бы на самом деле вызвать startActivityForResult () из действия хостинга, а также обработать итоговую onActivityResult () оттуда.

1 голос
/ 16 ноября 2015

Если вы используете вложенные фрагменты, это также работает:

getParentFragment().startActivityForResult(intent, RequestCode);

В дополнение к этому вы должны вызвать super.onActivityResult из родительского действия и заполнить метод onActivityResult фрагмента.

1 голос
/ 23 июня 2016

Моя проблема была связана с активностью хоста. Я нашел его с набором android:launchMode="standard" Я удалил его временно и он работает!

1 голос
/ 10 июня 2014

Как упоминал Олли С, существует активная ошибка для библиотеки поддержки, использующей возвращаемые значения для onActivityResult, когда вы используете вложенные фрагменты. Я просто ударил: - (.

См. Fragment.onActivityResult не вызывается, когда requestCode! = 0 .

0 голосов
/ 20 февраля 2012

Я обработал проблему, написав базовый класс, который расширяет Fragment, и в onactivityresult операции я определил текущий запущенный фрагмент, используя fragmenttag.Затем я вызываю пользовательский метод в классе фрагмента.Это вызовет событие в текущем фрагменте.

0 голосов
/ 04 августа 2016

В одной точке никто не имеет mention, которая гарантирует, что ваша активность хоста режим запуска не должна быть установлена ​​на singleInstance или singleTask.

onActivityResultне будет работать, если ваш режим запуска установлен на SingleInstance или SingleTask.или вы вызываете свою деятельность с помощью этих IntentFilters

standard или singleTop режим запуска будет работать нормально.

0 голосов
/ 30 мая 2016

Один из самых простых способов - начать действие с вашего фрагмента.

startActivity(ActivityName);

Затем добавьте ваш звонок startActivityForResult(intent,"1"); из вашей активности и добавьте onActivityResult в вашу активность

startActivityForResult(intent,"1");

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
// perform other activity result like fetching from Uris or handling cursors

finish(); // finish the activity will  get to back to your fragment.
}
0 голосов
/ 05 мая 2016

Если есть проблема с методом onActivityResult, который находится внутри класса фрагмента, и вы хотите обновить что-то, что также находится внутри класса фрагмента, используйте:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(resultCode == Activity.RESULT_OK)
    {
        // If the user had agreed to enabling Bluetooth,
        // populate the ListView with all the paired devices.
        this.arrayDevice = new ArrayAdapter<String>(this.getContext(), R.layout.device_item);
        for(BluetoothDevice bd : this.btService.btAdapater.getBondedDevices())
        {
            this.arrayDevice.add(bd.getAddress());
            this.btDeviceList.setAdapter(this.arrayDevice);
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Просто добавьте this.variable, как показано в коде выше. В противном случае метод будет вызван в родительском действии, и переменная не будет обновлена ​​для текущего экземпляра.

Я также проверил это, поместив этот блок кода в MainActivity, заменив this классом HomeFragment и установив переменные статическими. Я получил результаты, как и ожидал.

Так что, если вы хотите, чтобы класс фрагмента имел собственную реализацию onActivityResult, ответом является приведенный выше пример кода.

0 голосов
/ 06 ноября 2013

Я просто использую метод обхода:

public static Fragment _tempFragment = null;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(_tempFragment != null)
        _tempFragment.onActivityResult(requestCode, resultCode, data);
}

В вашем Фрагменте перед startActivityResult установите

MainActivity._tempFragment = this;

После onActivityResult <- во Фрагменте </p>

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);

     // Do your job
     {

     }
     MainActivity._tempFragment = null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...