I'm trying to launch an intent to pick a image from the camera or the android's gallery. I checked THIS post and currently my code is near to work:
private Intent getPickIntent() {
final List<Intent> intents = new ArrayList<Intent>();
if (allowCamera) {
setCameraIntents(intents, cameraOutputUri);
}
if (allowGallery) {
intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
}
if (intents.isEmpty()) return null;
Intent result = Intent.createChooser(intents.remove(0), null);
if (!intents.isEmpty()) {
result.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[] {}));
}
return result;
}
private void setCameraIntents(List<Intent> cameraIntents, Uri output) {
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = context.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(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
cameraIntents.add(intent);
}
}
When I set allowCamera=true
it works correctly.
When I set allowGallery=true
it shows the following chooser:
But if I set allowCamera=true
and allowGallery =true
the chooser shown is:
And if you select Android System
then the first chooser is shown.
I'd like the chooser to be something like:
How can I "expand" the Android System
option?
Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
galleryintent.setType("image/*");
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
chooser.putExtra(Intent.EXTRA_TITLE, "Select from:");
Intent[] intentArray = { cameraIntent };
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooser, REQUEST_PIC);
You may need to create a custom dialog for this:
Here is the code for the method which is to be called when the user clicks on a particular button:
private void ChooseGallerOrCamera() {
final CharSequence[] items = { "Take Photo", "Choose from Gallery",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "MyImage.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, REQUEST_CAMERA);
} else if (items[item].equals("Choose from Gallery")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(
Intent.createChooser(intent, "Select File"),
SELECT_FILE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
And the code for handling onActivityResult()
:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Bitmap mBitmap;
if (requestCode == REQUEST_CAMERA) {
File camFile = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : camFile.listFiles()) {
if (temp.getName().equals("MyImage.jpg")) {
camFile = temp;
break;
}
}
try {
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
mBitmap = BitmapFactory.decodeFile(camFile.getAbsolutePath(),
btmapOptions);
//Here you have the bitmap of the image from camera
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == SELECT_FILE) {
Uri selectedImageUri = data.getData();
String tempPath = getPath(selectedImageUri, MyActivity.this);
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
mBitmap = BitmapFactory.decodeFile(tempPath, btmapOptions);
//Here you have the bitmap of the image from gallery
}
}
}
public String getPath(Uri uri, Activity activity) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = activity
.managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
EDIT: Try Using this:
private void letUserTakeUserTakePicture() {
Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getTempFile(getActivity())));
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takePhotoIntent});
startActivityForResult(chooserIntent, Values.REQ_CODE_TAKEPICTURE);
}
In your linked post you can find the solution. The difference to your code is how the gallery intent is created:
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
Not with ACTION_PICK
how you did but with ACTION_GET_CONTENT
. It seems that if a single ACTION_PICK
is in the list (a "container intent"), the system traverses it to display the content of the pick, but as soon you include the camera intent it can't traverse anymore (since there is one direct intent and one container intent).
In the comment of this answer you find the difference between ACTION_PICK
and ACTION_GET_CONTENT
.
There are some solutions available which recommend to use a custom dialog. But this dialog will not have the standards icons (see develper docs here). So I recommend to stay at your solution and just fix the hierarchie issue.
## Intent to choose between Camera and Gallery Heading and can crop image after capturing from camera ##
public void captureImageCameraOrGallery() {
final CharSequence[] options = { "Take photo", "Choose from library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(
Post_activity.this);
builder.setTitle("Select");
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
if (options[which].equals("Take photo")) {
try {
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, TAKE_PICTURE);
} catch (ActivityNotFoundException ex) {
String errorMessage = "Whoops - your device doesn't support capturing images!";
}
} else if (options[which].equals("Choose from library")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ACTIVITY_SELECT_IMAGE);
} else if (options[which].equals("Cancel")) {
dialog.dismiss();
}
}
});
dialog = builder.create();
dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
dialog.show();
}
public void onActivityResult(int requestcode, int resultcode, Intent intent) {
super.onActivityResult(requestcode, resultcode, intent);
if (resultcode == RESULT_OK) {
if (requestcode == TAKE_PICTURE) {
picUri = intent.getData();
startCropImage();
} else if (requestcode == PIC_CROP) {
Bitmap photo = (Bitmap) intent.getExtras().get("data");
Drawable drawable = new BitmapDrawable(photo);
backGroundImageLinearLayout.setBackgroundDrawable(drawable);
} else if (requestcode == ACTIVITY_SELECT_IMAGE) {
Uri selectedImage = intent.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage, filePath,
null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
Drawable drawable = new BitmapDrawable(thumbnail);
backGroundImageLinearLayout.setBackgroundDrawable(drawable);
}
}
}
private void startCropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
// indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, PIC_CROP);
} catch (ActivityNotFoundException anfe) {
// display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast
.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With