52

Is it possible to to start Gallery in such a way so both pictures and videos are shown?

Thanks

Asahi
  • 13,378
  • 12
  • 67
  • 87

11 Answers11

66

Pick Audio file from Gallery:

//Use MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);

Pick Video file from Gallery:

//Use MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);

Pick Image from gallery:

//Use  MediaStore.Images.Media.EXTERNAL_CONTENT_URI
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

Pick Media Files or images:

 Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/* video/*");
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
54

You start the gallery as such:

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

then in your onActivityResult you can check if video or image was selected by doing this:

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

if (resultCode == RESULT_OK) {
    Uri selectedMediaUri = data.getData();
    if (selectedMediaUri.toString().contains("image")) {
        //handle image
    } else  if (selectedMediaUri.toString().contains("video")) {
        //handle video
    }
}
Cee McSharpface
  • 8,493
  • 3
  • 36
  • 77
Siavash
  • 7,583
  • 13
  • 49
  • 69
27

(EDIT: I don't use it anymore, we went back to the two choices "pick image" and "pick video". The problem was with some Sony phone. So, it's not 100% solution below, be careful! )

This is what I use:

if (Build.VERSION.SDK_INT < 19) {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/* video/*");
    startActivityForResult(Intent.createChooser(intent, getResources().getString(R.string.select_picture)), SELECT_GALLERY);
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});
    startActivityForResult(intent, SELECT_GALLERY_KITKAT);
}

The key here is intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});

Fen1kz
  • 1,050
  • 12
  • 24
  • I used your method its works but I am unable to read the filePath using MediaStore.Images.Media.DATA column, any idea which one should I use here to it – Nouman Tahir Apr 11 '17 at 11:50
  • Should this read `intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"video/*"});` since the type has already been set with `intent.setType("image/*");`? – samus Apr 17 '17 at 15:55
  • Nice solution but does not work on a Nexus 9 with Android 7, the Google photo app shows only the pictures. On other test devices it worked as expected. – Nantoka Oct 11 '19 at 19:03
11
intent.setType("*/*");

This presents user with dialog but works on at least ICS. Haven't tested on other platforms.

Eran
  • 387,369
  • 54
  • 702
  • 768
Maurycy
  • 3,911
  • 8
  • 36
  • 44
7

When you need to determine what kind of content was returned, you can do it using content resolver to get the MIME type of the returned content:

if( data != null) {
    Uri selectedUri = data.getData();   
    String[] columns = { MediaStore.Images.Media.DATA,
                         MediaStore.Images.Media.MIME_TYPE };

    Cursor cursor = getContentResolver().query(selectedUri, columns, null, null, null);
    cursor.moveToFirst();

    int pathColumnIndex     = cursor.getColumnIndex( columns[0] );
    int mimeTypeColumnIndex = cursor.getColumnIndex( columns[1] );

    String contentPath = cursor.getString(pathColumnIndex);
    String mimeType    = cursor.getString(mimeTypeColumnIndex);
    cursor.close();

    if(mimeType.startsWith("image")) {
          //It's an image
    }
    else if(mimeType.startsWith("video")) {
         //It's a video
    }       
}
else {
    // show error or do nothing
}
Pit0r
  • 150
  • 1
  • 4
2

UPDATE 2021

FINALLY a solution working for Android 9.

This piece of code only open image apps, and you can select both images and videos. I tried a bunch of different combinations and this exact code will make it work.

    libraryIntent.setType("video/*, image/*");
    String[] mimetypes = {"image/*", "video/*"};
    libraryIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
Gabriel Petersson
  • 8,434
  • 4
  • 32
  • 41
2

Still Working On Jan'2022

If This is Working For You Then Try it,

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

else For Older SDK's and For Some Devices Try the below one,

 Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});
     startActivityForResult(intent,PICK_FILE);

where, PICK_FILE is a variable,

private static final int PICK_FILE = 1;
Ataullha
  • 39
  • 5
2

CoolIris which came with my galaxy tab can do it. However the cooliris on my acer betouch will not :S On my milestone you can not start the gallery with a pick intent on the video url however when you start it on the images url, you can select a video and it will return a video url too.

Arno den Hond
  • 627
  • 1
  • 7
  • 24
1

This is working for me for Android 12 (SDK 32)
Pick multiple images & videos from the gallery
Also with the latest registerForActivityResult

val resultLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            onActivityResult(result)
        }

fun pickMediaFiles() {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.addCategory(Intent.CATEGORY_OPENABLE)
        intent.type = "image/* video/*"
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
        intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
        resultLauncher.launch(intent)
    }

fun onActivityResult(result: ActivityResult) {
        if (result.resultCode == RESULT_OK && result.data != null) {
            //If selected multiple medias
            if (result.data?.clipData != null) {
                val count: Int =
                    result.data!!.clipData!!.itemCount 
                for (i in 0 until count) {
                    val selectedUri: Uri? = result.data!!.clipData?.getItemAt(i)?.uri
                }
            }
            //If selected single media
            else if (result.data?.data != null) {
                val selectedUri: Uri? = result.data?.data
            }
        }
    }
Chirag Prajapati
  • 25
  • 1
  • 1
  • 7
0

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/*");
KILA
  • 205
  • 3
  • 5
0

After trying out different combinations from above answers and from other questions. This is what is finally working for me. API levels I tested it on v23 to v34. But it should work on versions below and higher too.

/**
 * Open gallery intent
 */
private void dispatchGalleryIntent() {
    final Intent openGalleryIntent = getOpenGalleryIntent();
    startActivityForResult(openGalleryIntent, REQ_CHOOSE_GALLERY);
}

/**
 * Returns gallery intent
 */
@NonNull
private Intent getOpenGalleryIntent() {
    final Intent openGalleryIntent = new Intent(Intent.ACTION_PICK);
    openGalleryIntent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "*/*");
    openGalleryIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {"image/*", "video/*"});
    openGalleryIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    return openGalleryIntent;
}

Key Factors in the above code is to

  1. first define type as "*/*" {representing All Data Types} and then pass your filters MimeType. Like in my case I wanted Video and Images so I passed mimeType array as {"image/*", "video/*"}"
  2. Use INTERNAL_CONTENT_URI instead of EXTERNAL_CONTENT_URI

CONFIGURATION REQUIREMENTS

Manifest Permissions Required For API Level 32 and lower

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

For API Level 33 and higher

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

Below is Complete code including checking for permissions and selecting files from GALLERY.

Callbacks after selecting files can be handled in onActivityResult

How to ask for permissions ? I am using EasyPermissions to check and ask for permissions. But you can use any method or simply use Android Default permission method.

private String[] attachmentsPathArr = new String[]{};
private final int REQ_GALLERY_PERMISSION = 300;
private final int REQ_CHOOSE_GALLERY = 600;

@RequiresApi(api = 33)
public static final String[] PERMISSIONS_STORAGE_AVI_V33_ARR = {        //AVI - Audio, Video, Image
            Manifest.permission.READ_MEDIA_VIDEO,
            Manifest.permission.READ_MEDIA_IMAGES
    };
public static final String PERMISSION_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;

 /**
 * Open Gallery task with permission
 */
@AfterPermissionGranted(REQ_GALLERY_PERMISSION)
private void galleryTask() {
    if (hasStoragePermission()) {
        // Have permission, call the gallery intent!
        dispatchGalleryIntent();
    } else {
        // Request one permission
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            EasyPermissions.requestPermissions(this, getString(R.string.gallery_permission_message),
                    REQ_GALLERY_PERMISSION, PERMISSIONS_STORAGE_AVI_V33_ARR);
        } else {
            EasyPermissions.requestPermissions(this, getString(R.string.gallery_permission_message),
                    REQ_GALLERY_PERMISSION, PERMISSION_STORAGE);
        }
    }
}

Permission Check

 /**
 * Storage specific permission check
 */
private boolean hasStoragePermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        return EasyPermissions.hasPermissions(getActivity(), PERMISSIONS_STORAGE_AVI_V33_ARR);
    } else {
        return EasyPermissions.hasPermissions(getActivity(), PERMISSION_STORAGE);
    }
}

Handle/Save selected files path returning from Gallery.

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
            if (requestCode == REQ_CHOOSE_GALLERY) {
                showLog(TAG, "onActivityResult REQ_CHOOSE_GALLERY- " + REQ_CHOOSE_GALLERY);
                if (data != null) {
                    Uri selectedImageUri = data.getData();
                    if (data.getClipData() != null) {
                        int count = data.getClipData().getItemCount();
                        attachmentsPathArr = new String[count];  //Initializing the array based on number of files path received
                        for (int index = 0; index < count; index++) {
                            attachmentsPathArr[index] = FileUtils.getPath(getActivity(), data.getClipData().getItemAt(index).getUri());
                            showLog(TAG, "onActivityResult \n -attachmentsPathArr[" + index + "].getUri()- " + data.getClipData().getItemAt(index).getUri());
                        }

                        setSelectedFiles(); //Do your next operation here like displaying the files or saving it.
                    } else {
                        showLog(TAG, "onActivityResult selectedImageUri == null selectedImageUri- " + selectedImageUri);
                    }
                }
            }
        } 
}

Hope it helps and saves your time! Thanks