Is it possible to to start Gallery in such a way so both pictures and videos are shown?
Thanks
Is it possible to to start Gallery in such a way so both pictures and videos are shown?
Thanks
//Use MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
//Use MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
//Use MediaStore.Images.Media.EXTERNAL_CONTENT_URI
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/* video/*");
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
}
}
(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/*"});
intent.setType("*/*");
This presents user with dialog but works on at least ICS. Haven't tested on other platforms.
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
}
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);
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;
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.
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
}
}
}
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/*");
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
"*/*"
{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/*"}"
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