Autoriser l'utilisateur à sélectionner une caméra ou une galerie pour l'image


151

Ce que j'essaie de faire semble très simple, mais après quelques jours de recherche, je n'arrive pas à le comprendre.

J'ai une application qui permet à l'utilisateur de sélectionner plusieurs images (jusqu'à 5). J'utilise un ImageView. Lorsque l'utilisateur clique sur le ImageView, je souhaite lui permettre de

  1. Sélectionnez l'image dans la galerie, ou
  2. Utilisez l'appareil photo pour capturer une image.

J'ai commencé par utiliser l' ACTION_GET_CONTENTintention, et cela fonctionne bien pour accéder à la galerie. Alors j'ai essayé d'utiliser l' ACTION_PICK_ACTIVITYintention pour permettre à l'utilisateur de choisir une caméra ou une galerie:

Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
Intent gallIntent=new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*"); 
Intent camIntent = new Intent("android.media.action.IMAGE_CAPTURE");
pickIntent.putExtra(Intent.EXTRA_INTENT, camIntent);
pickIntent.putExtra(Intent.EXTRA_INTENT, gallIntent)
pickIntent.putExtra(Intent.EXTRA_TITLE, "Select Source");
startActivityForResult(pickIntent, IMAGE_SELECTOR);

Mais il semble que je ne puisse en ajouter qu'un EXTRA_INTENT. Le menu s'affiche comme prévu, mais les seules options sont Galerie et Fichiers .... pas de caméra).

Y a-t-il un moyen meilleur / plus simple de faire cela qui me manque? Merci pour toute aide.


Réponse similaire pour info, complémentaire à la réponse superlative de David ci-dessous. stackoverflow.com/a/11676554/294884 merci encore David de tout le monde !!!
Fattie

Jetez un œil à cette réponse avec une intention qui fusionne les deux demandes (Caméra et Galerie) dans une intention unique: stackoverflow.com/a/32475805/2232889
Mario Velasco

Simple: utilisez une bibliothèque comme celle-ci .
Vansuita Jr.

Réponses:


31

Vous devrez créer votre propre boîte de dialogue de sélection fusionnant les deux résultats de résolution d'intention.

Pour ce faire, vous devrez interroger le PackageManager avec PackageManager.queryIntentActivities () pour les deux intentions d'origine et créer la liste finale des intentions possibles avec une nouvelle intention pour chaque activité récupérée comme ceci:

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

(J'ai écrit ceci directement ici pour que cela ne se compile pas)

Ensuite, pour plus d'informations sur la création d'une boîte de dialogue personnalisée à partir d'une liste, voir https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog


321

Comment lancer une seule intention pour sélectionner des images de la Galerie ou de l'appareil photo, ou de toute application enregistrée pour parcourir le système de fichiers.

Plutôt que de créer une boîte de dialogue avec une liste d'options d'intention, il est préférable d'utiliser Intent.createChooser pour accéder aux icônes graphiques et aux noms courts des différentes applications de navigateur de système de fichiers `` Camera '', `` Gallery '' et même tiers. comme «Astro», etc.

Cela décrit comment utiliser l'intention de sélection standard et y ajouter des intentions supplémentaires.

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

12
Très bien! Juste une petite amélioration: dans le premier, isCamera = MediaStore.ACTION_IMAGE_CAPTURE.equals (data.getAction ()); Une ligne pour les gouverner tous;)
Glatzial

7
Dans mon cas final String fname = Utils.getUniqueImageFilename();ne fonctionne pas ... il dit Utils cannot be resolved:(
Shajeel Afzal

30
@Shajeel, Utils.getUniqueImageFilename()est ma propre méthode pour générer un nom de fichier unique. Il existe de nombreuses façons de procéder. L'un des plus simples consiste à utiliser quelque chose comme "img_"+ System.currentTimeMillis() + ".jpg". Un autre est File.createTempFile().
David Manpearl

10
Cela a très bien fonctionné pour moi, mais j'ai eu un problème où l'utilisation de la caméra comme source n'appelait pas surActivityResult et la caméra elle-même ne rejetait pas. La cause principale était une autorisation manquante dans le manifeste: <uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
BitsEvolved le

11
Comme l'a dit Rohan, cela est changé sur 5.1.1. Vous devrez faire if (data == null || data.getData() == null).
Ryan

22

J'ai trouvé ça . En utilisant:

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

pour l'une des intentions, l'utilisateur a la possibilité de sélectionner des «documents» dans Android 4, ce que j'ai trouvé très déroutant. Utiliser ceci à la place montre l'option 'galerie':

Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

cela fonctionne bien..mais lorsque nous parcourons l'image de la caméra, l'image portrait apparaît en mode paysage ..

@ user5060065 et d'autres ayant des problèmes avec l'orientation de l'image sélectionnée, consultez stackoverflow.com/a/6931373/1975002 pour obtenir l'orientation correcte, puis faites-la pivoter si nécessaire.
Michaël Polla

12

J'ai également eu ce problème et ce que j'ai fait a été de créer un AlertDialog et d'utiliser la méthode setItems () avec l'écouteur DialogInterface:

AlertDialog.Builder getImageFrom = new AlertDialog.Builder(Fotos.this);
getImageFrom.setTitle("Select:");
final CharSequence[] opsChars = {getResources().getString(R.string.takepic), getResources().getString(R.string.opengallery)};
getImageFrom.setItems(opsChars, new android.content.DialogInterface.OnClickListener(){

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if(which == 0){
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
        }else
            if(which == 1){
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
                    getResources().getString(R.string.pickgallery)), SELECT_PICTURE);
            }
        dialog.dismiss();
    }
});

11

J'ai fusionné quelques solutions pour créer un utilitaire complet pour choisir une image dans la galerie ou l'appareil photo. Voici les fonctionnalités de ImagePicker util (également dans une librairie Github ):

  • Intentions fusionnées pour les requêtes Galerie et Appareil photo.
  • Redimensionner les grandes images sélectionnées (par exemple: 2500 x 1600)
  • Faire pivoter l'image si nécessaire

Capture d'écran:

Intention de démarrage ImagePicker

Modifier : Voici un fragment de code pour obtenir une intention fusionnée pour les applications Galerie et Appareil photo. Vous pouvez voir le code complet sur ImagePicker util (également dans une bibliothèque Github ):

public static Intent getPickImageIntent(Context context) {
    Intent chooserIntent = null;

    List<Intent> intentList = new ArrayList<>();

    Intent pickIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePhotoIntent.putExtra("return-data", true);
    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context)));
    intentList = addIntentsToList(context, intentList, pickIntent);
    intentList = addIntentsToList(context, intentList, takePhotoIntent);

    if (intentList.size() > 0) {
        chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
                context.getString(R.string.pick_image_intent_text));
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
    }

    return chooserIntent;
}

private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) {
    List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0);
    for (ResolveInfo resolveInfo : resInfo) {
        String packageName = resolveInfo.activityInfo.packageName;
        Intent targetedIntent = new Intent(intent);
        targetedIntent.setPackage(packageName);
        list.add(targetedIntent);
    }
    return list;
}

1
Cela fonctionne vraiment bien. Merci. Le seul problème que je rencontre est que les photos prises avec l'appareil photo en mode portrait apparaissent en mode paysage. Que dois-je faire pour obtenir la rotation des images requises?
365SplendidSuns

@ 365SplendidSuns Pouvez-vous vérifier s'il entre dans la méthode getRotationFromCamera( ImagePicker.java) et quelle valeur il renvoie? Sur quel téléphone testez-vous?
Mario Velasco

J'utilise un Sony Experia C et l'émulateur Android Studio. Je viens de mettre quelques points d'arrêt pour vérifier les choses que vous avez posées et il semble que le booléen isCamera soit faux dans la méthode getRotation qui empêche l'appel de getRotationFromCamera.
365SplendidSuns

Quelle version d'Android essayez-vous? J'ai ajouté une modification la semaine dernière sur la ligne 58, vérifiez si elle l'a résolue:boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
Mario Velasco

Ok, l'émulateur est la version 6.0 et il semble que la ligne 58 fonctionne bien là-dessus. Sur l'émulateur, isCamera est vrai et getRotationFromCamera est appelé bien mais l'orientation int est 0, ce qui signifie que getRotationFromCamera renvoie 0 ... L'appareil Sony utilise Android 4.2 et sur celui-ci ni imageReturnedIntent ni imageReturnedIntent.getData () ne sont nuls sur la ligne 58 ce qui signifie que isCamera est faux et je ne vais pas jusqu'à appeler getRotationFromCamera.
365SplendidSuns

8

ce code vous aidera, en ce sens qu'il y a deux boutons un pour l'appareil photo et un autre pour la galerie, et l'image sera affichée dans ImageView

https://github.com/siddhpuraamitr/Choose-Image-From-Gallery-Or-Camera


5
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change
MrEngineer13

6

Pour ceux qui obtiennent une erreur sur 4.4 à la hausse en essayant d'utiliser la sélection d'image, vous pouvez utiliser le code ci-dessous.

Plutôt que de créer une boîte de dialogue avec une liste d'options d'intention, il est préférable d'utiliser Intent.createChooser pour accéder aux icônes graphiques et aux noms courts des différentes applications de navigateur de système de fichiers `` Camera '', `` Gallery '' et même tiers. comme «Astro», etc.

Cela décrit comment utiliser l'intention de sélection standard et y ajouter des intentions supplémentaires.

private void openImageIntent(){

    // Determine Uri of camera image to save.
    final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "amfb" + File.separator);
    root.mkdir();
    final String fname = "img_" + System.currentTimeMillis() + ".jpg";
    final File sdImageMainDirectory = new File(root, fname);
    outputFileUri = Uri.fromFile(sdImageMainDirectory);

    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(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(res.activityInfo.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[]{}));
    startActivityForResult(chooserIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == CAMERA_CAPTURE_IMAGE_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(MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;
            if (isCamera) {
                selectedImageUri = outputFileUri;
                //Bitmap factory
                BitmapFactory.Options options = new BitmapFactory.Options();
                // downsizing image as it throws OutOfMemory Exception for larger
                // images
                options.inSampleSize = 8;
                final Bitmap bitmap = BitmapFactory.decodeFile(selectedImageUri.getPath(), options);
                preview.setImageBitmap(bitmap);
            } else {
                selectedImageUri = data == null ? null : data.getData();
                Log.d("ImageURI", selectedImageUri.getLastPathSegment());
                // /Bitmap factory
                BitmapFactory.Options options = new BitmapFactory.Options();
                // downsizing image as it throws OutOfMemory Exception for larger
                // images
                options.inSampleSize = 8;
                try {//Using Input Stream to get uri did the trick
                    InputStream input = getContentResolver().openInputStream(selectedImageUri);
                    final Bitmap bitmap = BitmapFactory.decodeStream(input);
                    preview.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    } else if (resultCode == RESULT_CANCELED){
        // user cancelled Image capture
        Toast.makeText(getApplicationContext(),
                "User cancelled image capture", Toast.LENGTH_SHORT)
                .show();
    } else {
        // failed to capture image
        Toast.makeText(getApplicationContext(),
                "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                .show();
    }
}

Salut. J'ai essayé votre solution, mais choisir une photo de gallary ne fonctionne pas: jetez un œil ici: stackoverflow.com/questions/36884651

Sur mon appareil à guimauve, cela gâche lors de l'utilisation de l'appareil photo. pour moi, les données ne sont pas nulles, mais l'action est, provoquant la définition de isCamera sur false.
JStephen

6

Cela devrait résoudre le problème null outputFileUri de Tina:

private static final String STORED_INSTANCE_KEY_FILE_URI = "output_file_uri";

@Override
public void onSaveInstanceState( Bundle outState ) {
    super.onSaveInstanceState( outState );

    if ( outputFileUri != null ) {
        outState.putString( STORED_INSTANCE_KEY_FILE_URI, outputFileUri.toString() );
    }
}

@Override
public void onViewStateRestored( Bundle savedInstanceState ) {
    super.onViewStateRestored( savedInstanceState );

    if ( savedInstanceState != null ) {
      final String outputFileUriStr = savedInstanceState.getString( STORED_INSTANCE_KEY_FILE_URI );
      if ( outputFileUriStr != null && !outputFileUriStr.isEmpty() ) {
          outputFileUri = Uri.parse( outputFileUriStr );
      }
    }
}

Remarque: j'utilise ce code dans android.support.v4.app.Fragment vos méthodes remplacées peuvent changer en fonction de la version de Fragment / Activité que vous utilisez.


5

Vous pouvez créer une boîte de dialogue d'options

Ouvrir la caméra:

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                                MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
                        if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
                            startActivityForResult(cameraIntent, CAMERA_IMAGE);
                        }

Ouvrir la galerie:

if (Build.VERSION.SDK_INT <= 19) {
            Intent i = new Intent();
            i.setType("image/*");
            i.setAction(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            startActivityForResult(i, GALLARY_IMAGE);
        } else if (Build.VERSION.SDK_INT > 19) {
            Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, GALLARY_IMAGE);
        }

Pour obtenir le résultat de la sélection

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == GALLARY_IMAGE) {
                Uri selectedImageUri = data.getData();
                String selectedImagePath = getRealPathFromURI(selectedImageUri);
            } else if (requestCode == CAMERA_IMAGE) {
                Bundle extras = data.getExtras();
                Bitmap bmp = (Bitmap) extras.get("data");
                SaveImage(bmp);
            }
        }
    }

 public String getRealPathFromURI(Uri uri) {
        if (uri == null) {
            return null;
        }
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
        if (cursor != null) {
            int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
        return uri.getPath();
    }

Méthode pour enregistrer l'image capturée

 private void SaveImage(final Bitmap finalBitmap) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                String root = Environment.getExternalStorageDirectory().toString();

                File myDir = new File(root + "/Captured Images/");
                if (!myDir.exists())
                    myDir.mkdirs();

                String fname = "/image-" + System.currentTimeMillis() + ".jpg";
                File file = new File(myDir, fname);
                try {
                    FileOutputStream out = new FileOutputStream(file);
                    finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
                    out.flush();
                    out.close();
                    localImagePath = myDir + fname;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


        });
        t.start();

    }

2

Problème d'image trop gros résolu et éviter de manquer de mémoire.

    private static final int SELECT_PICTURE = 0;
    private static final int REQUEST_CAMERA = 1;
    private ImageView mImageView;

    private void selectImage() {
        final CharSequence[] items = {"Take Photo", "Choose from Library",
                "Cancel"};
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        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(), "temp.jpg");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                    startActivityForResult(intent, REQUEST_CAMERA);
                } else if (items[item].equals("Choose from Library")) {
                    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_PICTURE);
                } else if (items[item].equals("Cancel")) {
                    dialog.dismiss();
                }
            }
        });
        builder.show();
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_CAMERA) {
                File f = new File(Environment.getExternalStorageDirectory()
                        .toString());
                for (File temp : f.listFiles()) {
                    if (temp.getName().equals("temp.jpg")) {
                        f = temp;
                        break;
                    }
                }
                try {
                    Bitmap bm;
                    BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
                    btmapOptions.inSampleSize = 2;
                    bm = BitmapFactory.decodeFile(f.getAbsolutePath(),
                            btmapOptions);

                    // bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
                    mImageView.setImageBitmap(bm);

                    String path = android.os.Environment
                            .getExternalStorageDirectory()
                            + File.separator
                            + "test";
                    f.delete();
                    OutputStream fOut = null;
                    File file = new File(path, String.valueOf(System
                            .currentTimeMillis()) + ".jpg");
                    fOut = new FileOutputStream(file);
                    bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                    fOut.flush();
                    fOut.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                String tempPath = getPath(selectedImageUri, this.getActivity());
                Bitmap bm;
                btmapOptions.inSampleSize = 2;
                BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
                bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
                mImageView.setImageBitmap(bm);
            }
        }
    }
    public String getPath(Uri uri, Activity activity) {
        String[] projection = {MediaStore.MediaColumns.DATA};
        Cursor cursor = activity
                .managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

1

Ajout de ma solution - il renverra un rappel, que ce soit de la caméra ou de la cuisine à côté de l'intention:

public class ImagePickerManager extends BaseAdapter {

private List<ResolveInfo> mApplications;
private TreeSet<Integer> mImageCaptureIntents;
private TreeSet<Integer> mImagePickerIntents;
private Context mContext;
private final ImagePickerManagerListener listener;

private static enum intentType {
    choosePhoto,
    takePhoto,
    unknown;

    public int getIntValue() {
        switch (this) {
            case choosePhoto:
                return 0;
            case takePhoto:
                return 1;
            case unknown:
                return 2;
        }
        return 0;
    }
}

public interface ImagePickerManagerListener {
    void onChooseImage(Intent intent);
    void onCaptureImage(Intent intent);
}

public ImagePickerManager(Context context,ImagePickerManagerListener listenr) {
    this.mContext = context;
    this.listener = listenr;

    mImageCaptureIntents = new TreeSet<>();
    mImagePickerIntents = new TreeSet<>();

    //Picking photo intent
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    mApplications = mContext.getPackageManager().queryIntentActivities(intent, 0);

    int index = 0;
    for (int i = 0; i < mApplications.size(); i++) {
        mImagePickerIntents.add(index);
        index++;
    }

    //Capture photo intent
    intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    List<ResolveInfo> resolveInfoList = mContext.getPackageManager().queryIntentActivities(intent, 0);
    mApplications.addAll(resolveInfoList);
    for (int i = 0; i < mApplications.size(); i++) {
        mImageCaptureIntents.add(index);
        index++;
    }
}

public static void openChooseAndCaptureImageDialog(final Context context, final ImagePickerManagerListener listener) {

    Log.d("openChooseAndCaptureImageDialog", "enter");

    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    final ImagePickerManager imagePickerManager = new ImagePickerManager(context,listener);
    builder.setTitle(context.getString(R.string.image_picker_dialog_box_title));
    builder.setAdapter(imagePickerManager, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialoginterface, int i) {
            ResolveInfo resolveInfo = (ResolveInfo) imagePickerManager.getItem(i);
            Intent pickerIntent = imagePickerManager.getIntentForPackage(context,resolveInfo,i);
            switch (imagePickerManager.getIntentType(i)){
                case choosePhoto:
                    listener.onChooseImage(pickerIntent);
                    break;
                case takePhoto:
                    listener.onCaptureImage(pickerIntent);
                    break;
                case unknown:
                    break;
            }
        }
    });

    builder.setCancelable(true);
    builder.setInverseBackgroundForced(true);
    AlertDialog dialog = builder.create();
    dialog.show();
}


private intentType getIntentType(int index) {

    if (mImageCaptureIntents.contains(index)) {
       return intentType.takePhoto;
    } else if(mImagePickerIntents.contains(index)) {
        return intentType.choosePhoto;
    }
    return intentType.unknown;
}

private Intent getIntentForPackage(Context context, ResolveInfo info,int index) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(info.activityInfo.packageName);

    ComponentName chosenName = new ComponentName(
            info.activityInfo.packageName,
            info.activityInfo.name);

    intent.setComponent(chosenName);
    intent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
    if (mImageCaptureIntents.contains(index)) {
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
    } else if(mImagePickerIntents.contains(index)) {
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_PICK);
    }
    return intent;
}

@Override
public int getCount() {
    return mApplications.size();
}

@Override
public Object getItem(int position) {
    return mApplications.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ResolveInfo item = mApplications.get(position);
    if (convertView == null) {
        TextView applicationTextView = new TextView(mContext);
        LayoutParams param = new LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT);
        applicationTextView.setLayoutParams(param);
        final int horizontalPadding = (int) FVRGeneralUtils.convertDpToPx(mContext, 15);
        final int verticalPadding = (int) FVRGeneralUtils.convertDpToPx(mContext, 5);
        applicationTextView.setPadding(horizontalPadding,verticalPadding, horizontalPadding, verticalPadding);
        applicationTextView.setGravity(android.view.Gravity.CENTER_VERTICAL);
        Resources.Theme th = mContext.getTheme();
        TypedValue tv = new TypedValue();

        if (th.resolveAttribute(android.R.attr.textAppearanceMedium, tv, true)) {
            applicationTextView.setTextAppearance(mContext, tv.resourceId);
        }

        applicationTextView.setMinHeight((int) FVRGeneralUtils.convertDpToPx(mContext, 25));
        applicationTextView.setCompoundDrawablePadding((int) FVRGeneralUtils.convertDpToPx(mContext, 7));
        convertView = applicationTextView;
    }

    TextView textView = (TextView) convertView;
    textView.setText(item.loadLabel(mContext.getPackageManager()));
    textView.setCompoundDrawablesWithIntrinsicBounds(item.loadIcon(mContext.getPackageManager()), null, null, null);
    return textView;
} }

1

Vous pouvez essayer ceci:

Pour ouvrir la galerie:

private void browseImage() {

        try {
  Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
  startActivityForResult(galleryIntent, GALLERY_IMAGE_PICK); //GALLERY_IMAGE_PICK it is a string
  } catch (Exception e) {}
     }

Pour ouvrir l'appareil photo:

 private void captureImage() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

    // start the image capture Intent

    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

}

1
C'est une pâte venue d'ailleurs sur SO. Par exemple, que fait getOutputMediaFileUri? Veuillez partager des exemples complets, accompagnés d'explications.
kilokahn

0

C'est simple en utilisant AlertDialog et Intent.ACTION_PICK

    //camOption is a string array contains two items (Camera, Gallery)
    AlertDialog.Builder builder = new AlertDialog.Builder(CarPhotos.this);
    builder.setTitle(R.string.selectSource)
    .setItems(R.array.imgOption, new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which)

     {

        if (which==0) {
        Intent intent = new Intent(this, CameraActivity.class);
        startActivityForResult(intent, REQ_CAMERA_IMAGE);               }

        if (which==1) {
        Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, RESULT_LOAD_IMAGE);
            }

     }
            });
             builder.create();
             builder.show();

0

S'appuyant sur la réponse de David, mes deux sous de la onActivityResult()part. Il prend en charge les changements introduits dans 5.1.1 et détecte si l'utilisateur a sélectionné une ou plusieurs images de la bibliothèque.

private enum Outcome {
    camera, singleLibrary, multipleLibrary, unknown
}

/**
 * Returns a List<Uri> containing the image uri(s) chosen by the user
 *
 * @param data      The data intent coming from the onActivityResult()
 * @param cameraUri The uri that had been passed to the intent when the chooser was invoked.
 * @return A List<Uri>, never null.
 */
public List<Uri> getPicturesUriFromIntent(Intent data, Uri cameraUri) {

    Outcome outcome = Outcome.unknown;

    if (data == null || (data.getData() == null && data.getClipData() == null)) {
        outcome = Outcome.camera;
    } else if (data.getData() != null && data.getClipData() == null) {
        outcome = Outcome.singleLibrary;
    } else if (data.getData() == null) {
        outcome = Outcome.multipleLibrary;
    } else {
        final String action = data.getAction();
        if (action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
            outcome = Outcome.camera;
        }
    }

    // list the uri(s) we got back
    List<Uri> uris = new ArrayList<>();
    switch (outcome) {
        case camera:
            uris.add(cameraUri);
            break;

        case singleLibrary:
            uris.add(data.getData());
            break;

        case multipleLibrary:
            final ClipData clipData = data.getClipData();
            for (int i = 0; i < clipData.getItemCount(); i++) {
                ClipData.Item item = clipData.getItemAt(i);
                uris.add(item.getUri());
            }
            break;
    }

    return uris;
}

0

Essayez de cette façon

final CharSequence[] items = { "Take Photo", "Choose from Library",
            "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(), "temp.jpg");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                startActivityForResult(intent, REQUEST_CAMERA);
            } else if (items[item].equals("Choose from Library")) {
                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();

Ensuite, créez une méthode onactivityresult et faites quelque chose comme ça

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == REQUEST_CAMERA) {
            File f = new File(Environment.getExternalStorageDirectory()
                    .toString());
            for (File temp : f.listFiles()) {
                if (temp.getName().equals("temp.jpg")) {
                    f = temp;
                    break;
                }
            }
            try {
                Bitmap bm;
                BitmapFactory.Options btmapOptions = new BitmapFactory.Options();

                bm = BitmapFactory.decodeFile(f.getAbsolutePath(),
                        btmapOptions);

                // bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
                ivImage.setImageBitmap(bm);

                String path = android.os.Environment
                        .getExternalStorageDirectory()
                        + File.separator
                        + "Phoenix" + File.separator + "default";
                f.delete();
                OutputStream fOut = null;
                File file = new File(path, String.valueOf(System
                        .currentTimeMillis()) + ".jpg");
                try {
                    fOut = new FileOutputStream(file);
                    bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                    fOut.flush();
                    fOut.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (requestCode == SELECT_FILE) {
            Uri selectedImageUri = data.getData();

            String tempPath = getPath(selectedImageUri, MainActivity.this);
            Bitmap bm;
            BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
            bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
            ivImage.setImageBitmap(bm);
        }
    }
}

Voir ceci http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample


0

Sélection de la caméra ou de la galerie pour l'image sous Android

J'avais travaillé dur sur la sélection d'images de la caméra ou de la galerie et créé une classe utilitaire pour ce travail. Avec l'utilisation de ces classes «Sélectionner une caméra ou une galerie d'images est trop facile», il vous a suffi de 5 à 10 minutes de votre développement.

Étape 1: ajoutez ces classes dans votre code.

ImagePickerUtils: - http://www.codesend.com/view/f8f7c637716bf1c693d1490635ed49b3/

BitmapUtils: - http://www.codesend.com/view/81c1c2a3f39f1f7e627f01f67be282cf/

ConvertUriToFilePath: - http://www.codesend.com/view/f4668a29860235dd1b66eb419c5a58b5/

MediaUtils: - https://codeshare.io/5vKEMl

Nous devons ajouter ces autorisations dans menifest:

  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-feature android:name="android.hardware.camera" />
  <uses-feature android:name="android.hardware.camera.autofocus" />

Cette fonction de classe (checkAndRequestPermissions) vérifie automatiquement l'autorisation dans Android-Marshmallow et Android - Nougat.

Étape 2. Appel de la classe de caméra pour lancer l'intention de la caméra:

 //Create a global veriable .  
     private Uri mCameraUri;
     private static final int CAMERA_REQUEST_CODE = 100;

// Call this function when you wants to select or capture an Image.
       mCameraUri = ImagePickerUtils.createTakePictureIntent(this, CAMERA_REQUEST_CODE);

Étape 3: Ajoutez onActivityResult à votre activité pour recevoir des données d'Intent

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            Uri fileUri = ImagePickerUtils.getFileUriOfImage(this, data, mCameraUri);
            try {
                Bitmap bitmap = null;
                if (CAMERA_REQUEST_CODE == requestCode) {
                    bitmap = new BitmapUtils().getDownsampledBitmap(this, fileUri, imageView.getWidth(), imageView.getHeight());
                }
                if (bitmap != null)
                imageView.setImageBitmap(bitmap);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

J'espère que cela vous aidera.Si quelqu'un a des suggestions pour améliorer ces cours, veuillez ajouter votre avis dans les commentaires.


Il a un problème. Où se trouve la classe MediaUtils utilisée dans BitmapUtils et dans ImagePickerUtils?
Roger RV

@RogerRV, merci de m'avoir prévenu, je viens de mettre à jour la réponse avec un nouveau fichier de classe.
A-Droid Tech

Merci à vous je vais le vérifier maintenant. J'ai essayé de le résoudre moi-même, cela fonctionne mais pas du tout
Roger RV

0

Selon la réponse de David Manpearl
https://stackoverflow.com/a/12347567/7226732

il suffit de modifier onActivityResult () comme

 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.getExtras() == 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 = fileUri;
                try {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
                    Toast.makeText(CreateWaterType.this, "Image Saved!", Toast.LENGTH_SHORT).show();
                    image_view.setImageBitmap(bitmap);

                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(CreateWaterType.this, "Failed!", Toast.LENGTH_SHORT).show();
                }

            } else {
                selectedImageUri = data == null ? null : data.getData();
                try {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);

                    Toast.makeText(CreateWaterType.this, "Image Saved!", Toast.LENGTH_SHORT).show();
                    image_view.setImageBitmap(bitmap);

                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(CreateWaterType.this, "Failed!", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}

et définissez la capture ou choisissez des images dans la vue image.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.