6

Select Image from Gallery inside Fragment Class is not working.

I tried more stacks code.

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
}

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

Above code is working in Activity Class. Not for Pure Fragment Class.

harikrishnan
  • 1,985
  • 4
  • 32
  • 63

6 Answers6

0

If your are invoking the startActivityForResult() method from a Fragment, you have two options:

  1. call startActivityForResult() directly
  2. call getActivity().startActivityForResult()

In your case, if you want to handle the result on your Activity, change your code in this way:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    getActivity().startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    getActivity().startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
}

Otherwise, if you need to handle the result in the calling Fragment and it's currently not working, you may have a propagation issue. This kind of problem has been widely described in this post.

A detailed article about startActivityForResult and nested fragment can be found here.

Community
  • 1
  • 1
bonnyz
  • 13,458
  • 5
  • 46
  • 70
  • Hi Bonnyz, I tried with above getActivity().startActivityForResult() code.. this also not working.. here, no need to send data from parent activity to fragent, or fragment to parent activity.. – harikrishnan Oct 12 '15 at 13:36
  • just, inside fragment class, just open gallery and pick an image ans show in imageview.. thats it.. these are all need to done with inside fragment class only.. – harikrishnan Oct 12 '15 at 13:37
  • @harikrishnan So, if need to to start/receive the onActivtyResult directly in the fragment, take a look at second part of the answer which talks about the propagation issue – bonnyz Oct 12 '15 at 13:38
0

If above code is not working you should check your fragment import statement .

I think you are using fragment within fragment. if so please post your import code.

Rahul Chaudhary
  • 1,059
  • 1
  • 6
  • 15
  • Yes Rahul.. here i am using Material Tab FRagment.inside one TabFragment Class. I want to do , like select image from gallery and upload it to web services.. – harikrishnan Oct 16 '15 at 11:54
  • code working only startActivityForResult() till.. next public void onActivityResult(int requestCode, int resultCode, Intent data){} method not called.. thats my problem..i want to do this only inside fragment class. i dont want to transfer any data from Fragment to Activity..... – harikrishnan Oct 16 '15 at 11:56
  • ok try to use getActivity.startActivityForResult and let me know the result – Rahul Chaudhary Oct 16 '15 at 12:06
0

Hope this help you.

Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(i, RESULT_LOAD_IMAGE);
// write this in your fragment or method or listener which will invoke gallery.

then write this in your fragment

public void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == RESULT_LOAD_IMAGE && resultCode == getActivity().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);
        Log.d("Picture Path", "Picture Path:"+picturePath);

        long total_Images_size=0;

        File f=new File(picturePath);
        //total_Images_size+=f.length();
        /*if(total_Images_size>MAX_IMAGE_FILES_SIZE)
        {
            Toast.makeText(getActivity(), "Image attachments size cannot exceed 5MB(total).", Toast.LENGTH_LONG).show();
            return;
        }*/
        String selectedFilename=picturePath.substring(picturePath.lastIndexOf("/"));

        addPicture(picturePath,  imageCount);


    }

Try and please let me know if there is any error.Thanks

Rushi Ayyappa
  • 2,708
  • 2
  • 16
  • 32
0

If you are using this code on a Fragment which is attached to an Activity, then:

  1. getActivity().startActivityForResult() will invoke the onActivityResult() of the activity.

  2. startActivityForResult() will invoke both the onActivityResult() of the activity and of the fragment. The problem here is, the fragment's onActivityResult() will get the correct requestCode. But that of the activity's will get a modified requestCode.

But this is not the case for Nested Fragments. In case of NestedFragments, always call getActivity().startActivityForResult() and handle the result in the onActivityResult() of the activity. If you don't want to create a strong dependency between fragments and activities, you have to have a design pattern that does this decoupling (I use the Otto library for this). Even better is to always call the getActivity().startActivityForResult() from the Fragment attached to the activity, rather than the nested one.

Best Practice: From my experience, handle the onActivityResult() only in activity! This will reduce a lot of maintenance nightmare. Use some other mechanism to delegate this to the fragments.

Henry
  • 17,490
  • 7
  • 63
  • 98
0

Since all you want to do is retrieve an image from the gallery intent and populate your imageview that exists in your FRAGMENT, what you can do is hold a reference to this imageview in your activity and use getActivity().startActivityForResult() then set the bitmap for the imageview reference in your activity.

Code:

// YOUR FRAGMENT

// fragment code...
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), GALLERY_INTENT_CALLED);
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    // Update your activity's imageview reference
    mListener.setImageViewRef(fragmentImgView);
    getActivity().startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
}

// more code..

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try {
        mListener = (OnFragmentInteractionListener) getActivity();
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

// Create interface to communicate with your activity

public interface OnFragmentInteractionListener {
    void setImageViewRef(ImageView imgView);
}

// END FRAGMENT CODE.

// YOUR ACTIVITY

public class MyActivity extends FragmentActivity implements MyFragment.OnFragmentInteractionListener {
    ...
    private ImageView myFragmentsImageViewReference;
    ...
    @Override
    void setImageViewRef(ImageView imgView) {
        this.myFragmentsImageViewReference = imgView;
    }

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

        ... get Image from intent ...
        myFragmentsImageViewReference.setImageBitmap(myBitmapRetrievedFromIntent);
        ...
    }
}

// END ACTIVITY CODE
Bhargav
  • 8,118
  • 6
  • 40
  • 63
0

Please check your activity's onActivityResult() method it will be getting called if you are not getting callback in Fragment's onActivityResult().Ifyou are getting call back in parent activity then you can invoke Fragment's onActivityResult() method from there...Tell me if you need anymore help...

Harry Sharma
  • 2,190
  • 2
  • 15
  • 41