android pick images from gallery

AndroidGalleryAction

Android Problem Overview


I want to create a picture chooser from gallery. I use code

 intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
 startActivityForResult(intent, TFRequestCodes.GALLERY);

My problem is that in this activity and video files are displayed. Is there a way to filter displayed files so that no video files will be displayed in this activity?

Android Solutions


Solution 1 - Android

Absolutely. Try this:

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

Don't forget also to create the constant PICK_IMAGE, so you can recognize when the user comes back from the image gallery Activity:

public static final int PICK_IMAGE = 1;

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (requestCode == PICK_IMAGE) {
        //TODO: action
    }
}

That's how I call the image gallery. Put it in and see if it works for you.

EDIT:

This brings up the Documents app. To allow the user to also use any gallery apps they might have installed:

    Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
    getIntent.setType("image/*");

    Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    pickIntent.setType("image/*");

    Intent chooserIntent = Intent.createChooser(getIntent, "Select Image");
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});

    startActivityForResult(chooserIntent, PICK_IMAGE);

Solution 2 - Android

Sometimes, you can't get a file from the picture you choose. It's because the choosen one came from Google+, Drive, Dropbox or any other provider.

The best solution is to ask the system to pick a content via Intent.ACTION_GET_CONTENT and get the result with a content provider.

You can follow the code bellow or look at my updated gist.

public void pickImage() {
  Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
  intent.setType("image/*");
  startActivityForResult(intent, PICK_PHOTO_FOR_AVATAR);
}
 
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
        if (data == null) {
            //Display an error
            return;
        }
        InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
        //Now you can do whatever you want with your inpustream, save it as file, upload to a server, decode a bitmap...
    }
}

Solution 3 - Android

public void FromCamera() {

	Log.i("camera", "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, 1);

}

public void FromCard() {
	Intent i = new Intent(Intent.ACTION_PICK,
			android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
	startActivityForResult(i, 2);
}

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

	super.onActivityResult(requestCode, resultCode, data);

	if (requestCode == 2 && 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);
			
		}

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


}

Solution 4 - Android

You can use this method to pick image from gallery. Only images will be displayed.

public void pickImage() {
    Intent intent = new Intent(Intent.ACTION_PICK,
            MediaStore.Images.Media.INTERNAL_CONTENT_URI);
    intent.setType("image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("scale", true);
    intent.putExtra("outputX", 256);
    intent.putExtra("outputY", 256);
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("return-data", true);
    startActivityForResult(intent, 1);
}

and override onActivityResult as

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }
        if (requestCode == 1) {
            final Bundle extras = data.getExtras();
            if (extras != null) {
                //Get image
                Bitmap newProfilePic = extras.getParcelable("data");
            }
        }
    }

Solution 5 - Android

Here is a full example for request permission (if need), pick image from gallery, then convert image to bitmap or file

AndroidManifesh.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Activity

class MainActivity : AppCompatActivity() {

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

        button_pick_image.setOnClickListener {
            pickImage()
        }
    }

    private fun pickImage() {
        if (ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            val intent = Intent(
                Intent.ACTION_PICK,
                MediaStore.Images.Media.INTERNAL_CONTENT_URI
            )
            intent.type = "image/*"
            intent.putExtra("crop", "true")
            intent.putExtra("scale", true)
            intent.putExtra("aspectX", 16)
            intent.putExtra("aspectY", 9)
            startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                READ_EXTERNAL_STORAGE_REQUEST_CODE
            )
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_IMAGE_REQUEST_CODE) {
            if (resultCode != Activity.RESULT_OK) {
                return
            }
            val uri = data?.data
            if (uri != null) {
                val imageFile = uriToImageFile(uri)
                // todo do something with file
            }
            if (uri != null) {
                val imageBitmap = uriToBitmap(uri)
                // todo do something with bitmap
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            READ_EXTERNAL_STORAGE_REQUEST_CODE -> {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // pick image after request permission success
                    pickImage()
                }
            }
        }
    }

    private fun uriToImageFile(uri: Uri): File? {
        val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
        val cursor = contentResolver.query(uri, filePathColumn, null, null, null)
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                val columnIndex = cursor.getColumnIndex(filePathColumn[0])
                val filePath = cursor.getString(columnIndex)
                cursor.close()
                return File(filePath)
            }
            cursor.close()
        }
        return null
    }

    private fun uriToBitmap(uri: Uri): Bitmap {
        return MediaStore.Images.Media.getBitmap(this.contentResolver, uri)
    }

    companion object {
        const val PICK_IMAGE_REQUEST_CODE = 1000
        const val READ_EXTERNAL_STORAGE_REQUEST_CODE = 1001
    }
}

Demo
https://github.com/PhanVanLinh/AndroidPickImage

Solution 6 - Android

I have same problem .I use this codes

addIntent

 Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Tack Image"), PICK_PHOTO);

add onActivityResult

 @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_PHOTO && resultCode == Activity.RESULT_OK) {
      if (data == null) {
      //error
        return;
      }
      try {
        Uri uri = data.getData();
        File file = FileUtil.from(currentActivity, uri);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

FileUtil class

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileUtil {
  private static final int EOF = -1;
  private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

  private FileUtil() {

  }

  public static File from(Context context, Uri uri) throws IOException {
    InputStream inputStream = context.getContentResolver().openInputStream(uri);
    String fileName = getFileName(context, uri);
    String[] splitName = splitFileName(fileName);
    File tempFile = File.createTempFile(splitName[0], splitName[1]);
    tempFile = rename(tempFile, fileName);
    tempFile.deleteOnExit();
    FileOutputStream out = null;
    try {
      out = new FileOutputStream(tempFile);
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
    if (inputStream != null) {
      copy(inputStream, out);
      inputStream.close();
    }

    if (out != null) {
      out.close();
    }
    return tempFile;
  }

  private static String[] splitFileName(String fileName) {
    String name = fileName;
    String extension = "";
    int i = fileName.lastIndexOf(".");
    if (i != -1) {
      name = fileName.substring(0, i);
      extension = fileName.substring(i);
    }

    return new String[]{name, extension};
  }

  private static String getFileName(Context context, Uri uri) {
    String result = null;
    if (uri.getScheme().equals("content")) {
      Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
      try {
        if (cursor != null && cursor.moveToFirst()) {
          result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        if (cursor != null) {
          cursor.close();
        }
      }
    }
    if (result == null) {
      result = uri.getPath();
      int cut = result.lastIndexOf(File.separator);
      if (cut != -1) {
        result = result.substring(cut + 1);
      }
    }
    return result;
  }

  private static File rename(File file, String newName) {
    File newFile = new File(file.getParent(), newName);
    if (!newFile.equals(file)) {
      if (newFile.exists() && newFile.delete()) {
        Log.d("FileUtil", "Delete old " + newName + " file");
      }
      if (file.renameTo(newFile)) {
        Log.d("FileUtil", "Rename file to " + newName);
      }
    }
    return newFile;
  }

  private static long copy(InputStream input, OutputStream output) throws IOException {
    long count = 0;
    int n;
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    while (EOF != (n = input.read(buffer))) {
      output.write(buffer, 0, n);
      count += n;
    }
    return count;
  }
}

and you must add provider_paths.xml to xml folder like image enter image description here

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

and finaly add below in AndroidManifest.xml

<application
...>

...
      <provider
          android:name="androidx.core.content.FileProvider"
          android:authorities="${applicationId}.provider"
          android:exported="false"
          android:grantUriPermissions="true">
          <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
        </provider>
...
</application>

I hope I helped

Solution 7 - Android

2021 Kotlin solution with new version of Fragment:

dependencies {
  implementation "androidx.fragment:fragment:1.3.3"
}
class YourFragment : Fragment() {

    private val fileChooserContract = registerForActivityResult(ActivityResultContracts.GetContent()) { imageUri ->
        if (imageUri != null) {
            // imageUri now contains URI to selected image
        }
    }

    // ...

    fun openFileChooser() {
        fileChooserContract.launch("image/*")
    }
}

Solution 8 - Android

Goodbye startActivityForResult()

Proper way nowadays with AndroidX Activity, is Activity Result APIs and that is strongly recommended way by google

private val selectImageFromGalleryResult = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
    uri?.let { previewImage.setImageURI(uri) }
}

Simply call selectImageFromGallery() when needed

private fun selectImageFromGallery() = selectImageFromGalleryResult.launch("image/*")

Solution 9 - Android

Just to offer an update to the answer for people with API min 19, per the docs: >On Android 4.4 (API level 19) and higher, you have the additional option of using the ACTION_OPEN_DOCUMENT intent, which displays a system-controlled picker UI controlled that allows the user to browse all files that other apps have made available. From this single UI, the user can pick a file from any of the supported apps.

>On Android 5.0 (API level 21) and higher, you can also use the ACTION_OPEN_DOCUMENT_TREE intent, which allows the user to choose a directory for a client app to access.

Open files using storage access framework - Android Docs

     val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
     intent.type = "image/*"
     startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE)

Solution 10 - Android

OnActivityResult method is deprecated

val singleImageResultLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == Activity.RESULT_OK) {
                    // There are no request codes
                    val data: Intent? = result.data
                    val selectedImageUri: Uri? = data?.data
                    if (null != selectedImageUri) {
                        // Get the path from the Uri
                        val path = getPathFromURI(selectedImageUri)
                        findViewById<TextView>(R.id.textView).text = path
                        findViewById<ImageView>(R.id.imageView2).setImageURI(selectedImageUri)
                    }
                }
            }
findViewById<Button>(R.id.oneImageSelectBtn).setOnClickListener {
            val intent = Intent()
            intent.type = "image/*"
            intent.action = Intent.ACTION_GET_CONTENT
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
            singleImageResultLauncher.launch(Intent.createChooser(intent, "Select Picture"))

        }
private fun getPathFromURI(uri: Uri?): String {
        var path = ""
        if (contentResolver != null) {
            val cursor = contentResolver.query(uri!!, null, null, null, null)
            if (cursor != null) {
                cursor.moveToFirst()
                val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME)
                path = cursor.getString(idx)
                cursor.close()
            }
        }
        return path
}

Solution 11 - Android

If you are only looking for images and multiple selection.

Look @ once https://stackoverflow.com/a/15029515/1136023

It's helpful for future.I personally feel great by using MultipleImagePick.

Solution 12 - Android

thanks to mklkj.

this is a activity version.

fileChooserContract can select a image. filesChooserContract can select multi images.

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "MainActivity"
    }

    lateinit var viewBinding: ActivityMainBinding

    private val fileChooserContract = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        Log.d(TAG, "onActivityResult: uri $uri")
    }

    private val filesChooserContract = registerForActivityResult(ActivityResultContracts.GetMultipleContents()) { uriList ->
        for (uri in uriList) {
            Log.d(TAG, "onActivityResult: uri $uri")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)

        viewBinding.btnPick.setOnClickListener {
            fileChooserContract.launch("image/*")
        }

        viewBinding.btnPickMulti.setOnClickListener {
            filesChooserContract.launch("image/*")
        }
    }
}

Solution 13 - Android

OPTION-1

The below code allows user to select an image from any file explorer application

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

But in some devices, the above solution will not fetch the image with EXIF information such as orientation. So in those devices, EXIF processing such as changing image orientation could not be performed as expected.

OPTION-2

The below code allows user to select an image from any gallery application

Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult ( intent, PICK_IMAGE_CODE );

But in some devices, while setting the intent type, the above solution will clear the intent data (MediaStore.Images.Media.EXTERNAL_CONTENT_URI) which could hinder the gallery opening process.

OPTION-3

Finally, I suggest the below code which allows user to select an image from any gallery application which does not cause any problem and does not show up any warning

Intent intent = new Intent ();
intent.setAction ( Intent.ACTION_PICK );
intent.setDataAndType ( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*" );
startActivityForResult ( intent, PICK_IMAGE_CODE );

Solution 14 - Android

Here is working code a util method in kotlin:

fun launchGalleryWithFragment() {
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        intent.type = "image/*"
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1001)
    }

Now override onActivityResult method:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
var path: Uri? = null
        if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK) {
            if(dataIntent == null || dataIntent.data == null){
                return null
            }
            path = dataIntent.data
        }

}

Solution 15 - Android

For only pick from local add this :

        i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)

And this working nice :

    val i = Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    i.type = "image/*"
    i.putExtra(Intent.EXTRA_LOCAL_ONLY,true)
    startActivityForResult(Intent.createChooser(i,"Select Photo"),pickImageRequestCode)

Solution 16 - Android

Kotlin: Open the ACTION_GET_CONTENT event when you want to prompt the user:

val intent = Intent(Intent.ACTION_GET_CONTENT).apply { type = "image/*" }
startActivityForResult(intent, 9998)

After the user picked an image, handle that event in the onActivityResult function of your Activity. As an example I am displaying it in an ImageView and storing it in the app cache:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 9998) {
        val uri: Uri = data?.data ?: return
        val bytes = contentResolver.openInputStream(uri)?.readBytes() ?: return
        imageView.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
        File("$cacheDir/imgPicked").writeBytes(bytes)  // if needed: store to cache
    }
}

Ideally, replace 9998 with some internal request code enum your app uses. This is just so you can differentiate callbacks from your own requests.

Unlike getParcelable("data") this does not require any permissions.

Note that this doesn't handle the Exif rotation bit on images that set it, so a few images will end up with incorrect orientation (Kotlin solution).

Solution 17 - Android

Since startActivityForResult() is depracated we can choose only image from gallery in the following way using ActivityResultLauncher:

At first we need to define an ActivityResultLauncher<String[]> and initialize it in onCreate() (for Activities) or onViewCreated() (for fragments)

        ActivityResultLauncher<String[]> galleryActivityLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri result) {
                if (result != null) {
                    // perform desired operations using the result Uri
                } else {
                    Log.d(TAG, "onActivityResult: the result is null for some reason");
                }
            }
        });

Let's say we need to open the gallery when submitButton is clicked.

So inside the onClickListener we need to call

galleryActivityLauncher.launch(new String[]{"image/*"});

The trick here is the argument for launch(). By adding "image/*" to the argument array, we are specifying that the file explorer should load images only.

Solution 18 - Android

U can do it easier than this answers :

Uri Selected_Image_Uri = data.getData();
ImageView imageView = (ImageView) findViewById(R.id.loadedimg);
imageView.setImageURI(Selected_Image_Uri);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBuda GavrilView Question on Stackoverflow
Solution 1 - AndroidJMRboostiesView Answer on Stackoverflow
Solution 2 - AndroidBenjaminView Answer on Stackoverflow
Solution 3 - AndroidASHISH KUMAR TiwaryView Answer on Stackoverflow
Solution 4 - AndroidAbhishekView Answer on Stackoverflow
Solution 5 - AndroidLinhView Answer on Stackoverflow
Solution 6 - Androidabolfazl bazghandiView Answer on Stackoverflow
Solution 7 - AndroidmklkjView Answer on Stackoverflow
Solution 8 - AndroidZoranView Answer on Stackoverflow
Solution 9 - AndroidP FusterView Answer on Stackoverflow
Solution 10 - AndroidMeet BhavsarView Answer on Stackoverflow
Solution 11 - AndroidBhavesh HirparaView Answer on Stackoverflow
Solution 12 - Androidaotian16View Answer on Stackoverflow
Solution 13 - Androidniranj1997View Answer on Stackoverflow
Solution 14 - AndroidAli NawazView Answer on Stackoverflow
Solution 15 - AndroidBurak DizlekView Answer on Stackoverflow
Solution 16 - AndroidxjclView Answer on Stackoverflow
Solution 17 - AndroidganjaamView Answer on Stackoverflow
Solution 18 - AndroidReza TaghizadehView Answer on Stackoverflow