onActivityResult is not being called in Fragment

后端 未结 30 2700
忘了有多久
忘了有多久 2020-11-21 04:28

The activity hosting this fragment has its onActivityResult called when the camera activity returns.

My fragment starts an activity for a result with th

相关标签:
30条回答
  • 2020-11-21 04:53

    Kotlin version for those who use Android Navigation Component inspired in Mohit Mehta's answer

     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach { fragment ->
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }
    
    0 讨论(0)
  • 2020-11-21 04:53

    With Android's Navigation component, this problem, when you have nested Fragments, could feel like an unsolvable mystery.

    Based on knowledge and inspiration from the following answers in this post, I managed to make up a simple solution that works:

    • Answer in this post
    • Answer in this post

    In your activity's onActivityResult(), you can loop through the active Fragments list that you get using the FragmentManager's getFragments() method.

    Please note that for you to do this, you need to be using the getSupportFragmentManager() or targeting API 26 and above.

    The idea here is to loop through the list checking the instance type of each Fragment in the list, using instanceof.

    While looping through this list of type Fragment is ideal, unfortunately, when you're using the Android Navigation Component, the list will only have one item, i.e. NavHostFragment.

    So now what? We need to get Fragments known to the NavHostFragment. NavHostFragment in itself is a Fragment. So using getChildFragmentManager().getFragments(), we once again get a List<Fragment> of Fragments known to our NavHostFragment. We loop through that list checking the instanceof each Fragment.

    Once we find our Fragment of interest in the list, we call its onActivityResult(), passing to it all the parameters that the Activity's onActivityResult() declares.

    //  Your activity's onActivityResult()
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            List<Fragment> lsActiveFragments = getSupportFragmentManager().getFragments();
            for (Fragment fragmentActive : lsActiveFragments) {
    
                if (fragmentActive instanceof NavHostFragment) {
    
                    List<Fragment> lsActiveSubFragments = fragmentActive.getChildFragmentManager().getFragments();
                    for (Fragment fragmentActiveSub : lsActiveSubFragments) {
    
                        if (fragmentActiveSub instanceof FragWeAreInterestedIn) {
                            fragmentActiveSub.onActivityResult(requestCode, resultCode, data);
                        }
    
                    }
    
                }
    
            }
    
        }

    0 讨论(0)
  • 2020-11-21 04:56
    1. You can simply override BaseActivity onActivityResult on fragment baseActivity.startActivityForResult .

    2. On BaseActivity add interface and override onActivityResult.

      private OnBaseActivityResult baseActivityResult;
      public static final int BASE_RESULT_RCODE = 111;
      public interface OnBaseActivityResult{
          void onBaseActivityResult(int requestCode, int resultCode, Intent data);
         }
      }
      
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if(getBaseActivityResult() !=null && requestCode == BASE_RESULT_RCODE){
          getBaseActivityResult().onBaseActivityResult(requestCode, resultCode, data);
          setBaseActivityResult(null);
      }
      
    3. On Fragment implements OnBaseActivityResult

      @Override
      public void onBaseActivityResult(int requestCode, int resultCode, Intent data) {
      Log.d("RQ","OnBaseActivityResult");
      if (data != null) {
          Log.d("RQ","OnBaseActivityResult + Data");
          Bundle arguments = data.getExtras();
        }
      }
      

    This workaround will do the trick.

    0 讨论(0)
  • 2020-11-21 04:57

    I'm having this same problem with the ChildFragmentManager. The manager will not pass the result to the nested fragment, you have to do that manually in your base fragment.

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
        if (fragment != null) {
            fragment.onActivityResult(requestCode, resultCode, intent);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 04:58

    My Problem was with the Host activity I found it with a set android:launchMode="standard" I removed it temporary an it work !

    0 讨论(0)
  • 2020-11-21 05:01

    This is one of the most popular issue. We can found lots of thread regarding this issue. But none of them is useful for ME.

    So I have solved this problem using this solution.

    Let's first understand why this is happening.

    We can call startActivityForResult directly from Fragment but actually mechanic behind are all handled by Activity.

    Once you call startActivityForResult from a Fragment, requestCode will be changed to attach Fragment's identity to the code. That will let Activity be able to track back that who send this request once result is received.

    Once Activity was navigated back, the result will be sent to Activity's onActivityResult with the modified requestCode which will be decoded to original requestCode + Fragment's identity. After that, Activity will send the Activity Result to that Fragment through onActivityResult. And it's all done.

    The problem is:

    Activity could send the result to only the Fragment that has been attached directly to Activity but not the nested one. That's the reason why onActivityResult of nested fragment would never been called no matter what.

    Solution:

    1) Start Intent in your Fragment by below code:

           /** Pass your fragment reference **/
           frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345
    

    2) Now in your Parent Activity override **onActivityResult() :**

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

    You have to call this in parent activity to make it work.

    3) In your fragment call:

    @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == Activity.RESULT_OK) {
    
           }
    }
    

    That's it. With this solution, it could be applied for any single fragment whether it is nested or not. And yes, it also covers all the case! Moreover, the codes are also nice and clean.

    0 讨论(0)
提交回复
热议问题