web-dev-qa-db-fra.com

android - enregistrer l'image dans la galerie

j'ai une application avec une galerie d'images et je veux que l'utilisateur puisse l'enregistrer dans sa propre galerie. J'ai créé un menu d'options avec une seule voix "enregistrer" pour permettre cela, mais le problème est ... comment puis-je enregistrer l'image dans la galerie?

c'est mon code:

@Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle item selection
            switch (item.getItemId()) {
            case R.id.menuFinale:

                imgView.setDrawingCacheEnabled(true);
                Bitmap bitmap = imgView.getDrawingCache();
                File root = Environment.getExternalStorageDirectory();
                File file = new File(root.getAbsolutePath()+"/DCIM/Camera/img.jpg");
                try 
                {
                    file.createNewFile();
                    FileOutputStream ostream = new FileOutputStream(file);
                    bitmap.compress(CompressFormat.JPEG, 100, ostream);
                    ostream.close();
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }



                return true;
            default:
                return super.onOptionsItemSelected(item);
            }
        }

je ne suis pas sûr de cette partie du code:

File root = Environment.getExternalStorageDirectory();
                File file = new File(root.getAbsolutePath()+"/DCIM/Camera/img.jpg");

est-il correct d'enregistrer dans la galerie? malheureusement, le code ne fonctionne pas :(

78
Christian Giupponi
MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);

L'ancien code ajoutera l'image à la fin de la galerie. Si vous souhaitez modifier la date afin qu'elle apparaisse au début ou dans une autre métadonnée, reportez-vous au code ci-dessous (Cortesy of S-K, samkirton ):

https://Gist.github.com/samkirton/0242ba81d7ca00b475b9

/**
 * Android internals have been modified to store images in the media folder with 
 * the correct date meta data
 * @author samuelkirton
 */
public class CapturePhotoUtils {

    /**
     * A copy of the Android internals  insertImage method, this method populates the 
     * meta data with DATE_ADDED and DATE_TAKEN. This fixes a common problem where media 
     * that is inserted manually gets saved at the end of the gallery (because date is not populated).
     * @see Android.provider.MediaStore.Images.Media#insertImage(ContentResolver, Bitmap, String, String)
     */
    public static final String insertImage(ContentResolver cr, 
            Bitmap source, 
            String title, 
            String description) {

        ContentValues values = new ContentValues();
        values.put(Images.Media.TITLE, title);
        values.put(Images.Media.DISPLAY_NAME, title);
        values.put(Images.Media.DESCRIPTION, description);
        values.put(Images.Media.MIME_TYPE, "image/jpeg");
        // Add the date meta data to ensure the image is added at the front of the gallery
        values.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
        values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());

        Uri url = null;
        String stringUrl = null;    /* value to be returned */

        try {
            url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

            if (source != null) {
                OutputStream imageOut = cr.openOutputStream(url);
                try {
                    source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
                } finally {
                    imageOut.close();
                }

                long id = ContentUris.parseId(url);
                // Wait until MINI_KIND thumbnail is generated.
                Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null);
                // This is for backward compatibility.
                storeThumbnail(cr, miniThumb, id, 50F, 50F,Images.Thumbnails.MICRO_KIND);
            } else {
                cr.delete(url, null, null);
                url = null;
            }
        } catch (Exception e) {
            if (url != null) {
                cr.delete(url, null, null);
                url = null;
            }
        }

        if (url != null) {
            stringUrl = url.toString();
        }

        return stringUrl;
    }

    /**
     * A copy of the Android internals StoreThumbnail method, it used with the insertImage to
     * populate the Android.provider.MediaStore.Images.Media#insertImage with all the correct
     * meta data. The StoreThumbnail method is private so it must be duplicated here.
     * @see Android.provider.MediaStore.Images.Media (StoreThumbnail private method)
     */
    private static final Bitmap storeThumbnail(
            ContentResolver cr,
            Bitmap source,
            long id,
            float width, 
            float height,
            int kind) {

        // create the matrix to scale it
        Matrix matrix = new Matrix();

        float scaleX = width / source.getWidth();
        float scaleY = height / source.getHeight();

        matrix.setScale(scaleX, scaleY);

        Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
            source.getWidth(),
            source.getHeight(), matrix,
            true
        );

        ContentValues values = new ContentValues(4);
        values.put(Images.Thumbnails.KIND,kind);
        values.put(Images.Thumbnails.IMAGE_ID,(int)id);
        values.put(Images.Thumbnails.HEIGHT,thumb.getHeight());
        values.put(Images.Thumbnails.WIDTH,thumb.getWidth());

        Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values);

        try {
            OutputStream thumbOut = cr.openOutputStream(url);
            thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
            thumbOut.close();
            return thumb;
        } catch (FileNotFoundException ex) {
            return null;
        } catch (IOException ex) {
            return null;
        }
    }
}
159
sfratini

En fait, vous pouvez enregistrer votre image à n’importe quel endroit. Si vous souhaitez enregistrer dans un espace public, afin que toute autre application puisse y accéder, utilisez le code suivant:

storageDir = new File(
    Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    ), 
    getAlbumName()
);

La photo ne va pas à l'album. Pour ce faire, vous devez appeler un scan:

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

Vous pouvez trouver plus d’informations sur https://developer.Android.com/training/camera/photobasics.html#TaskGallery

45
Sigrist

J'ai essayé beaucoup de choses pour laisser ce travail sur Marshmallow et Lollipop. Enfin, j'ai fini par déplacer l'image enregistrée dans le dossier DCIM (la nouvelle application Google Photo ne numérise les images que si elles se trouvent apparemment dans ce dossier).

public static File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
         .format(System.currentTimeInMillis());
    File storageDir = new File(Environment
         .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/");
    if (!storageDir.exists())
        storageDir.mkdirs();
    File image = File.createTempFile(
            timeStamp,                   /* prefix */
            ".jpeg",                     /* suffix */
            storageDir                   /* directory */
    );
    return image;
}

Et puis le code standard pour analyser les fichiers que vous pouvez trouver dans le site de Google Developers également .

public static void addPicToGallery(Context context, String photoPath) {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(photoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    context.sendBroadcast(mediaScanIntent);
}

N'oubliez pas que ce dossier ne peut pas être présent dans tous les périphériques du monde et qu'à partir de Marshmallow (API 23), vous devez demander à l'utilisateur l'autorisation de WRITE_EXTERNAL_STORAGE.

18
MatPag

Selon ce cours , la bonne façon de faire est:

Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES
    )

Cela vous donnera le chemin racine du répertoire de la galerie.

12
Cédric Julien
private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}
11
nitin Sol

Vous pouvez créer un répertoire dans le dossier de la caméra et enregistrer. Et numérisez une fois que vous avez terminé. Il montrera instantanément votre image dans la galerie. À votre santé!!

            String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()+ "/Camera/Your_Directory_Name";
            File myDir = new File(root);
            myDir.mkdirs();
            String fname = "Image-" + image_name + ".png";
            File file = new File(myDir, fname);
            System.out.println(file.getAbsolutePath());
            if (file.exists()) file.delete();
            Log.i("LOAD", root + fname);
            try {
                FileOutputStream out = new FileOutputStream(file);
                finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            MediaScannerConnection.scanFile(context, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);
5
javatar

Je viens ici avec le même doute, mais pour Xamarin pour Android, j'ai utilisé la réponse Sigrist pour faire cette méthode après avoir sauvegardé mon fichier:

private void UpdateGallery()
{
    Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
    Java.IO.File file = new Java.IO.File(_path);
    Android.Net.Uri contentUri = Android.Net.Uri.FromFile(file);
    mediaScanIntent.SetData(contentUri);
    Application.Context.SendBroadcast(mediaScanIntent);
} 

et cela a résolu mon problème, Thx Sigrist. Je le mets ici car je n’ai pas trouvé de réponse à ce sujet pour Xamarin et j’espère que cela pourra aider d’autres personnes.

1
Slaters

Dans mon cas, les solutions ci-dessus ne fonctionnaient pas, je devais faire ce qui suit:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
1
dc10
 String filePath="/storage/emulated/0/DCIM"+app_name;
    File dir=new File(filePath);
    if(!dir.exists()){
        dir.mkdir();
    }

Ce code est dans la méthode onCreate.Ce code est utilisé pour créer un répertoire de nom_app. Vous pouvez maintenant accéder à ce répertoire à l'aide de l'application du gestionnaire de fichiers par défaut sous Android. Utilisez cette chaîne filePath chaque fois que nécessaire pour définir votre dossier de destination. Je suis sûr que cette méthode fonctionne sur Android 7 aussi parce que j’ai testé sur elle.Puis, cela peut fonctionner sur d’autres versions de Android aussi.

0
Bhavik Mehta