Android: Let user pick image or video from Gallery - android

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

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/*");

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
}

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.

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;

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/*");

Related

How to set maximum files selection count on intent "Intent.EXTRA_ALLOW_MULTIPLE".User can select upto certain limit?

I'm use following Intent type and use "Intent.EXTRA_ALLOW_MULTIPLE" for selecting multiple files selection,But I want to set maximum files selection count to Intent,Without using custom class in android application.
Intent intent = new Intent();
intent.setType("*/*");
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, true);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
String[] extraMimeTypes = {"image/*", "video/*", "application/pdf", "audio/*",
"application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",};
intent.putExtra(Intent.EXTRA_MIME_TYPES, extraMimeTypes);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
startActivityForResult(intent, 201);
I want to sent files selection count in android Intent.
The only way I can think of is by checking the number of files received inside the Intent data parameter in the OnActivityResult() method using ClipData and recall Intent when the limit has been exceeded.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_OK&&requestCode==201&&data!=null){
ClipData clip=data.getClipData();
if(clip==null){//data.getClipData() returns null if there is ONE item received
Toast.makeText(this,"You have selected only one item!",Toast.LENGTH_LONG).show();
//To receive and manage a single data because clip gets null in this case
ClipData.Item item = new ClipData.Item(data.getData());
ClipDescription description=new ClipDescription("clip",new String[1]);
clip=new ClipData(description,item);
//You have your single data in clip
}else{
if(clip.getItemCount()>YOUR_LIMIT){
Toast.makeText(this,"You have selected greater items than the maximum limit! Reselect your files again!",Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.setType("*/*");
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, true);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
String[] extraMimeTypes = {"image/*", "video/*", "application/pdf", "audio/*",
"application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",};
intent.putExtra(Intent.EXTRA_MIME_TYPES, extraMimeTypes);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
startActivityForResult(intent, 201);
}else{
//Manage Data Received in ClipData clip
}
}
}
}

get Media metadata onActivityResult

I have to select video or image on chooser intent like this
Intent getIntent = new Intent(Intent.ACTION_GET_CONTENT);
getIntent.setType("image/* video/*");
Intent pickIntent = new Intent(Intent.ACTION_PICK);
pickIntent.setType("image/* video/*");
Intent chooserIntent = Intent.createChooser(getIntent, "Select Media");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent});
startActivityForResult(chooserIntent, 1);
Then I want to get the metadata of the file chosen in onActivityResult()
like height and width and length of the video and the size
Use this to get all your requirements.
MediaMetadataRetriever ret = new MediaMetadataRetriever();
Bitmap bmp = null;
try
{
ret.setDataSource("<<--Your retrieved data file-->>");
bmp = ret.getFrameAtTime();
videoHeight=bmp.getHeight();
videoWidth=bmp.getWidth();
videoSize = bmp.getAllocationByteCount()
}
Hope this helps, and let me know if any issue arises.

How to open document directory like whatsapp while sending a document... not an Image

I just wanted to open document directory with listing of all the documents only not images. I am using below code
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// The MIME data type filter
intent.setType("application/*");
// Only return URIs that can be opened with ContentResolver
intent.addCategory(Intent.CATEGORY_OPENABLE);
but it's working in a different way on other devices
try this
File file = new File(name);
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = "application/msword/pdf/vnd.ms-powerpoint/vnd.ms-excel";
intent.setDataAndType(Uri.fromFile(file), type);
startActivity(intent);
try this dude.
Intent intent = new Intent();
intent.setType("application/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select files"), 1);
Try this
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
String mimeType = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
intent.setDataAndType(Uri.fromFile(file), (extension.isEmpty() || mimeType == null) ? "text/*" : mimeType);
// custom message for the intent
startActivity(Intent.createChooser(intent, "Choose an Application:"));
Whatsapp displays his own document picker screen first, and if you click "Browse other docs..." It shows system UI document picker with below intent:
Intent reference: https://developer.android.com/training/data-storage/shared/documents-files
// Change according to your requirement
val mimeTypes = arrayOf(
"image/jpeg", // jpeg or jpg
"image/png", // png
"application/pdf", // pdf
"application/msword", // doc
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", // docx
"application/vnd.ms-excel", // xls
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // xlsx
"video/mp4", // mp4
"audio/mpeg", // mp3
)
private val filePickerLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult(), ::onFilePickerResult
)
private fun startFilePicker() {
val pickerIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
pickerIntent.addCategory(Intent.CATEGORY_OPENABLE)
pickerIntent.type = "*/*"
pickerIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
pickerIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
filePickerLauncher.launch(pickerIntent)
}
private fun onFilePickerResult(result: ActivityResult) {
if (result.resultCode != Activity.RESULT_OK) {
return
}
val multipleUriData = result.data?.clipData
val singleUri = result.data?.data
when {
multipleUriData != null -> {
for (i in 0 until multipleUriData.itemCount) {
val uri = multipleUriData.getItemAt(i).uri
//TODO: validateAndSendFile(uri)
}
}
singleUri != null -> {
//TODO: validateAndSendFile(singleUri)
}
else -> return
}
}

How to pick image or video on Android L?

I am using below code and it works fine below android 5. I am able to pick image or video from SD card.
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("video/* image/*");
getActivity().startActivityForResult(photoPickerIntent, 1);
However on Android L it shows only videos.
tried searching but didn't find anything, any help will be appreciated.
hi #Mohit you can use this solution for image and video
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("*/*");
getActivity().startActivityForResult(photoPickerIntent, 1);
for both image and video you can use setType(*/*);
here ACTION_GET_CONTENT is give only gallery selection while ACTION_PICK give many more options to pick image and video from different action, So as per #DipeshDhakal answer you should use only ACTION_GET_CONTENT.
and this is work on android L and api 10 also.
Use Intent.ACTION_GET_CONTENT
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
photoPickerIntent.setType("video/*, images/*");
startActivityForResult(photoPickerIntent, 1);
Was running into a similar issue. Code that worked on 5.0 and below started breaking on 5.1+, and only filtered by the first type passed in.
A co-worker came up the following, and I thought I'd share:
We were previously using the following intent:
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
i.setType("image/*,video/*");
and the following code to get the path from whatever the user selected, if anything:
public static String getFilePathFromURI(Uri imageUri, Activity context) {
String filePath = null;
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(imageUri,
filePathColumn, null, null, null);
if (cursor != null) {
try {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
} finally {
cursor.close();
}
}
return filePath;
}
Now:
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*");
String[] mimetypes = {"image/*", "video/*"};
i.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
And to get the path, the getPath function found in this answer:
https://stackoverflow.com/a/20559175/434400

Allowing User to select Image from camera and Gallery dose not work for installed app like Camera360

I'm newbie in Android development. Well my application allows the user to select images from a gallery and to captures image taken from camera. Well it works perfectly fine while picking an image from a gallery and Native Camera but it dose not work when picking an image from an installed app like Camera360. Can anyone help me with this issue.
Below is my code to show a options to select images from Gallery and camera
File root = new File(Environment.getExternalStorageDirectory() + File.separator + "Test" + File.separator);
if (!root.exists())
root.mkdirs();
String fname = "img_" + System.currentTimeMillis() + ".jpg";
File sdImageMainDirectory = new File(root, fname);
Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
List<Intent> cameraIntents = new ArrayList<Intent>();
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
PackageManager packageManager = getPackageManager();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
String packageName = res.activityInfo.packageName;
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
cameraIntents.add(intent);
}
// Filesystem.
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, PICK_IMAGE_REQUEST);
onActivityResult Method is implemeted below
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PICK_IMAGE_REQUEST) {
final boolean isCamera;
if (data == null) {
isCamera = true;
} else {
final String action = data.getAction();
if (action == null) {
isCamera = false;
} else
isCamera = action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
}
Bitmap yourSelectedImage;
if (isCamera) {
yourSelectedImage = BitmapFactory.decodeFile(outputFileUri.getPath());
} else {
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 filePath = cursor.getString(columnIndex);
cursor.close();
yourSelectedImage = BitmapFactory.decodeFile(filePath);
}
com.pkmmte.view.CircularImageView CircularImageView = (com.pkmmte.view.CircularImageView) findViewById(R.id.profileImage);
CircularImageView.setImageBitmap(yourSelectedImage);
}
}
}
The code works perfectly fine for both camera and gallery image picker. But it crashes for installed app like Camera360. Can some one help me regarding this
A Uri is not a file, and so you cannot pass it to decodeFile() on BitmapFactory. Your "pretend this Uri actually came from MediaStore" code will not work either.
Either use an image loading library like Picasso or Universal Image Loader, or have your own background thread that uses openInputStream() on a ContentResolver to read in the contents of that Uri, passing the stream to decodeStream() on BitmapFactory.
The code works perfectly fine for both camera and gallery image picker.
Only for the couple of cases that you tried. For example, if the "gallery image picker" returns an image that is on removable storage on Android 4.4+, even if you could get a filesystem path, you can't read it, as you don't have read access for arbitrary locations on removable storage.

Categories

Resources