4

I want to select gallery intent in fragment.when user choose option to select image from gallery then gallery opens and immediately onActivityResult of fragment is being called.and when user pick image then onActivityResult() is not called.So i am not able to select image from gallery. Belo is my code to open gallery -

Intent intent = new   Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.setType("video/, images/");
    startActivityForResult(intent, 2);

and here is my onActivityResult-

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult"); // not printed
    Toast.makeText(mContext, "aaaa"+requestCode, Toast.LENGTH_SHORT).show();
}

What the problem in my code.

Thanks in advance.

Ravi Bhandari
  • 4,682
  • 8
  • 40
  • 68
  • are you sure you can start an activity for result from a fragment without using an activity reference? I think you should catch the activity result in the starting activity. – MineConsulting SRL Nov 05 '14 at 09:11
  • Yes i am using same code in some other fragment and it is working fine.Also you are right firstly parent activity onActivityResult and then fragment onActivityResult is called but both are called when gallery is open. – Ravi Bhandari Nov 05 '14 at 09:16
  • What happens if you first check the requestcode? – MineConsulting SRL Nov 05 '14 at 10:41
  • When i click button to open then passing request code 2 as mention in my question,after button click gallery opens and suddenly onActivityresult called with requestcode 2 and responsecode 0. – Ravi Bhandari Nov 05 '14 at 11:30

4 Answers4

2

Use this to open the android image chooser:

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

and for onActivityResult use this:

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

    Cursor cursor = null;
    if (resultCode != Activity.RESULT_OK)
        return;
    if (data == null)
        return;
    Uri originalUri = null;
    if (requestCode == GALLERY_INTENT_CALLED && data != null) {
        originalUri = data.getData();
        String[] filePathColumn = {MediaStore.Images.Media.DATA};

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

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        filePath = cursor.getString(columnIndex);
        cursor.close();
        Log.d("path of uri", filePath);

    } else if (requestCode == GALLERY_KITKAT_INTENT_CALLED && data != null) {
        originalUri = data.getData();

        final int takeFlags = data.getFlags()
                & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // Check for the freshest data.
        getActivity().getContentResolver().takePersistableUriPermission(
                originalUri, takeFlags);
        Log.d("Uri: ", originalUri.toString());

        filePath = getPath(getActivity(), originalUri);

        Log.d("filepath", filePath);

    }

}

@SuppressLint("NewApi")
public static String getPath(final Context context, final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/"
                        + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"),
                    Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[]{split[1]};

            return getDataColumn(context, contentUri, selection,
                    selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context       The context.
 * @param uri           The Uri to query.
 * @param selection     (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri,
                                   String selection, String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {column};

    try {
        cursor = context.getContentResolver().query(uri, projection,
                selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            final int column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}
Auroratic
  • 462
  • 8
  • 25
amit kumar
  • 291
  • 1
  • 6
1

# I am showing you an example in which i used an ImageView to show image result .There are two methods used 1.From camera and 2.From SD card #

public void camera(View view) {

        Log.i("SonaSys", "startCameraActivity()");
        File file = new File(path);
        Uri outputFileUri = Uri.fromFile(file);
        Intent intent = new Intent(
                android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        startActivityForResult(intent, 0);

    }

public void gallery(View view) {

  String path = Environment.getExternalStorageDirectory()
                + "/images/imagename.jpg";
        Intent i = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, RESULT_LOAD_IMAGE);
    }

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

        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK
                && null != data) {

            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

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

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

            bitmap = BitmapFactory.decodeFile(picturePath);
            image.setImageBitmap(bitmap);

            if (bitmap != null) {
                ImageView rotate = (ImageView) findViewById(R.id.rotate);
                rotate.setVisibility(View.VISIBLE);
            }

        } else {

            Log.i("SonaSys", "resultCode: " + resultCode);
            switch (resultCode) {
            case 0:
                Log.i("SonaSys", "User cancelled");
                break;
            case -1:
                onPhotoTaken();
                break;

            }

        }

    }

    protected void onPhotoTaken() {
        // Log message
        Log.i("SonaSys", "onPhotoTaken");
        taken = true;
        imgCapFlag = true;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
        bitmap = BitmapFactory.decodeFile(path, options);
        image.setImageBitmap(bitmap);


    }
0

use this code for choose image,

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

Since Activity gets the result of onActivityResult(), you will need to override the activity's onActivityResult() and call super.onActivityResult() to propagate to the respective fragment for unhandled results codes or for all.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);
}
Akash Moradiya
  • 3,318
  • 1
  • 14
  • 19
  • I have try your code super.onActivityResult(requestCode, resultCode, data); but it still called onActivityResult when gallery opens instead of when i picked image. – Ravi Bhandari Nov 05 '14 at 09:19
0

To help others who are struggling with this bug, i would suggest the following:

1. The launch mode of your fragment activity

if launch mode of your activity is the "singleInstance" in that case the onActivityResult will be called automatically once you leave the activity and goes to activity where you are supposed to pick the image. This is true for the camera intent also. Try to change your launch mode to "singleTop" or anything as an alternative to the launch mode that you have right now. This way what will happen that your activityOnResult will be called only when you finish up picking the image. Also the result will be return to the fragment only from where you have called the startActivityForResult. I will suggest you to consider to implement the dialogueFragment for giving option to user to pick the image or click image

2. The how have you called the startActivityForResult

Its another interesting thing, if you call your startActivityResult from fragment using the local context of the fragment the result will be returned back to the fragment but if you call it using the fragment activity context like getActivity().startActivityResult the result will be passed back to the parent fragment activity. So it depends upon you where you want to handle it. Other important thing, do call the

super.onActivityResult(requestCode, resultCode, data);

in your method where you are getting the result. Other than these try following the suggestion that other has provided for picking the image using the proper intent.

Community
  • 1
  • 1
Ankush Sharma
  • 913
  • 11
  • 20