6

I am working in Fragment in which I need to select an image from gallery and set it to an imageView but getActivity().startActivityForResult() is now working

I have already checked many Links but all are saying that call this method in parent activity but I dont have any parent activity as this fragment is inside a another fragment. I have checked this link too

startActivityForResult is not working in Fragment

Here is my code :-

MainActivity Class:-

public class SabaKuchHomeActivity extends FragmentActivity {

private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

// nav drawer title
private CharSequence mDrawerTitle;

// used to store app title
private CharSequence mTitle;

// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;

private ArrayList<NavDrawerItem> navDrawerItems=new ArrayList<NavDrawerItem>();
private NavDrawerListAdapter adapter;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    setContentView(R.layout.home_activity);
    mTitle = mDrawerTitle = getTitle();


    // load slide menu items
    navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

    // nav drawer icons from resources
    navMenuIcons = getResources()
            .obtainTypedArray(R.array.nav_drawer_icons);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

    // adding nav drawer items to array
            // Home
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
            // Find People
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
            // Photos
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
            // Communities, Will add a counter here
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1), true, "22"));
            // Pages
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
            // What's hot, We  will add a counter here
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));
            navDrawerItems.add(new NavDrawerItem(navMenuTitles[6], navMenuIcons.getResourceId(6, -1)));

            // Recycle the typed array
            navMenuIcons.recycle();

            mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

            // setting the nav drawer list adapter
            adapter = new NavDrawerListAdapter(getApplicationContext(),
                    navDrawerItems);
            mDrawerList.setAdapter(adapter);

            // enabling action bar app icon and behaving it as toggle button
            getActionBar().setDisplayHomeAsUpEnabled(true);
            getActionBar().setHomeButtonEnabled(true);
            //getActionBar().setDisplayShowHomeEnabled(false);


            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                    R.drawable.ic_drawer, //nav menu toggle icon
                    R.string.app_name, // nav drawer open - description for accessibility
                    R.string.app_name // nav drawer close - description for accessibility
            ) {
                @TargetApi(Build.VERSION_CODES.HONEYCOMB)
                public void onDrawerClosed(View view) {
                    getActionBar().setTitle(mTitle);
                    //getActionBar().show();
                    // calling onPrepareOptionsMenu() to show action bar icons
                    invalidateOptionsMenu();
                }

                public void onDrawerOpened(View drawerView) {
                    getActionBar().setTitle(mDrawerTitle);
                    // calling onPrepareOptionsMenu() to hide action bar icons
                    //getActionBar().hide();
                    invalidateOptionsMenu();
                }
            };
            mDrawerLayout.setDrawerListener(mDrawerToggle);

            if (savedInstanceState == null) {
                // on first time display view for first nav item
                displayView(0);
            }
        }

        /**
         * Slide menu item click listener
         * */
        private class SlideMenuClickListener implements
                ListView.OnItemClickListener {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                // display view for selected nav drawer item
                displayView(position);
            }
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // toggle nav drawer on selecting action bar app icon/title
            if (mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            // Handle action bar actions click
            switch (item.getItemId()) {
            case R.id.action_search:

                Intent TrendIntent = new Intent(SabaKuchHomeActivity.this,TrendsActivity.class);
                startActivity(TrendIntent);

                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }

        /* *
         * Called when invalidateOptionsMenu() is triggered
         */
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public boolean onPrepareOptionsMenu(Menu menu) {
            // if nav drawer is opened, hide the action items
            boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
            menu.findItem(R.id.action_search).setVisible(!drawerOpen);
            return super.onPrepareOptionsMenu(menu);
        }

        /**
         * Diplaying fragment view for selected nav drawer list item
         * */


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
private void displayView(int position) {
    // update the main content by replacing fragments
    android.support.v4.app.Fragment fragment = null;
    switch (position) {
    case 0:
        fragment = new OzoneFragment();
        break;
    case 1:
        fragment = new MyZoneFragment();
        break;
    case 2:
        fragment = new BizZoneFragment();
        break;
    case 3:
        fragment = new EventsFragment();
        break;
    case 4:
        fragment = new PrivacySettingFragment();
        break;
    case 5:
        fragment = new ProfileSettingFragment(); ***This is the fragment where I am moving now***
        break;

    case 6:

        AppContoller.getInstance().pref=getSharedPreferences(AppContoller.getInstance().PREF_NAME, 0);
        Editor editer=AppContoller.getInstance().pref.edit();
        editer.putString(AppContoller.getInstance().USER_ID, "0");
        editer.commit();

        finish();

        break ;

    default:
        break;
    }

    if (fragment != null) {
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();

        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getActionBar().setTitle(mTitle);
}

/**
 * When using the ActionBarDrawerToggle, you must call it during
 * onPostCreate() and onConfigurationChanged()...
 */

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);
}

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

}

here is ProfileSettingFragment() fragment :-

 @SuppressLint("NewApi")
public class ProfileSettingFragment extends android.support.v4.app.Fragment implements TabListener {

private ViewPager mPager;
private MyPageAdapter adapter;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
         View rootView = inflater.inflate(R.layout.profile_setting_fragment, container, false);

         mPager=(ViewPager)rootView.findViewById(R.id.pager);

            mPager.setOffscreenPageLimit(5);
            adapter=new MyPageAdapter(getChildFragmentManager());
            mPager.setAdapter(adapter);


            TabPageIndicator indicater=(TabPageIndicator)rootView.findViewById(R.id.indicator1);
            indicater.setViewPager(mPager);

            indicater.setOnPageChangeListener(new OnPageChangeListener() {

                @Override
                public void onPageSelected(int arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrollStateChanged(int arg0) {
                    // TODO Auto-generated method stub

                }
            });

            /*mPager.setOnPageChangeListener(new OnPageChangeListener() {

                @Override
                public void onPageSelected(int position) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onPageScrollStateChanged(int arg0) {
                    // TODO Auto-generated method stub

                }
            });*/

            /*actionBar.addTab(actionBar.newTab().setText("Home").setTabListener(this));
            actionBar.addTab(actionBar.newTab().setText("MiZone").setTabListener(this));
            actionBar.addTab(actionBar.newTab().setText("Top Trending").setTabListener(this));
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);*/

            return rootView;
    }

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

    private class MyPageAdapter extends FragmentStatePagerAdapter
       {
            private List<android.support.v4.app.Fragment> fragments;

        public MyPageAdapter(FragmentManager fm) {
            super(fm);
            // TODO Auto-generated constructor stub
            this.fragments=new ArrayList<android.support.v4.app.Fragment>();
            fragments.add(new ProfileGeneralSetting());
            fragments.add(new ProfileOzoneSetting());
            fragments.add(new ProfileMyzoneSetting());
            fragments.add(new ProfileBizzoneSetting());
            fragments.add(new ProfilePasswordSetting());

        }

        @Override
        public android.support.v4.app.Fragment getItem(int arg0) {
            // TODO Auto-generated method stub
            return fragments.get(arg0);
        }

        @Override
        public CharSequence getPageTitle(int position) {
        // TODO Auto-generated method stub
             switch (position) {
                case 0:
                    return "General";
                case 1:
                    return "Ozone";
                case 2:
                    return "MyZone";
                case 3:
                    return "Biz Zone";
                case 4 :
                    return "Password Setting";
            }
             return null;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return fragments.size();
        }

       }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
        mPager.setCurrentItem(tab.getPosition());

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

}

here is Nested Fragment from where I have to change the image :-

public class ProfileOzoneSetting extends Fragment implements MiFeelingBase, OnClickListener{

 NetworkImageView genSetOzoneUserImage;

 private ArrayList<String>arrCategoryId=new ArrayList<String>();
 List<String> interestList = new ArrayList<String>();
 String[] interest;
 Boolean setImg ;


 private static final int SELECT_PICTURE = 1;
 private String selectedImagePath;


 Button SettingOzSave;
 private MultipartEntity reqEntity;

 String[] y ={""};


 private String strUserID;
 ImageLoader imageLoader = AppContoller.getInstance().getImageLoader();

 OzoneSettingData ozSettingList = new OzoneSettingData();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    View rootView = inflater.inflate(R.layout.profiesettingozone, container, false);


    genSetOzoneUserImage = (NetworkImageView)rootView.findViewById(R.id.genSetOzoneUserImage);

    SettingOzSave = (Button)rootView.findViewById(R.id.SettingOzSave);

    SettingOzSave.setOnClickListener(this);

    genSetOzoneUserImage.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Log.d("first time", "before method");

            Intent intent  = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
        //startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);

            Log.d("first time", "before method11");
            //startActivityForResult(intent, SELECT_PICTURE);
            getParentFragment().startActivityForResult(intent, SELECT_PICTURE);
            //startActivityForResult(intent, SELECT_PICTURE);
            //((SabaKuchHomeActivity)getActivity()).startActivitForResult(intent, SELECT_PICTURE);
            //getContext().getApplicationContext.startActivityforResult(intent, SELECT_PICTURE);
            //fragment.getApplicationContext.startActivityforResult(intent, SELECT_PICTURE);
            //getActivity().startActivityForResult(intent, SELECT_PICTURE);
            //startActivityForResult(intent, SELECT_PICTURE);
            //((SabaKuchHomeActivity)getActivity()).startActivitForResult(intent, SELECT_PICTURE);

            Log.d("first time", "before method22");

        }
    });


    APIAccess.fetchData(ProfileOzoneSetting.this, getActivity(), getActivity());
    return rootView;
}
@Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {


    Log.d("first time", "before method33");
      super.onActivityResult(requestCode, resultCode, data);

        Log.d("first time", "before method44");

        if (requestCode == SELECT_PICTURE && resultCode ==Activity.RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            Cursor cursor = getActivity().getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
            genSetOzoneUserImage.setImageBitmap(BitmapFactory.decodeFile(picturePath));

            setImg = true;
         }
          }

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
     AppContoller.getInstance().pref=getActivity().getSharedPreferences(AppContoller.getInstance().PREF_NAME, 0);



@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = getActivity().managedQuery(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

Please let me know what mistake I am doing here???

Update

I did update SabaKuchHomeActivity and ProfileSettingFragment

Community
  • 1
  • 1
Devraj
  • 1,479
  • 1
  • 22
  • 42
  • Just print something in Log on onClick of your button – Piyush Jul 30 '15 at 07:18
  • Try to cast your `getActivity()` to the parent activity. e.g `((YourActivityClasss)getActivity()).startActivitForResult();` – Prerak Sola Jul 30 '15 at 07:18
  • The fragment is inside another fragment?? How did you initialize both the parent and child fragments?? – Olayinka Jul 30 '15 at 07:22
  • what is your parent fragment(Is it activty or FragmentActivity). From where you called this fragment. You need to ovveride onActivityResult in your Parent Activity or Fragment Activity. – RamBabu Pudari Jul 30 '15 at 07:23
  • What exactly not working?! does it crash? -1 – hasan Jul 30 '15 at 08:10
  • @PiyushGupta yes I have tried to print Log before and after onActivityforResult() and that's how I came to know that this method is not calling. – Devraj Jul 30 '15 at 08:11
  • Means log is not printing ?? @Devraj – Piyush Jul 30 '15 at 08:12
  • @RamBabuPudari my parent activity in neither Activity nor ActivityFragment. It is Fragment as I have mentioned in question too. check my updated question. – Devraj Jul 30 '15 at 08:17
  • @Olayinka please chk my updated question – Devraj Jul 30 '15 at 08:19
  • @hasan83 no crashes, no error in Logcat. when I select the image from gallery, It doesn't set it to the imageview. – Devraj Jul 30 '15 at 08:20
  • @PrerakSola tried, Not working. – Devraj Jul 30 '15 at 08:21
  • 1
    look at @vilpe89 answer – Olayinka Jul 30 '15 at 08:23
  • @PiyushGupta only the log before onActivityforResult() is printing, but not Inside that. – Devraj Jul 30 '15 at 08:24
  • Just take a look at my answer already and stop spamming comments – vilpe89 Jul 30 '15 at 08:27
  • @vilpe89 look prerakSola's comment here plzzz... – Devraj Jul 30 '15 at 08:32
  • @Devraj that doesn't do any difference, that would still launch it from Activity, not from Fragment. – vilpe89 Jul 30 '15 at 08:38
  • 1
    @Devraj even parent fragment also from where you are calling.it should be Activity or Fragment Activity.There Override the OnActvityResult – RamBabu Pudari Jul 30 '15 at 08:51
  • @Devraj fyi,there must be an Activity which contains all these fragments, I would suggest use of interface methods to communicate to your activity and vice-versa . By this call the startActivityForResult method in activity and get the result passed to your fragment. – Amar Aug 28 '15 at 09:13
  • you have no Activity? FragmentActivity? really? and you are surprised at this? SIr? I'm i missing something? uhhhmm???? – Elltz Aug 30 '15 at 06:16
  • @Elltz no one can use fragment without activity. But I think you are not getting my question. This is nested fragment (Activity-->fragment-->fragment) and I have tried almost every method people suggested me here. – Devraj Sep 01 '15 at 06:35
  • Sir, try this, instead of relying on the nested child fragment for the activityonresult, instead create an interface between your pager fragment or direct fragment and the child fragment, after, let the direct fragment listen to the onactivityresult then pass it through the interface and send it to the respective inner child fragment. let me know if it makes sense to you. so i can go further for a demo, also lets try & do that in less than 20 hours :-) – Elltz Sep 03 '15 at 09:56
  • 1
    @Elltz yes sure... even I am trying to do this too but getting confused as I have done so much coding, now my brain is chocked... lolzz.. plzz provide me some demo. It would be very helpful. :) – Devraj Sep 03 '15 at 10:23

14 Answers14

9

The problem is that you are implementing onActivityResult in your Fragment and calling getActivity().startActivityForResult(...). Because you are launching Activity from Activity, the onActivityResult(...) method call goes to the Activity that launches new Activity.

So all you need to do is remove the getActivity() part and your onActivityResult(...) will be called in your Fragment!

EDIT: As you can see from GrepCode, the code in Fragment's startActivityForResult is different from Activity's startActivityForResult. That sure ain't coincidence....

vilpe89
  • 4,656
  • 1
  • 29
  • 36
  • Ok, then the problem is somewhere else... Have you tried to put logging or break point to debug onActivityResult method when you have removed the getActivity() part? Remove the getActivity() part and put something before **if (resultCode == Activity.RESULT_OK) {** code line. I think **resultCode** is NOT Activity.RESULT_OK :) – vilpe89 Jul 30 '15 at 08:33
  • One way to make sure where the calls stop is to put **onActivityResult** also in your Activity and parent Fragment, then put some Log code there and watch what happens! – vilpe89 Jul 30 '15 at 08:44
  • Yes I have tried this too... also updated my question according to your suggestion – Devraj Jul 30 '15 at 09:09
  • I dont have any activity or fragmentActivity to hold this fragment. It is also a fragment holding this fragment. – Devraj Jul 30 '15 at 09:35
  • 1
    every UI component is contained by an activity – user3290180 Jul 31 '15 at 08:09
6

You should not use

getActivity().startActivityForResult(...)

Simply use

startActivityForResult(...)

This way the onActivityResult in your fragment will be called.

Piyush
  • 18,895
  • 5
  • 32
  • 63
apals
  • 291
  • 1
  • 3
1

This is discussed in detail here and blogged about here and there is a bug report about it here.

The short version is: This is broken for nested fragements and you have to write your own workaround.

My suggestion would be to in your child fragment call:

getParentFragment().startActivityForResult(....)

and in your parent Fragment override onActivityResult and replay the call to your child fragments:

...
for (Fragment child : getChildFragmentManager().getFragments()) {
   child.onActivityResult(requestCode, resultCode, data);
}
...
Community
  • 1
  • 1
Espen Riskedal
  • 1,425
  • 15
  • 28
1

Give it a try, When you call startActivityForResult(), onActivityResult() of the Activity is first called then onActivityResult() of its fragment is called but this call is not given to the nested fragment. So in onActivityResult() of your fragment you will have to get the current loaded fragment somehow, typecast it if needed and then call a method written inside it to which you pass whatever you get OnActivityResult().

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

  // notifying nested fragments (support library bug fix)
  final FragmentManager childFragmentManager = getChildFragmentManager();

  if (childFragmentManager != null) {
    final List < Fragment > nestedFragments = childFragmentManager.getFragments();

    if (nestedFragments == null || nestedFragments.size() == 0) return;

    for (Fragment childFragment: nestedFragments) {
      if (childFragment != null && !childFragment.isDetached() && !childFragment.isRemoving()) {
        childFragment.onActivityResult(requestCode, resultCode, data);
      }
    }
  }
}

Code in your fragment's onActivityResult() would look something like, Try to get the fragment from fragmentManager or with the help of your viewPagerAdapter Also try to call startActivityForResult as,

fragment.getParentFragment().startActivityForResult();

instead of

fragment.startActivityForResult();

Put this in your outer fragment to access the current loaded fragment,

MyFragment myFragment = (MyFragment)pagerAdapter.getCurrentFragment();
myFragment.myMethod();

And the below code in the adapter which will return the current fragment loaded, remember below is just for you to understand, use it in your code accordingly

Fragment fragment;

@Override
public Fragment getItem(int index) {
    fragment = new FragFilter();
    return fragment;
}

public Fragment getCurrentFragment() {
    return this.fragment;
}
RevanthKrishnaKumar V.
  • 1,855
  • 1
  • 21
  • 34
Rohit Jagtap
  • 1,660
  • 1
  • 14
  • 12
  • did u put this? fragment.getParentFragment().startActivityForResult(); instead of fragment.startActivityForResult(); – Rohit Jagtap Sep 01 '15 at 13:13
  • yes I tried...it started giving error "fragment cannot be resolved" on "fragment". and ask to change Fragment(support.android.v4.app). and when I change it, it gives error in whole line.."Cannot make a static reference to the non-static method getParentFragment() from the type Fragment" – Devraj Sep 02 '15 at 05:33
  • try to get the fragment from the pagerAdapter and then typecast it and call it's method – Rohit Jagtap Sep 02 '15 at 05:42
  • I am sorry, but I am not able to fragment from pagerAdapter, please tell me, – Devraj Sep 02 '15 at 06:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88536/discussion-between-r-j-and-devraj). – Rohit Jagtap Sep 02 '15 at 06:18
1

Remove

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

in your activity and first fragment and maintain this in your nested fragment

and Even if not worked pass your activity instance while intializing fragment as

fragment = new ProfileSettingFragment(activity);

and create a constructor in fragment what your using with activity instance then you can call onActivityResult in main activity and can get data form that activity as you are passing activity reference while initializing your fragment.

You can create an interface which have a method will return a string and by implementing that in your activity you can receive the data through over where your activity reference available.

King of Masses
  • 18,405
  • 4
  • 60
  • 77
0

For some reason when you startActivityForResult from

android.support.v4.app.Fragment

wont work, it will go to your Activities onActivityResult. If you use

android.app.Fragment

it will work and return to your onActivityResult in Fragment.

Jason
  • 231
  • 3
  • 14
  • Jason, Thank you for you effort, May be you are right but I cannot change v4.app.fragment into android.app.fragment because I am using viewPager that uses v4 support lib and if I replace this, I get errors in all the fragment objects, classes, constructor etc. please help me to sort out this issue. – Devraj Sep 01 '15 at 06:40
  • if you need v4 fragment, what I did in one of my projects is; all fragments extends BaseFragment and base has a function called onResult. So now when onResut is called in Activity y pass the info to this function onResult in fragment and the only thing you need is @override this function in each individual fragment. – Jason Sep 01 '15 at 07:54
  • Jason, please check my updated question. I have added my main activity class too. – Devraj Sep 01 '15 at 09:15
0

Although i didn't test your code. I am writing this answer on my behalf.

getActivity.startActivityForResult(...)

should call Activity onActivityResult.

getParentFragment().onActivityResult(...)

should call onActivityResult in your parent fragment.

And

this.onActivityResult(...)

should should call your current fragment onActivityResult() method.

you can try these keyword as mentioned here. In case you still face problem let me know i'll a code sample on GIT

Ankur Chaudhary
  • 2,709
  • 3
  • 19
  • 30
0

try this:

getContext().getApplicationContext.startActivityforResult();
  • Asking to create a method 'getContext()' in class. and after creating that, 'getApplicationContext' gives error "getApplicationContext cannot be resolved or is not a field" – Devraj Sep 01 '15 at 09:24
  • @Devraj you can use `v.getApplicationContext.startActivityforResult();` too, actually use (View v) –  Sep 01 '15 at 18:45
  • heyi Milad, I really appreciate that you are giving your 100% but brother using v.getApplicationContext.startActivityforResult() also gives error that "getApplicationContext cannot be resolved or is not a field" – Devraj Sep 02 '15 at 05:37
0

override onActivityResult in your SabaKuchHomeActivity use

public void dispatchTakePictureIntent() {
        final int TAKE_PHOTO_RESULT_CODE = 2345;
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent
                .resolveActivity(getActivity().getPackageManager()) != null)
            if (getParentFragment() != null)
                getParentFragment().startActivityForResult(takePictureIntent, TAKE_PHOTO_RESULT_CODE);
            else
                startActivityForResult(takePictureIntent, TAKE_PHOTO_RESULT_CODE);
    }

    public void dispatchChoosePictureIntent() {
        final int CHOOSE_PHOTO_RESULT_CODE = 1234;
        Intent intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        if (getParentFragment() != null)
            getParentFragment().startActivityForResult(Intent.createChooser(intent, "Choose Picture"),
                    CHOOSE_PHOTO_RESULT_CODE);
        else
            startActivityForResult(Intent.createChooser(intent, "Choose Picture"),
                    CHOOSE_PHOTO_RESULT_CODE);
    }

Use getParentFragment() if you are using custom fragment or/and viewpager, otherwise igonre/remove getParentFragment()

Haris Qurashi
  • 2,104
  • 1
  • 13
  • 28
  • why you are creating dispatchChoosePictureIntent() two times in a single class???? – Devraj Sep 01 '15 at 11:21
  • read code carefully one method is for capture picture, other for select from gallery – Haris Qurashi Sep 01 '15 at 11:23
  • yeah... I came to know after few seconds of posting comment. My question is, I tried getParentFragment() but it makes no change. and how can I override onActivityResult() in SabaKuchHomeActivity. can you please make that change in my code?? – Devraj Sep 01 '15 at 11:33
  • i did update your question, run your project, add breakpoint in onActivityResult inside your activity and fragment, and see what happens – Haris Qurashi Sep 01 '15 at 11:45
  • Do insert above methods in your code and call any one of them, – Haris Qurashi Sep 01 '15 at 11:51
  • I did, But not working. same result as before. :'( I think no can resolve this issue.. :( – Devraj Sep 01 '15 at 12:09
  • i did solved this issue same as i told you, may be you are missing something, which isn't described here, otherwise above works fine – Haris Qurashi Sep 01 '15 at 12:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88478/discussion-between-haris-qureshi-and-devraj). – Haris Qurashi Sep 01 '15 at 12:14
0

Simple solution just call the startActivityForResult(/* … */) only and onActivityResult(/* … */) in your fragment will be called. I usually use this.

MUHAMMAD WASIM
  • 191
  • 2
  • 11
0

we can also implement onActivityResult() in your Fragment as well.

so dear for your code just remove getActivity. from getActivity.startActivityForResult(...) then it will calls onActivityResult() of your fragment. for more information see this link. enjoy your code:)

Community
  • 1
  • 1
John smith
  • 1,781
  • 17
  • 27
  • this is the first thing I tried before posting the question here... :P not working bro... also I have no errors in logcat but a warning is there "Activity result fragment index out of range: 0x20001" – Devraj Sep 03 '15 at 06:44
0

It became a longer code ,i will just do a brief walkthrough -(since its a bounty) and that's all. here is the xml i used. the rest java

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/rumorsapp.ghaweek"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="rumorsapp.ghaweek.MainActivity" >

<android.support.design.widget.TabLayout
    android:id="@+id/tablayou"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:background="#ff9900"
    android:minHeight="50dp"
    app:tabIndicatorColor="#f09"
    app:tabMode="scrollable"
    app:tabPadding="10dp"
    app:tabSelectedTextColor="#004"
    app:tabTextColor="#fff" >
</android.support.design.widget.TabLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_marginTop="2dp"
    android:layout_below="@+id/tablayou"
    android:layout_height="match_parent"/>
</RelativeLayout>

All i did to make it work was create an interface called ActivityResHan which simply had a method called initiate(String fragmentTag); (my names are poor -i know) the logic was to have my direct Fragment -(fragment containing the viewpager or the Child that fornicated and has kids) implement this ActivityResHan interface

class ViewPagerFragment extends Fragment implements ActivityResHan{

which was to going to call the startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); to retrieve a Contact from the content provider.

@Override
    public void initiate(String fragmentTag) {
        calleer = fragmentTag; //this calleer saves the tag
        Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
        pickContactIntent.setType(Phone.CONTENT_TYPE);
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
    }

This direct-Fragment's onActivityResult checks if calleer is empty -(i hope you have already met calleer) if its not then it calls the onActivityResultfor his/her children, and it recognises its children by Tag, through FragmentManager.findFragmentByTag(); that's where calleer comes in

and now Every Child of the direct-Fragment, when it needs to start an activity for result just finds the direct-Fragment by Tag -(viewpageframent) and then cast that Fragment to ActivityResHan and calls initiate(fragmentTag);

((ActivityResHan)getActivity().getSupportFragmentManager().
                            findFragmentByTag("viewpageframent")).initiate(getTag());

The rest of the codes makes it all happen.

import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.design.widget.TabLayout.OnTabSelectedListener;
import android.support.design.widget.TabLayout.Tab;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

/*
 *  FOr simplicity i added compacted classes, but the idea is, it is suppose
 *  to work even if you have separate clases. you may even reslove to getting
 *  rid of the interface, and using request code, as the tag. so you can 
 *  identify them there.
 */

//i am in my separate class
interface ActivityResHan{

    void initiate(String fragmentTag);
}
//i am in my separate class
public class MainActivity extends AppCompatActivity {

String ANDROID_PAGER_TAG_REFERER = "android:switcher:2131296359:";
ViewPager mViewPager;
TabLayout tabl;
FrameLayout fl;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    fl = new FrameLayout(this);
    fl.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.MATCH_PARENT));
    fl.setId(2);
    setContentView(fl);
    getSupportFragmentManager().beginTransaction().
    add(2,new ViewPagerFragment(), "viewpageframent").commit();

}

//i am in my separate class
private class ViewPagerFragment extends Fragment implements ActivityResHan{
    static final int PICK_CONTACT_REQUEST = 1; 
    String calleer = "";

    @Override
    @Nullable
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.activity_main, null);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);
        tabl = (TabLayout) view.findViewById(R.id.tablayou);
        mViewPager = (ViewPager) view.findViewById(R.id.pager);
        tabl.setTabsFromPagerAdapter(new FragmentPAdapt());
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabl));

        tabl.setOnTabSelectedListener(new OnTabSelectedListener() {

            @Override
            public void onTabUnselected(Tab arg0) {

            }

            @Override
            public void onTabSelected(Tab arg0) {
                mViewPager.setCurrentItem(arg0.getPosition());
            }

            @Override
            public void onTabReselected(Tab arg0) {

            }
        });
    }

    @Override
    public void initiate(String fragmentTag) {
        calleer = fragmentTag;
        Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
        pickContactIntent.setType(Phone.CONTENT_TYPE);
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        if(!calleer.isEmpty()){
            Fragment fg =getSupportFragmentManager().findFragmentByTag(calleer);
            fg.onActivityResult(requestCode, resultCode, data);
            calleer = "";
        }else{
            //run my own shit
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

}
//i am in my separate class
private class FragmentPAdapt extends FragmentPagerAdapter{

    private class Thefrag extends Fragment{
        TextView t;
        public Thefrag() {
            super();
        }
        @Override
        @Nullable
        public View onCreateView(LayoutInflater inflater,
                @Nullable ViewGroup container,
                @Nullable Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            LinearLayout v = new LinearLayout(MainActivity.this);
            v.setBackgroundColor(Color.WHITE);
            t = new TextView(MainActivity.this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, 
                    LinearLayout.LayoutParams.MATCH_PARENT);
            lp.gravity = Gravity.CENTER_VERTICAL|Gravity.FILL_VERTICAL;
            t.setLayoutParams(lp);
            t.setText("         This is frag " +getTag().subSequence(
                    getTag().length()-1,
                    getTag().length()));
            t.setTextSize(15f);
            v.setClickable(true);
            v.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View arg0) {
                    ((ActivityResHan)getActivity().getSupportFragmentManager().
                            findFragmentByTag("viewpageframent")).initiate(getTag());
                }
            });
            v.addView(t);
            return v;
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                Intent data) {
            // TODO Auto-generated method stub
            t.setText("               Contact uri is = " + data.getDataString());
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    public FragmentPAdapt() {
        super(getSupportFragmentManager());
        mViewPager.setAdapter(this);
    }

    @Override
    public Fragment getItem(int arg0) {
        Fragment f = getSupportFragmentManager().findFragmentByTag(
                ANDROID_PAGER_TAG_REFERER + String.valueOf(arg0));
        if(f == null){
            return new Thefrag();
        }
        return f;
    }

    @Override
    public int getCount() {         
        return 10;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return "FRAGMENT "+String.valueOf(position);
    }
 }

}

Hope it helps.

Elltz
  • 10,730
  • 4
  • 31
  • 59
  • Sorry bro, I waited for you so long, and after that I got engaged with some other work. I will check your process for sure, and don't worry, if it work, I will restart the bounty and give that to you for sure. :) – Devraj Sep 04 '15 at 10:14
0
In Kotlin

In Activity :-

private var fragment: Fragment? = null

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.fragment_activity)

    fragment = Fragment()

 }

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    fragment?.onActivityResult(requestCode, resultCode, data)
}

In Fragment :- 

button.setOnClickListener {

activity?.startActivityForResult(Intent(parentActivity,
                SecondActivity::class.java), REQUEST_CODE)

}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    val string = data?.getStringExtra("SELECTED_NAME")
    Log.e("Name", "$string")
}

In SecondActivity :- 

override fun onOptionsItemSelected(item: MenuItem): Boolean {

    when (item.itemId) {
        android.R.id.home -> finish()

        R.id.action_filter_apply -> {
            val intent = Intent()
            intent.putExtra("SELECTED_NAME", "Android")
            setResult(Activity.RESULT_OK, intent)
            finish()
        }
    }

    return super.onOptionsItemSelected(item)
}
 
Krishna
  • 1,556
  • 13
  • 21
  • OMG, still trying to answer 5 year old question. Hopefully you didn't read the question properly. I didn't use 2 activities. It was the scenario of Activity-->Fragment-->ChildFragment. and I wanted to get instance in ChildFragment. – Devraj Sep 17 '20 at 06:55
-1

In your fragment override this method

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
}

and store the activity variable as a member of your class. This way you will always get the right activity, provided by the system.

user3290180
  • 4,260
  • 9
  • 42
  • 77