Intention to choose between camera or gallery in Android

I am trying to launch an intent to select an image from an Android camera or gallery. I checked this post and currently my code is close 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:

enter image description here

But if I set allowCamera=true and allowGallery =true following allowGallery =true shown:

enter image description here

And if you select Android System , the first choice will be shown.

I would like the choice to be something like this:

enter image description here

How can I “extend” the Android System option?

+11
java android android-intent
source share
6 answers

In your related message you can find a solution. The difference with 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 , as you did, but with ACTION_GET_CONTENT . It seems that if there is one ACTION_PICK (“container intent”) in the list, the system moves to display the contents of the collection, but as soon as you turn on the camera’s intention, it can no longer pass (since there is one direct intention and one container intention).

In the comment of this answer you will find the difference between ACTION_PICK and ACTION_GET_CONTENT .

There are several solutions available that recommend using a custom dialog. But there will be no standards icons in this dialog box (see Develter docs here ). Therefore, I recommend stopping at your decision and simply fixing the hierarchy problem.

+7
source share
  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); 
+7
source share
 ## 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(); } } 
+3
source share

You may need to create a custom dialog for this:

Here is the code for the method that should be called when the user clicks on a specific 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 to handle 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); } 
+1
source share

The intention to show the camera and video files in the activity selection window:

  Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null); galleryintent.setType("video/*"); Intent cameraIntent = new Intent(MediaStore.ACTION_VIDEO_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_VIDEO_CAPTURE); 
0
source share

Your code has already very achieved the goal. Just swap the gallery and add camera order.

 if (allowGallery) { intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)); } if (allowCamera) { setCameraIntents(intents, cameraOutputUri); } 

Here is my test result. The difference in appearance, since my OS is Android Nougat (7.0)

The first screenshot in your order, the second after the exchange. As you said, in the first situation, click on the system logo to see the gallery elements.

enter image description here enter image description here

0
source share

All Articles