web-dev-qa-db-fra.com

Comment télécharger et enregistrer une image dans Android

Comment télécharger et enregistrer une image à partir d'une URL donnée sous Android?

85
Droidman

Modifier à partir du 30.12.2015 - Le guide ultime du téléchargement d'images


dernière mise à jour majeure: 31 mars 2016


TL; DR a.k.a cesse de parler, donne-moi simplement le code !!

Passez au bas de cet article, copiez la BasicImageDownloader (version javadoc ici ) dans votre projet, implémentez l'interface OnImageLoaderListener et vous avez terminé.

Remarque : bien que le BasicImageDownloader gère les erreurs possibles et empêchera votre application de se bloquer en cas de problème, elle ne procédera à aucun post-traitement (par exemple, réduction des effectifs ) sur le Bitmaps téléchargé.


Depuis que cet article a attiré beaucoup d’attention, j’ai décidé de le retravailler complètement pour éviter que les utilisateurs n’utilisent des technologies dépréciées, de mauvaises pratiques de programmation ou tout simplement des bêtises - comme chercher des "hacks" pour gérer un réseau sur le fil accepte tous les certificats SSL.

J'ai créé un projet de démonstration intitulé "Image Downloader" qui montre comment télécharger (et enregistrer) une image à l'aide de ma propre implémentation de téléchargeur, du logiciel intégré DownloadManager d'Android ainsi que de bibliothèques populaires à code source ouvert. Vous pouvez voir le code source complet ou télécharger le projet sur GitHub .

Remarque : Je n'ai pas encore ajusté la gestion des autorisations pour SDK 23+ (Marshmallow), le projet cible donc le SDK 22 (Lollipop).

Dans mon conclusion à la fin de cet article, je partagerai mon opinion humble sur le cas d'utilisation approprié pour chaque mode de téléchargement d'image que j'ai mentionné.

Commençons par une propre implémentation (vous pouvez trouver le code à la fin du post). Tout d'abord, il s'agit d'un Basic ImageDownloader et c'est tout. Tout ce qu’il fait est de se connecter à l’URL donnée, de lire les données et d’essayer de les décoder en tant que Bitmap, en déclenchant les rappels d’interface OnImageLoaderListener le cas échéant. L'avantage de cette approche est simple et vous avez un aperçu clair de ce qui se passe. Une bonne façon de procéder si tout ce dont vous avez besoin est de télécharger/afficher et sauvegarder certaines images, sans vous soucier de la maintenance d'un cache mémoire/disque.

Remarque: en cas de grandes images, vous devrez peut-être les réduire .

-

Android DownloadManager est un moyen de laisser le système gérer le téléchargement pour vous. En fait, il est capable de télécharger tout type de fichier, pas seulement des images. Vous pouvez laisser votre téléchargement se faire en silence et être invisible pour l'utilisateur, ou lui permettre de voir le téléchargement dans la zone de notification. Vous pouvez également enregistrer un BroadcastReceiver pour être averti une fois le téléchargement terminé. La configuration est assez simple, reportez-vous au projet lié pour obtenir un exemple de code.

Utiliser DownloadManager n’est généralement pas une bonne idée si vous souhaitez également afficher l’image, car vous devez lire et décoder le fichier enregistré au lieu de simplement définir le Bitmap téléchargé dans un ImageView. DownloadManager ne fournit pas non plus d'API pour que votre application puisse suivre la progression du téléchargement.

-

Maintenant, l'introduction de l'excellent matériel - les bibliothèques. Ils peuvent faire beaucoup plus que simplement télécharger et afficher des images, notamment: créer et gérer le cache mémoire/disque, redimensionner les images, les transformer, etc.

Je commencerai par Volley , une puissante bibliothèque créée par Google et couverte par la documentation officielle. Tout en étant une bibliothèque réseau polyvalente ne se spécialisant pas en images, Volley propose une API assez puissante pour la gestion des images.

Vous devrez implémenter une classe Singleton pour gérer les demandes Volley et vous êtes prêt à partir.

Vous voudrez peut-être remplacer votre ImageView par le NetworkImageView de Volley, de sorte que le téléchargement devienne essentiellement un one-liner:

((NetworkImageView) findViewById(R.id.myNIV)).setImageUrl(url, MySingleton.getInstance(this).getImageLoader());

Si vous avez besoin de plus de contrôle, voici à quoi il ressemble pour créer un ImageRequest avec Volley:

     ImageRequest imgRequest = new ImageRequest(url, new Response.Listener<Bitmap>() {
             @Override
             public void onResponse(Bitmap response) {
                    //do stuff
                }
            }, 0, 0, ImageView.ScaleType.CENTER_CROP, Bitmap.Config.ARGB_8888, 
             new Response.ErrorListener() {
             @Override
             public void onErrorResponse(VolleyError error) {
                   //do stuff
                }
            });

Il est à noter que Volley présente un excellent mécanisme de traitement des erreurs en fournissant la classe VolleyError qui vous aide à déterminer la cause exacte d’une erreur. Si votre application fait beaucoup de réseautage et que la gestion des images n’est pas son objectif principal, alors Volley est un choix parfait pour vous.

-

Square's Picasso est une bibliothèque bien connue, qui s'occupe de tout le chargement des images. Afficher une image avec Picasso est aussi simple que:

 Picasso.with(myContext)
       .load(url)
       .into(myImageView); 

Par défaut, Picasso gère le cache disque/mémoire afin que vous n'ayez pas à vous en préoccuper. Pour plus de contrôle, vous pouvez implémenter l'interface Target et l'utiliser pour charger votre image - ceci fournira des rappels similaires à ceux de l'exemple Volley. Vérifiez le projet de démonstration pour des exemples.

Picasso vous permet également d'appliquer des transformations à l'image téléchargée et il existe même d'autres bibliothèques autour de ces API. Fonctionne également très bien dans un RecyclerView/ListView/GridView.

-

niversal Image Loader est une autre bibliothèque très populaire servant à la gestion des images. Il utilise son propre ImageLoader qui (une fois initialisé) a une instance globale qui peut être utilisée pour télécharger des images dans une seule ligne de code:

  ImageLoader.getInstance().displayImage(url, myImageView);

Si vous souhaitez suivre l'évolution du téléchargement ou accéder à la version téléchargée Bitmap:

 ImageLoader.getInstance().displayImage(url, myImageView, opts, 
 new ImageLoadingListener() {
     @Override
     public void onLoadingStarted(String imageUri, View view) {
                     //do stuff
                }

      @Override
      public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                   //do stuff
                }

      @Override
      public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                   //do stuff
                }

      @Override
      public void onLoadingCancelled(String imageUri, View view) {
                   //do stuff
                }
            }, new ImageLoadingProgressListener() {
      @Override
      public void onProgressUpdate(String imageUri, View view, int current, int total) {
                   //do stuff
                }
            });

L'argument opts dans cet exemple est un objet DisplayImageOptions. Reportez-vous au projet de démonstration pour en savoir plus.

Semblable à Volley, UIL fournit la classe FailReason qui vous permet de vérifier ce qui ne va pas en cas d'échec du téléchargement. Par défaut, UIL maintient un cache mémoire/disque si vous ne lui dites pas explicitement de ne pas le faire.

Remarque : l'auteur a indiqué qu'il ne maintenait plus le projet à compter du 27 novembre 2015. Mais, compte tenu du nombre important de contributeurs, nous pouvons espérer que Universal Image Loader vivra.

-

Fresco de Facebook est la bibliothèque la plus récente et (IMO) la plus avancée qui élève la gestion des images à un nouveau niveau: de garder Bitmaps du tas Java (antérieur à Lollipop) à prendre en charge formats animés et streaming JPEG progressif .

Pour en savoir plus sur les idées et les techniques derrière Fresco, reportez-vous à cet article .

L'utilisation de base est assez simple. Notez que vous devrez appeler Fresco.initialize(Context); une seule fois, de préférence dans la classe Application. L'initialisation de Fresco plusieurs fois peut entraîner un comportement imprévisible et des erreurs de MOO.

Fresco utilise Drawees pour afficher des images, vous pouvez les considérer comme des ImageViews:

    <com.facebook.drawee.view.SimpleDraweeView
    Android:id="@+id/drawee"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    fresco:fadeDuration="500"
    fresco:actualImageScaleType="centerCrop"
    fresco:placeholderImage="@drawable/placeholder_grey"
    fresco:failureImage="@drawable/error_orange"
    fresco:placeholderImageScaleType="fitCenter"
    fresco:failureImageScaleType="centerInside"
    fresco:retryImageScaleType="centerCrop"
    fresco:progressBarImageScaleType="centerInside"
    fresco:progressBarAutoRotateInterval="1000"
    fresco:roundAsCircle="false" />

Comme vous pouvez le constater, de nombreux éléments (y compris les options de transformation) sont déjà définis en XML. Il vous suffit donc d'afficher une image en une couche:

 mDrawee.setImageURI(Uri.parse(url));

Fresco fournit une API de personnalisation étendue qui, dans certaines circonstances, peut être relativement complexe et obliger l'utilisateur à lire la documentation attentivement (oui, parfois , vous devez RTFM).

J'ai inclus des exemples de fichiers JPEG progressifs et d'images animées dans l'exemple de projet.


Conclusion - "J'ai appris les bonnes choses, que devrais-je utiliser maintenant?"

Notez que le texte suivant reflète mon opinion personnelle et ne doit pas être considéré comme un postulat.

  • Si vous ne devez télécharger/enregistrer/afficher que des images, n'envisagez pas de les utiliser dans un Recycler-/Grid-/ListView et vous n'avez pas besoin de tout un tas d'images pour que l'affichage soit prêt, le BasicImageDownloader devrait répondre à vos besoins.
  • Si votre application enregistre des images (ou d'autres fichiers) à la suite d'un utilisateur ou d'une action automatisée et que vous n'avez pas besoin que les images soient souvent affichées, utilisez le Gestionnaire de téléchargement Android . .
  • Si votre application fait beaucoup de réseautage, transmet/reçoit des données JSON, fonctionne avec des images, mais que celles-ci ne sont pas l'objectif principal de l'application, allez avec Volley .
  • Votre application est axée sur les images et les médias. Vous souhaitez appliquer des transformations aux images sans vous soucier des API complexes: utilisez Picasso (Remarque: ne fournit aucune API permettant de suivre l'état du téléchargement intermédiaire) ou Universal Image Loader
  • Si votre application ne concerne que les images, vous avez besoin de fonctionnalités avancées telles que l'affichage de formats animés et si vous êtes prêt à lire la documentation, utilisez Fresco .

Au cas où vous auriez manqué cela, le lien Github pour le projet de démonstration.


Et voici le BasicImageDownloader.Java

import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.os.AsyncTask;
import Android.support.annotation.NonNull;
import Android.util.Log;
import Java.io.BufferedInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.net.URL;
import Java.net.URLConnection;
import Java.util.HashSet;
import Java.util.Set;

public class BasicImageDownloader {

    private OnImageLoaderListener mImageLoaderListener;
    private Set<String> mUrlsInProgress = new HashSet<>();
    private final String TAG = this.getClass().getSimpleName();

    public BasicImageDownloader(@NonNull OnImageLoaderListener listener) {
        this.mImageLoaderListener = listener;
    }

    public interface OnImageLoaderListener {
        void onError(ImageError error);      
        void onProgressChange(int percent);
        void onComplete(Bitmap result);
    }


    public void download(@NonNull final String imageUrl, final boolean displayProgress) {
        if (mUrlsInProgress.contains(imageUrl)) {
            Log.w(TAG, "a download for this url is already running, " +
                    "no further download will be started");
            return;
        }

        new AsyncTask<Void, Integer, Bitmap>() {

            private ImageError error;

            @Override
            protected void onPreExecute() {
                mUrlsInProgress.add(imageUrl);
                Log.d(TAG, "starting download");
            }

            @Override
            protected void onCancelled() {
                mUrlsInProgress.remove(imageUrl);
                mImageLoaderListener.onError(error);
            }

            @Override
            protected void onProgressUpdate(Integer... values) {
                mImageLoaderListener.onProgressChange(values[0]);
            }

        @Override
        protected Bitmap doInBackground(Void... params) {
            Bitmap bitmap = null;
            HttpURLConnection connection = null;
            InputStream is = null;
            ByteArrayOutputStream out = null;
            try {
                connection = (HttpURLConnection) new URL(imageUrl).openConnection();
                if (displayProgress) {
                    connection.connect();
                    final int length = connection.getContentLength();
                    if (length <= 0) {
                        error = new ImageError("Invalid content length. The URL is probably not pointing to a file")
                                .setErrorCode(ImageError.ERROR_INVALID_FILE);
                        this.cancel(true);
                    }
                    is = new BufferedInputStream(connection.getInputStream(), 8192);
                    out = new ByteArrayOutputStream();
                    byte bytes[] = new byte[8192];
                    int count;
                    long read = 0;
                    while ((count = is.read(bytes)) != -1) {
                        read += count;
                        out.write(bytes, 0, count);
                        publishProgress((int) ((read * 100) / length));
                    }
                    bitmap = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
                } else {
                    is = connection.getInputStream();
                    bitmap = BitmapFactory.decodeStream(is);
                }
            } catch (Throwable e) {
                if (!this.isCancelled()) {
                    error = new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION);
                    this.cancel(true);
                }
            } finally {
                try {
                    if (connection != null)
                        connection.disconnect();
                    if (out != null) {
                        out.flush();
                        out.close();
                    }
                    if (is != null)
                        is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return bitmap;
        }

            @Override
            protected void onPostExecute(Bitmap result) {
                if (result == null) {
                    Log.e(TAG, "factory returned a null result");
                    mImageLoaderListener.onError(new ImageError("downloaded file could not be decoded as bitmap")
                            .setErrorCode(ImageError.ERROR_DECODE_FAILED));
                } else {
                    Log.d(TAG, "download complete, " + result.getByteCount() +
                            " bytes transferred");
                    mImageLoaderListener.onComplete(result);
                }
                mUrlsInProgress.remove(imageUrl);
                System.gc();
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public interface OnBitmapSaveListener {
        void onBitmapSaved();
        void onBitmapSaveError(ImageError error);
    }


    public static void writeToDisk(@NonNull final File imageFile, @NonNull final Bitmap image,
                               @NonNull final OnBitmapSaveListener listener,
                               @NonNull final Bitmap.CompressFormat format, boolean shouldOverwrite) {

    if (imageFile.isDirectory()) {
        listener.onBitmapSaveError(new ImageError("the specified path points to a directory, " +
                "should be a file").setErrorCode(ImageError.ERROR_IS_DIRECTORY));
        return;
    }

    if (imageFile.exists()) {
        if (!shouldOverwrite) {
            listener.onBitmapSaveError(new ImageError("file already exists, " +
                    "write operation cancelled").setErrorCode(ImageError.ERROR_FILE_EXISTS));
            return;
        } else if (!imageFile.delete()) {
            listener.onBitmapSaveError(new ImageError("could not delete existing file, " +
                    "most likely the write permission was denied")
                    .setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
            return;
        }
    }

    File parent = imageFile.getParentFile();
    if (!parent.exists() && !parent.mkdirs()) {
        listener.onBitmapSaveError(new ImageError("could not create parent directory")
                .setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
        return;
    }

    try {
        if (!imageFile.createNewFile()) {
            listener.onBitmapSaveError(new ImageError("could not create file")
                    .setErrorCode(ImageError.ERROR_PERMISSION_DENIED));
            return;
        }
    } catch (IOException e) {
        listener.onBitmapSaveError(new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION));
        return;
    }

    new AsyncTask<Void, Void, Void>() {

        private ImageError error;

        @Override
        protected Void doInBackground(Void... params) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(imageFile);
                image.compress(format, 100, fos);
            } catch (IOException e) {
                error = new ImageError(e).setErrorCode(ImageError.ERROR_GENERAL_EXCEPTION);
                this.cancel(true);
            } finally {
                if (fos != null) {
                    try {
                        fos.flush();
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

        @Override
        protected void onCancelled() {
            listener.onBitmapSaveError(error);
        }

        @Override
        protected void onPostExecute(Void result) {
            listener.onBitmapSaved();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
  }

public static Bitmap readFromDisk(@NonNull File imageFile) {
    if (!imageFile.exists() || imageFile.isDirectory()) return null;
    return BitmapFactory.decodeFile(imageFile.getAbsolutePath());
}

public interface OnImageReadListener {
    void onImageRead(Bitmap bitmap);
    void onReadFailed();
}

public static void readFromDiskAsync(@NonNull File imageFile, @NonNull final OnImageReadListener listener) {
    new AsyncTask<String, Void, Bitmap>() {
        @Override
        protected Bitmap doInBackground(String... params) {
            return BitmapFactory.decodeFile(params[0]);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (bitmap != null)
                listener.onImageRead(bitmap);
            else
                listener.onReadFailed();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imageFile.getAbsolutePath());
}

    public static final class ImageError extends Throwable {

        private int errorCode;
        public static final int ERROR_GENERAL_EXCEPTION = -1;
        public static final int ERROR_INVALID_FILE = 0;
        public static final int ERROR_DECODE_FAILED = 1;
        public static final int ERROR_FILE_EXISTS = 2;
        public static final int ERROR_PERMISSION_DENIED = 3;
        public static final int ERROR_IS_DIRECTORY = 4;


        public ImageError(@NonNull String message) {
            super(message);
        }

        public ImageError(@NonNull Throwable error) {
            super(error.getMessage(), error.getCause());
            this.setStackTrace(error.getStackTrace());
        }

        public ImageError setErrorCode(int code) {
            this.errorCode = code;
            return this;
        }

        public int getErrorCode() {
            return errorCode;
        }
      }
   }
221
Droidman

Je viens juste de résoudre ce problème et j'aimerais partager le code complet pouvant télécharger, enregistrer sur la carte SD (et masquer le nom du fichier), récupérer les images et enfin vérifier si l'image y est déjà L'URL provient de la base de données afin que le nom de fichier puisse être facilement et simplement en utilisant id.

premier téléchargement d'images

   private class GetImages extends AsyncTask<Object, Object, Object> {
    private String requestUrl, imagename_;
    private ImageView view;
    private Bitmap bitmap ; 
      private FileOutputStream fos;
    private GetImages(String requestUrl, ImageView view, String _imagename_) {
        this.requestUrl = requestUrl;
        this.view = view;
        this.imagename_ = _imagename_ ;
    }

    @Override
    protected Object doInBackground(Object... objects) {
        try {
            URL url = new URL(requestUrl);
            URLConnection conn = url.openConnection();
            bitmap = BitmapFactory.decodeStream(conn.getInputStream());
        } catch (Exception ex) {
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object o) { 
        if(!ImageStorage.checkifImageExists(imagename_))
        { 
                view.setImageBitmap(bitmap);
                ImageStorage.saveToSdCard(bitmap, imagename_); 
            }  
        }  
   }

Puis créez une classe pour sauvegarder et récupérer les fichiers

  public class ImageStorage {


public static String saveToSdCard(Bitmap bitmap, String filename) {

    String stored = null;

    File sdcard = Environment.getExternalStorageDirectory() ; 

    File folder = new File(sdcard.getAbsoluteFile(), ".your_specific_directory");//the dot makes this directory hidden to the user
    folder.mkdir(); 
    File file = new File(folder.getAbsoluteFile(), filename + ".jpg") ;
    if (file.exists())
        return stored ;

    try {
        FileOutputStream out = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
        stored = "success";
    } catch (Exception e) {
        e.printStackTrace();
    }
     return stored;
   }

public static File getImage(String imagename) {

        File mediaImage = null;
        try {
            String root = Environment.getExternalStorageDirectory().toString();
            File myDir = new File(root);
            if (!myDir.exists())
                return null;

            mediaImage = new File(myDir.getPath() + "/.your_specific_directory/"+imagename);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return mediaImage;
    }
public static boolean checkifImageExists(String imagename)
{
    Bitmap b = null ;
    File file = ImageStorage.getImage("/"+imagename+".jpg");
    String path = file.getAbsolutePath();

    if (path != null)
        b = BitmapFactory.decodeFile(path); 

    if(b == null ||  b.equals(""))
    {
        return false ;
    }
    return true ;
}
  }

Ensuite, pour accéder aux images d’abord, vérifiez s’il est déjà là, sinon téléchargez-le.

          if(ImageStorage.checkifImageExists(imagename))
            {
                File file = ImageStorage.getImage("/"+imagename+".jpg"); 
                String path = file.getAbsolutePath(); 
                if (path != null){
                    b = BitmapFactory.decodeFile(path);
                    imageView.setImageBitmap(b);
                }  
            } else { 
                new GetImages(imgurl, imageView, imagename).execute() ; 
            }
32
Nasz Njoka Sr.

Pourquoi avez-vous vraiment besoin de votre propre code pour le télécharger? Que diriez-vous de passer votre URI au gestionnaire de téléchargement?

public void downloadFile(String uRl) {
    File direct = new File(Environment.getExternalStorageDirectory()
            + "/AnhsirkDasarp");

    if (!direct.exists()) {
        direct.mkdirs();
    }

    DownloadManager mgr = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);

    Uri downloadUri = Uri.parse(uRl);
    DownloadManager.Request request = new DownloadManager.Request(
            downloadUri);

    request.setAllowedNetworkTypes(
            DownloadManager.Request.NETWORK_WIFI
                    | DownloadManager.Request.NETWORK_MOBILE)
            .setAllowedOverRoaming(false).setTitle("Demo")
            .setDescription("Something useful. No, really.")
            .setDestinationInExternalPublicDir("/AnhsirkDasarp", "fileName.jpg");

    mgr.enqueue(request);

}
31
AnhSirk Dasarp

cela pourrait vous aider ..

Button download_image = (Button)bigimagedialog.findViewById(R.id.btn_downloadimage);
                    download_image.setOnClickListener(new View.OnClickListener()
                    {
                        public void onClick(View v)
                        {
                            boolean success = (new File("/sdcard/dirname")).mkdir(); 
                            if (!success)
                            {
                                Log.w("directory not created", "directory not created");
                            }

                            try
                            {
                                URL url = new URL("YOUR_URL");
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                                connection.setDoInput(true);
                                connection.connect();
                                InputStream input = connection.getInputStream();
                                Bitmap myBitmap = BitmapFactory.decodeStream(input);

                                String data1 = String.valueOf(String.format("/sdcard/dirname/%d.jpg",System.currentTimeMillis()));

                                FileOutputStream stream = new FileOutputStream(data1);

                                ByteArrayOutputStream outstream = new ByteArrayOutputStream();
                                myBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outstream);
                                byte[] byteArray = outstream.toByteArray();

                                stream.write(byteArray);
                                stream.close();

                                Toast.makeText(getApplicationContext(), "Downloading Completed", Toast.LENGTH_SHORT).show();
                            }
                            catch (Exception e)
                            {
                                e.printStackTrace();
                            }
                        }
                    });
12
Ajay

J'ai une solution simple qui fonctionne parfaitement. Le code n'est pas le mien, je l'ai trouvé sur ce link . Voici les étapes à suivre:

1. Avant de télécharger l’image, écrivons une méthode pour enregistrer les images bitmap dans un fichier image de la mémoire interne d’Android. Il a besoin d'un contexte, il est préférable d'utiliser la passe dans le contexte de l'application par getApplicationContext (). Cette méthode peut être transférée dans votre classe d'activité ou dans d'autres classes util.

public void saveImage(Context context, Bitmap b, String imageName) 
{
    FileOutputStream foStream;
    try 
    {
        foStream = context.openFileOutput(imageName, Context.MODE_PRIVATE);
        b.compress(Bitmap.CompressFormat.PNG, 100, foStream);
        foStream.close();
    } 
    catch (Exception e) 
    {
        Log.d("saveImage", "Exception 2, Something went wrong!");
        e.printStackTrace();
    }
}

2. Nous avons maintenant une méthode pour enregistrer une image bitmap dans un fichier image sous andorid. Écrivons la AsyncTask pour le téléchargement d’images par url. Cette classe privée doit être placée dans votre classe d'activité en tant que sous-classe. Une fois l'image téléchargée, la méthode onPostExecute appelle la méthode saveImage définie ci-dessus pour enregistrer l'image. Remarque: le nom de l'image est codé en dur sous le nom «my_image.png».

private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
    private String TAG = "DownloadImage";
    private Bitmap downloadImageBitmap(String sUrl) {
        Bitmap bitmap = null;
        try {
            InputStream inputStream = new URL(sUrl).openStream();   // Download Image from URL
            bitmap = BitmapFactory.decodeStream(inputStream);       // Decode Bitmap
            inputStream.close();
        } catch (Exception e) {
            Log.d(TAG, "Exception 1, Something went wrong!");
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        return downloadImageBitmap(params[0]);
    }

    protected void onPostExecute(Bitmap result) {
        saveImage(getApplicationContext(), result, "my_image.png");
    }
}

3. La AsyncTask permettant de télécharger l'image est définie, mais nous devons l'exécuter pour exécuter cette AsyncTask. Pour ce faire, écrivez cette ligne dans votre méthode onCreate de votre classe d’activité, ou dans la méthode onClick d’un bouton ou dans d’autres emplacements qui vous conviennent.

new DownloadImage().execute("http://developer.Android.com/images/activity_lifecycle.png");

L'image doit être enregistrée dans /data/data/your.app.packagename/files/my_image.jpeg. Cochez cette publication pour accéder à ce répertoire à partir de votre appareil.

OMI cela résout le problème! Si vous souhaitez effectuer d'autres étapes telles que le chargement de l'image, vous pouvez suivre ces étapes supplémentaires:

4. Une fois l'image téléchargée, nous avons besoin d'un moyen de charger le bitmap d'image à partir de la mémoire de stockage interne afin de pouvoir l'utiliser. Écrivons la méthode de chargement du bitmap de l’image. Cette méthode prend deux paramètres, un contexte et un nom de fichier image, sans le chemin d'accès complet. Context.openFileInput (imageName) recherchera le fichier dans le répertoire de sauvegarde lorsque ce nom de fichier aura été enregistré dans la méthode saveImage ci-dessus.

public Bitmap loadImageBitmap(Context context, String imageName) {
    Bitmap bitmap = null;
    FileInputStream fiStream;
    try {
        fiStream    = context.openFileInput(imageName);
        bitmap      = BitmapFactory.decodeStream(fiStream);
        fiStream.close();
    } catch (Exception e) {
        Log.d("saveImage", "Exception 3, Something went wrong!");
        e.printStackTrace();
    }
    return bitmap;
}

5. Nous disposons maintenant de tout ce dont nous avons besoin pour définir l'image d'un ImageView ou de toute autre vue sur laquelle vous souhaitez utiliser l'image. Lorsque nous avons sauvegardé l'image, nous avons codé en dur le nom de l'image sous la forme «my_image.jpeg». Nous pouvons maintenant transmettre ce nom à la méthode loadImageBitmap ci-dessus pour obtenir le bitmap et le définir en tant qu'image.

someImageView.setImageBitmap(loadImageBitmap(getApplicationContext(), "my_image.jpeg"));

6. Pour obtenir le chemin complet de l'image par nom d'image.

File file            = getApplicationContext().getFileStreamPath("my_image.jpeg");
String imageFullPath = file.getAbsolutePath();

7. Vérifiez si le fichier image existe.

Fichier fichier = 

getApplicationContext().getFileStreamPath("my_image.jpeg");
if (file.exists()) Log.d("file", "my_image.jpeg exists!");
  1. Pour supprimer le fichier image.

    Fichier fichier = getApplicationContext (). GetFileStreamPath ("mon_image.jpeg"); If (fichier.delete ().) Log.d ("fichier", "mon_image.jpeg supprimé!");

Essaye ça

 try
                {
                    Bitmap bmp = null;
                    URL url = new URL("Your_URL");
                    URLConnection conn = url.openConnection();
                    bmp = BitmapFactory.decodeStream(conn.getInputStream());
                    File f = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis() + ".jpg");
                    if(f.exists())
                        f.delete();
                    f.createNewFile();
                    Bitmap bitmap = bmp;
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
                    byte[] bitmapdata = bos.toByteArray();
                    FileOutputStream fos = new FileOutputStream(f);
                    fos.write(bitmapdata);
                    fos.flush();
                    fos.close();
                    Log.e(TAG, "imagepath: "+f );
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
0
Sunil

ce code fonctionne parfaitement dans mon projet 

downloadImagesToSdCard(imagepath,imagepath);

private void downloadImagesToSdCard(String downloadUrl,String imageName)
        {
            try
            {
                URL url = new URL("www.xxx.com"+downloadUrl); 
                /* making a directory in sdcard */
            //  String sdCard=Environment.getExternalStorageDirectory().toString();
                ContextWrapper cw = new ContextWrapper(getActivity());
                 // path to /data/data/yourapp/app_data/imageDir
                File directory = cw.getDir("files", Context.MODE_PRIVATE);

                File myDir = new File(directory,"folder");

                /*  if specified not exist create new */
                if(!myDir.exists())
                {
                    myDir.mkdir();
                    Log.v("", "inside mkdir");
                }

                /* checks the file and if it already exist delete */
                String fname = imageName;
                File file = new File (myDir, fname);
                Log.d("file===========path", ""+file);
                if (file.exists ()) 
                    file.delete (); 

                /* Open a connection */
                URLConnection ucon = url.openConnection();
                InputStream inputStream = null;
                HttpURLConnection httpConn = (HttpURLConnection)ucon;
                httpConn.setRequestMethod("GET");
                httpConn.connect();
                inputStream = httpConn.getInputStream();
                /*if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) 
                {
                    inputStream = httpConn.getInputStream();
                }*/

                FileOutputStream fos = new FileOutputStream(file);  
                int totalSize = httpConn.getContentLength();
                int downloadedSize = 0;   
                byte[] buffer = new byte[1024];
                int bufferLength = 0;
                while ( (bufferLength = inputStream.read(buffer)) >0 ) 
                {                 
                    fos.write(buffer, 0, bufferLength);                  
                    downloadedSize += bufferLength;                 
                    Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;
                }   

                fos.close();
                Log.d("test", "Image Saved in sdcard..");  
                viewimage();
            }
            catch(IOException io)
            {                  
                io.printStackTrace();
            }
            catch(Exception e)
            {                     
                e.printStackTrace();
            }


        } 

        public void viewimage()
        {
              String path = serialnumber+".png";
               ContextWrapper cw = new ContextWrapper(getActivity());

                //path to /data/data/yourapp/app_data/dirName
                File directory = cw.getDir("files", Context.MODE_PRIVATE);

                File mypath=new File(directory,"folder/"+path);

                Bitmap b;
                try {
                    b = BitmapFactory.decodeStream(new FileInputStream(mypath));
                //  b.compress(format, quality, stream)
                    profile_image.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
0
tej shah
public class testCrop extends AppCompatActivity {
    ImageView iv;
    String imagePath = "https://style.pk/wp-content/uploads/2015/07/omer-Shahzad-performed-umrah-600x548.jpg";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testcrpop);
        iv = (ImageView) findViewById(R.id.testCrop);
        imageDownload image = new imageDownload(testCrop.this, iv);
        image.execute(imagePath);
    }
    class imageDownload extends AsyncTask<String, Integer, Bitmap> {
        Context context;
        ImageView imageView;
        Bitmap bitmap;
        InputStream in = null;
        int responseCode = -1;
//constructor.
        public imageDownload(Context context, ImageView imageView) {
            this.context = context;
            this.imageView = imageView;
        }
        @Override
        protected void onPreExecute() {
        }
        @Override
        protected Bitmap doInBackground(String... params) {
            try {
                URL url = new URL(params[0]);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setDoOutput(true);
                httpURLConnection.connect();
                responseCode = httpURLConnection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    in = httpURLConnection.getInputStream();
                    bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        }
        @Override
        protected void onPostExecute(Bitmap data) {
            imageView.setImageBitmap(data);
            saveImage(data);
        }

        private void saveImage(Bitmap data) {
            File createFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"test");
            createFolder.mkdir();
            File saveImage = new File(createFolder,"downloadimage.jpg");
            try {
                OutputStream outputStream = new FileOutputStream(saveImage);
                data.compress(Bitmap.CompressFormat.JPEG,100,outputStream);
                outputStream.flush();
                outputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

OUTPUT  enter image description here

Assurez-vous que vous avez ajouté la permission d'écrire des données en mémoire 

 <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
0
Opriday