android- open gallery and choose image and video
Asked Answered
D

10

22

In my project I want to open a gallery on a button click and should be able to pick image or video to get path of them.

Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

startActivityForResult(i, RESULT_LOAD_IMAGE);

From above code i am able to open gallery but in this case i am only able to choose image. So, please help me in choosing video also. Thanks in advance.

Delores answered 7/4, 2013 at 12:41 Comment(0)
D
10

Below code solved my problem

  final Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
                        galleryIntent.setType("*/*");
                        startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
Delores answered 7/4, 2013 at 16:42 Comment(0)
B
31

On Android 6.0 and above using "video/* image/" or "image/ video/*" type doesn't work, it only recognizes the first filter you specify. I solved the problem using this code:

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("*/*");
photoPickerIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});
startActivityForResult(photoPickerIntent, Constants.SELECT_PHOTO);

Although this will ask the user which app they want to use to select the image/video.

Bendy answered 2/6, 2017 at 20:12 Comment(5)
Thanks, this response should be higher up nowadaysRadiobroadcast
Exact solution for choose only video and image booth parallel.Eltonelucidate
This approach shows extra chooser dialog on android 6.0.1. If choose Google Photos right, it displays videos and photos.Lepidosiren
It displays other apps as well like contacts, google music.Sweetscented
AS OF 2021 I have added a solution below that allows only for images and videos, I found nothing else online that worked so I mixed some answers and accidentaly found the solutionHayfield
C
22

You can use the next snippet:

Intent mediaChooser = new Intent(Intent.ACTION_GET_CONTENT);
//comma-separated MIME types
mediaChooser.setType("video/*, image/*");
startActivityForResult(mediaChooser, RESULT_LOAD_IMAGE);

But I think that it only work on ICS or bigger

Carlenacarlene answered 7/4, 2013 at 12:59 Comment(4)
should be "image/*" instead of "images/*"Whiten
on 6.0 this only allows videos to be chosenAncier
This seems to be broken, at least for newer versions of android or google photos app. Seems like only the first mime type in comma separated list is recognized.Scoop
How can I multi-select photos and videos?Honk
C
11

You need use the following as picking Intent

Intent photoLibraryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoLibraryIntent.setType("image/* video/*");
Cullum answered 6/9, 2013 at 11:52 Comment(0)
D
10

Below code solved my problem

  final Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
                        galleryIntent.setType("*/*");
                        startActivityForResult(galleryIntent, RESULT_LOAD_IMAGE);
Delores answered 7/4, 2013 at 16:42 Comment(0)
H
9

2022 Android 9

I've tried everything available online, and accidently mixed 2 solutions that turned out to work.

This only gives photo library and google photos as options, and you can select photos AND videos.

    libraryIntent.setType("video/*, image/*");
    String[] mimetypes = {"image/*", "video/*"};
    libraryIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
Hayfield answered 27/1, 2021 at 22:29 Comment(0)
S
8

Not enough rep to comment, but @YYamil's response works well.

Intent mediaChooser = new Intent(Intent.ACTION_GET_CONTENT);
//comma-separated MIME types
mediaChooser.setType("video/*, image/*");
startActivityForResult(mediaChooser, RESULT_LOAD_IMAGE);

If you're using the new registerForResultActivity, create a copy of ActivityResultContracts.GetMultipleContents() and put in createIntent:

    @CallSuper
    override fun createIntent(context: Context, input: String): Intent {
        return Intent(Intent.ACTION_GET_CONTENT)
            .addCategory(Intent.CATEGORY_OPENABLE)
            .setType(input)
            .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
            .putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*")) // this does the trick
    }
Skink answered 14/11, 2020 at 5:37 Comment(0)
P
4

This is the best i known...... Try this for once....

 final CharSequence[] options = {"Images", "Videos", "Cancel"};
            AlertDialog.Builder builder = new AlertDialog.Builder(OpenGallery.this);
            builder.setTitle("Select From...");
            builder.setItems(options, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int item) {
                    if (options[item].equals("Images")) {
                        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                        startActivityForResult(intent, 1);
                    } else if (options[item].equals("Videos")) {
                        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
                        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                        startActivityForResult(intent, 1);
                    } else if (options[item].equals("Cancel")) {
                        dialog.dismiss();
                    }
                    dialog.dismiss();
                }
            });
            builder.show();
Polyphagia answered 13/4, 2017 at 7:9 Comment(0)
W
3

Change your Intent to this:

Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);

When trying to get videos you need to state to mediaStore that video is in order and not images as you wrote.

Wrand answered 18/4, 2013 at 15:25 Comment(0)
S
0

Well android has put a lot of restriction on accessing the external content. I ended up using 3rd party library. This one is good.: https://github.com/AnilFurkanOkcun/UWMediaPicker-Android

implementation 'com.github.AnilFurkanOkcun:UWMediaPicker-Android:1.3.0'


UwMediaPicker
.with(this)                     // Activity or Fragment
    .setGalleryMode(UwMediaPicker.GalleryMode.ImageGallery) // GalleryMode: ImageGallery/VideoGallery/ImageAndVideoGallery, default is ImageGallery
.setGridColumnCount(4)                                  // Grid column count, default is 3
    .setMaxSelectableMediaCount(10)                         // Maximum selectable media count, default is null which means infinite
    .setLightStatusBar(true)                                // Is llight status bar enable, default is true
.enableImageCompression(true)               // Is image compression enable, default is false
.setCompressionMaxWidth(1280F)              // Compressed image's max width px, default is 1280
.setCompressionMaxHeight(720F)              // Compressed image's max height px, default is 720
.setCompressFormat(Bitmap.CompressFormat.JPEG)      // Compressed image's format, default is JPEG
.setCompressionQuality(85)              // Image compression quality, default is 85
.setCompressedFileDestinationPath(destinationPath)  // Compressed image file's destination path, default is "${application.getExternalFilesDir(null).path}/Pictures"
.launch{selectedMediaList-> } // (::onMediaSelected)    // Will be called when media is selected
Shulem answered 29/7, 2020 at 13:24 Comment(0)
S
0

I've prepared a way to use all of the Intents that were used for this across Android versions.

It also allows multiple MimeTypes.

Example for webp/gif: getGalleryIntent(activity, null, "image/webp|image/gif")

You need to use try-catch for each of the Intents that you get there, so that you could go to the next fallback if it doesn't work.

You can do the same for images in general together with videos in general.

    private fun setTypesForIntent(intent: Intent, type: String = "image/*") {
        val split = type.split('|')
        if (split.size <= 1)
            intent.type = type
        else {
            //            galleryIntent.addCategory(Intent.CATEGORY_OPENABLE)
            intent.type = "image/*"
            intent.putExtra(Intent.EXTRA_MIME_TYPES, split.toTypedArray())
        }
    }

    fun getGalleryIntent(context: Context, title: CharSequence?, type: String = "image/*", extraIntents: ArrayList<Intent>? = null): Array<Intent> {
        val documentPickerIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
        setTypesForIntent(documentPickerIntent, type)
        if (VERSION.SDK_INT < VERSION_CODES.Q)
            return arrayOf(getPickImageChooserIntent(context, title, true, type, extraIntents), documentPickerIntent)
        val packageManager = context.packageManager
        val galleryIntent = Intent(Intent.ACTION_GET_CONTENT)
        setTypesForIntent(galleryIntent, type)
        val galleryChooserIntent = Intent.createChooser(galleryIntent, title)!!
        if (!extraIntents.isNullOrEmpty())
            galleryChooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toTypedArray<Parcelable>())
        val pickIntent =
                Intent(Intent.ACTION_PICK).setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        setTypesForIntent(pickIntent, type)
        val pickChooserIntent = Intent.createChooser(pickIntent, title)!!
        if (!extraIntents.isNullOrEmpty())
            pickChooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toTypedArray<Parcelable>())
        val getContentActivities =
                packageManager.queryIntentActivitiesCompat(galleryIntent)
        //avoid using the new picker it possible
        val newFilePickerResolveInfo =
                getContentActivities.firstOrNull { it.activityInfo.packageName == "com.google.android.providers.media.module" }
        if (newFilePickerResolveInfo != null)
            return arrayOf(documentPickerIntent, galleryChooserIntent, galleryIntent, pickChooserIntent, pickIntent)
        return arrayOf(galleryChooserIntent, galleryIntent, pickChooserIntent, pickIntent, documentPickerIntent)
    }

    /**
     * Create a chooser intent to select the source to get image from.<br></br>
     * The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br></br>
     * All possible sources are added to the intent chooser.
     *
     * @param context          used to access Android APIs, like content resolve, it is your
     * activity/fragment/widget.
     * @param title            the title to use for the chooser UI
     * @param includeDocuments if to include KitKat documents activity containing all sources
     */
    private fun getPickImageChooserIntent(context: Context, title: CharSequence?, includeDocuments: Boolean, type: String = "image/*",
                                          extraIntents: ArrayList<Intent>? = null): Intent {
        val packageManager = context.packageManager
        var galleryIntents =
                getGalleryIntents(packageManager, Intent.ACTION_GET_CONTENT, includeDocuments, type)
        if (galleryIntents.isEmpty()) {
            // if no intents found for get-content try pick intent action (Huawei P9).
            galleryIntents =
                    getGalleryIntents(packageManager, Intent.ACTION_PICK, includeDocuments, type)
        }
        val allIntents = ArrayList(galleryIntents)
        val target: Intent
        if (allIntents.isEmpty()) {
            target = Intent()
        } else {
            target = allIntents[allIntents.size - 1]
            allIntents.removeAt(allIntents.size - 1)
        }
        // Create a chooser from the main  intent
        val chooserIntent = Intent.createChooser(target, title)!!
        if (!extraIntents.isNullOrEmpty())
            allIntents.addAll(extraIntents)
        // Add all other intents
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toTypedArray<Parcelable>())
        return chooserIntent
    }

    /**
     * Get all Gallery intents for getting image from one of the apps of the device that handle
     * images. Intent.ACTION_GET_CONTENT and then Intent.ACTION_PICK
     */
    fun getGalleryIntents(packageManager: PackageManager, action: String, includeDocuments: Boolean, type: String = "image/*"): List<Intent> {
        val intents = ArrayList<Intent>()
        val galleryIntent = if (action == Intent.ACTION_GET_CONTENT)
            Intent(action)
        else
            Intent(action, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        setTypesForIntent(galleryIntent, type)
        val listGallery = packageManager.queryIntentActivitiesCompat(galleryIntent)
        for (res in listGallery) {
            val intent = Intent(galleryIntent)
            intent.component = ComponentName(res.activityInfo.packageName, res.activityInfo.name)
            intent.`package` = res.activityInfo.packageName
            intents.add(intent)
        }
        // remove documents intent
        if (!includeDocuments) {
            for (intent in intents) {
                if (intent.component!!.className == "com.android.documentsui.DocumentsActivity") {
                    intents.remove(intent)
                    break
                }
            }
        }
        return intents
    }
Smallish answered 24/3 at 0:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.