Allow user to select camera or gallery for image
How to launch a single Intent to select images from either the Gallery or the Camera, or any application registered to browse the filesystem.
Rather than creating a Dialog with a list of Intent options, it is much better to use Intent.createChooser in order to get access to the graphical icons and short names of the various 'Camera', 'Gallery' and even Third Party filesystem browser apps such as 'Astro', etc.
This describes how to use the standard chooser-intent and add additional intents to that.
private Uri outputFileUri;
private void openImageIntent() {
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
root.mkdirs();
final String fname = Utils.getUniqueImageFilename();
final File sdImageMainDirectory = new File(root, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
startActivityForResult(chooserIntent, YOUR_SELECT_PICTURE_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == YOUR_SELECT_PICTURE_REQUEST_CODE) {
final boolean isCamera;
if (data == null) {
isCamera = true;
} else {
final String action = data.getAction();
if (action == null) {
isCamera = false;
} else {
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if (isCamera) {
selectedImageUri = outputFileUri;
} else {
selectedImageUri = data == null ? null : data.getData();
}
}
}
}
You'll have to create your own chooser dialog merging both intent resolution results.
To do this, you will need to query the PackageManager with PackageManager.queryIntentActivities() for both original intents and create the final list of possible Intents with one new Intent for each retrieved activity like this:
List<Intent> yourIntentsList = new ArrayList<Intent>();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(camIntent, 0);
for (ResolveInfo res : listCam) {
final Intent finalIntent = new Intent(camIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
yourIntentsList.add(finalIntent);
}
List<ResolveInfo> listGall = packageManager.queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
final Intent finalIntent = new Intent(gallIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
yourIntentsList.add(finalIntent);
}
(I wrote this directly here so this may not compile)
Then, for more info on creating a custom dialog from a list see https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog