142 votes

Sélectionnez plusieurs images dans la galerie Android

En gros, ce que j'essaie de faire, c'est d'ouvrir la Galerie sur Android et de permettre à l'utilisateur de sélectionner plusieurs images. Cette question a été posée fréquemment, mais je ne suis pas satisfait des réponses. Principalement parce que j'ai trouvé quelque chose d'intéressant dans la documentation de mon IDE (je reviendrai là-dessus plus tard) et donc je ne veux pas utiliser un adaptateur personnalisé mais juste celui par défaut.

Maintenant, mon code pour sélectionner une seule image est le suivant :

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Sélectionnez une image"), 1);

Maintenant, les gens sur SO et d'autres sites vous diront que vous avez 2 options :

1) Ne pas utiliser ACTION_GET_CONTENT mais plutôt ACTION_SEND_MULTIPLE à la place.
Cela ne fonctionne pas. Cela est selon la documentation pour envoyer des fichiers et non récupérer et c'est exactement ce qu'il fait. Lorsque j'utilise ACTION_SEND_MULTIPLE, une fenêtre s'ouvre sur mon appareil où je dois sélectionner une application pour envoyer mes données. Ce n'est pas ce que je veux, donc je me demande comment les gens ont réussi à le faire avec cette solution... Est-ce que je manque quelque chose ?

2) Implémenter une Galerie personnalisée. C'est ma dernière option que je considérerai car à mon avis, ce n'est pas ce que je recherche car je dois styliser moi-même ET pourquoi diable vous ne pouvez pas simplement sélectionner plusieurs images dans la galerie par défaut ?

Il doit y avoir une option pour cela... Maintenant, la chose intéressante que j'ai trouvée est la suivante :
_J'ai trouvé cela dans la description de ACTION_GET_CONTENT._

Si l'appelant peut gérer plusieurs éléments retournés (l'utilisateur effectue une sélection multiple), il peut spécifier EXTRA_ALLOW_MULTIPLE pour l'indiquer.

C'est assez intéressant. Ils y font référence au cas d'utilisation où un utilisateur peut sélectionner plusieurs éléments, non ?

Plus tard, ils disent dans la documentation :

Vous pouvez utiliser EXTRA_ALLOW_MULTIPLE pour permettre à l'utilisateur de sélectionner plusieurs éléments.

Donc c'est assez évident, n'est-ce pas ? C'est ce dont j'ai besoin. Mais ma question suivante est : Où puis-je mettre ce EXTRA_ALLOW_MULTIPLE ? La triste chose est que je ne le trouve nulle part dans le guide des développeurs Android et ce n'est pas non plus défini comme une constante dans la classe INTENT.

Est-ce que quelqu'un peut m'aider avec ce EXTRA_ALLOW_MULTIPLE ?

159voto

Kyle Shank Points 1655

L'option EXTRA_ALLOW_MULTIPLE est activée sur l'intention via la méthode Intent.putExtra() :

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

Votre code ci-dessus devrait ressembler à ceci :

Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Sélectionner une image"), 1);

Remarque: l'option EXTRA_ALLOW_MULTIPLE n'est disponible que dans Android API 18 et supérieur.

83voto

Laith Mihyar Points 891

Définissez ces variables dans la classe:

int PICK_IMAGE_MULTIPLE = 1; 
String imageEncoded;    
List imagesEncodedList;

Supposons que lors d'un clic sur un bouton, cela devrait ouvrir la galerie pour sélectionner des images

 Intent intent = new Intent();
 intent.setType("image/*");
 intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
 intent.setAction(Intent.ACTION_GET_CONTENT);
 startActivityForResult(Intent.createChooser(intent,"Sélectionner une image"), PICK_IMAGE_MULTIPLE);

Ensuite, vous devez remplacer la méthode onActivityResult

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    try {
        // Quand une image est sélectionnée
        if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == RESULT_OK
                    && null != data) {
            // Obtenir l'image à partir des données

            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            imagesEncodedList = new ArrayList();
            if(data.getData()!=null){

                Uri mImageUri=data.getData();

                // Obtenir le curseur
                Cursor cursor = getContentResolver().query(mImageUri,
                            filePathColumn, null, null, null);
                // Déplacer vers la première ligne
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                imageEncoded  = cursor.getString(columnIndex);
                cursor.close();

            } else {
                if (data.getClipData() != null) {
                    ClipData mClipData = data.getClipData();
                    ArrayList mArrayUri = new ArrayList();
                    for (int i = 0; i < mClipData.getItemCount(); i++) {

                        ClipData.Item item = mClipData.getItemAt(i);
                        Uri uri = item.getUri();
                        mArrayUri.add(uri);
                        // Obtenir le curseur
                        Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
                        // Déplacer vers la première ligne
                        cursor.moveToFirst();

                        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                        imageEncoded  = cursor.getString(columnIndex);
                        imagesEncodedList.add(imageEncoded);
                        cursor.close();

                    }
                    Log.v("LOG_TAG", "Images sélectionnées" + mArrayUri.size());
                }
            }
        } else {
            Toast.makeText(this, "Vous n'avez pas sélectionné d'image", Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        Toast.makeText(this, "Quelque chose s'est mal passé", Toast.LENGTH_LONG)
                    .show();
    }

    super.onActivityResult(requestCode, resultCode, data);
}

REMARQUE: la galerie ne vous donne pas la possibilité de sélectionner plusieurs images, donc nous ouvrons ici toutes les images du studio afin que vous puissiez sélectionner plusieurs images parmi elles. et n'oubliez pas d'ajouter les permissions dans votre manifeste

TRÈS IMPORTANT: getData(); pour obtenir une seule image et je l'ai stockée ici dans la chaîne imageEncoded si l'utilisateur sélectionne plusieurs images alors elles doivent être stockées dans la liste

Il faut donc vérifier laquelle est nulle pour utiliser l'autre

Bonne expérience à vous et aux autres

57voto

Mira_Cole Points 111

Beaucoup de ces réponses ont des similarités mais manquent toutes la partie la plus importante qui est dans onActivityResult, vérifiez si data.getClipData est nul avant de vérifier data.getData

Le code pour appeler le sélecteur de fichiers :

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*"); // permet n'importe quel type de fichier image. Changez * par une extension spécifique pour limiter
//**La ligne suivante est importante!
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Sélectionner une image"), SELECT_PICTURES); //SELECT_PICTURES est simplement un entier global utilisé pour vérifier l'intent d'appel dans onActivityResult

Le code pour obtenir toutes les images sélectionnées :

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == SELECT_PICTURES) {
        if(resultCode == Activity.RESULT_OK) {
            if(data.getClipData() != null) {
                int count = data.getClipData().getItemCount(); // évaluez le nombre avant la boucle for --- sinon, le nombre est évalué à chaque itération.
                for(int i = 0; i < count; i++) {
                    Uri imageUri = data.getClipData().getItemAt(i).getUri();
                    //faites quelque chose avec l'image (enregistrez-la dans un répertoire ou faites ce que vous avez à faire ici)
                } 
            }
        } else if(data.getData() != null) {
            String cheminImage = data.getData().getPath();
            //faites quelque chose avec l'image (enregistrez-la dans un répertoire ou faites ce que vous avez à faire ici)
        }
    }
}

Notez que le sélecteur d'Android dispose des options Photos et Galerie disponibles sur certains appareils. Photos permet de sélectionner plusieurs images. Galerie permet d'en sélectionner une à la fois.

20voto

R4j Points 2884

J'espère que cette réponse n'est pas en retard. Parce que le widget de galerie ne prend pas en charge la sélection multiple par défaut, mais vous pouvez personnaliser la gridview qui accepte votre intention de sélection multiple. L'autre option est d'étendre la vue de la galerie et d'ajouter votre propre code pour permettre la sélection multiple.
Cette simple bibliothèque peut le faire : https://github.com/luminousman/MultipleImagePick

Mise à jour:
D'après le commentaire de @ilsy, CustomGalleryActivity dans cette bibliothèque utilise manageQuery, qui est obsolète, donc il devrait être changé en getContentResolver().query() et cursor.close() comme cette réponse

8voto

Hasib Akter Points 3290

Initialiser l'instance :

private String imagePath;
private List imagePathList;

Dans onActivityResult, vous devez écrire ceci, le bloc If-else 2. Un pour une seule image et un autre pour plusieurs images.

if (requestCode == GALLERY_CODE && resultCode == RESULT_OK  && data != null) {

    imagePathList = new ArrayList<>();

    if (data.getClipData() != null) {

        int count = data.getClipData().getItemCount();
        for (int i=0; i

`

Partie la plus importante, Obtenir le chemin de l'image à partir de l'URI :

public void getImageFilePath(Uri uri) {

    File file = new File(uri.getPath());
    String[] filePath = file.getPath().split(":");
    String image_id = filePath[filePath.length - 1];

    Cursor cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
    if (cursor!=null) {
        cursor.moveToFirst();
        imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
        imagePathList.add(imagePath);
        cursor.close();
    }
}

J'espère que cela peut vous aider.

`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X