Intención de elegir entre la cámara o la galería en Android

Estoy tratando de lanzar una intención de recoger una imagen de la cámara o la galería del android. He comprobado este post y actualmente mi código está cerca de trabajar:

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); } } 

Cuando establezco allowCamera = true funciona correctamente.

Cuando establezco allowGallery = true, muestra el siguiente selector:

Introduzca aquí la descripción de la imagen

Pero si establezco allowCamera = true y allowGallery = true el selector mostrado es:

Introduzca aquí la descripción de la imagen

Y si selecciona Android System aparecerá el primer selector.

Me gustaría que el selector fuera algo así como:

Introduzca aquí la descripción de la imagen

¿Cómo puedo "expandir" la opción del Android System ?

En su publicación enlazada puede encontrar la solución. La diferencia con tu código es cómo se crea la intención de la galería:

 final Intent galleryIntent = new Intent(); galleryIntent.setType("image/*"); galleryIntent.setAction(Intent.ACTION_GET_CONTENT); 

No con ACTION_PICK como lo hiciste pero con ACTION_GET_CONTENT . Parece que si un solo ACTION_PICK está en la lista (una "intención de contenedor"), el sistema lo atraviesa para mostrar el contenido de la selección, pero tan pronto como incluya la intención de la cámara no puede atravesar más (ya que hay una Intención directa y una intención de contenedor).

En el comentario de esta respuesta encontrará la diferencia entre ACTION_PICK y ACTION_GET_CONTENT .

Hay algunas soluciones disponibles que recomiendan utilizar un diálogo personalizado. Sin embargo, este cuadro de diálogo no tendrá los iconos de normas (consulte los documentos de desarrollador aquí ). Así que recomiendo permanecer en su solución y sólo solucionar el problema de jerarquía.

 ## 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(); } } 
  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); 

Puede que tenga que crear un cuadro de diálogo personalizado para esto:

Aquí está el código para el método que se va a llamar cuando el usuario hace clic en un botón en particular:

 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(); } 

Y el código para manejar 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: Intente usar esto:

 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); } 
  • ¿Es la agrupación de objetos pequeños más eficiente que el recolector de basura Java de Android?
  • Coordenadas no correspondientes
  • Convertir valor de color entero en RGB
  • Prueba de una clase Fragment en aislamiento usando Mockito
  • ¿Por qué getExternalStorageDirectory devuelve el almacenamiento raíz de mi teléfono, no la tarjeta SD?
  • Cuándo instalar keystore & cuándo instalar sólo el certificado envuelto en keystore
  • ¿Cómo activar el desplazamiento rápido (pulgar) en el menú desplegable de Android Spinner?
  • Cómo hacer HorizontalScrollView RIGHT a LEFT Scroll android
  • Gson, cómo deserializar matriz o cadena vacía
  • Solicitud de Https, autenticación en Android
  • Detección de círculos de Hough android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.