Как загрузить и сохранить изображение в Android

Как вы загружаете и сохраняете изображение с определенного URL-адреса в Android?

Solutions Collecting From Web of "Как загрузить и сохранить изображение в Android"

Изменить с 30.12.2015 – Окончательное руководство по загрузке изображений


Последнее крупное обновление: 31 марта 2016 г.


TL; DR aka перестаньте говорить, просто дай мне код!

Пропустите эту публикацию, скопируйте BasicImageDownloader (версия javadoc здесь ) в свой проект, OnImageLoaderListener интерфейс OnImageLoaderListener и все готово.

Обратите внимание : хотя BasicImageDownloader обрабатывает возможные ошибки и предотвратит сбой вашего приложения, если что-то пойдет не так, оно не будет выполнять пост-обработку (например, сокращение) загруженных Bitmaps .


Поскольку этот пост получил довольно много внимания, я решил полностью переработать его, чтобы люди не использовали устаревшие технологии, плохо программировали или просто делали глупые вещи – например, искали «хаки» для запуска сети по основному потоку или Принять все сертификаты SSL.

Я создал демонстрационный проект под названием «Image Downloader», который демонстрирует, как загружать (и сохранять) изображение с помощью моей собственной реализации загрузчика, встроенного DownloadManager Android, а также некоторых популярных библиотек с открытым исходным кодом. Вы можете просмотреть полный исходный код или загрузить проект на GitHub .

Примечание . Я еще не настроил управление разрешениями для SDK 23+ (Marshmallow), поэтому проект нацелен на SDK 22 (Lollipop).

В моем заключении в конце этого сообщения я поделюсь своим скромным мнением о правильном варианте использования для каждого конкретного способа загрузки изображений, о котором я упоминал.

Начнем с собственной реализации (вы можете найти код в конце сообщения). Прежде всего, это Basic ImageDownloader, и все. Все, что он делает, – это подключение к указанному URL-адресу, считывание данных и попытка его декодирования в виде Bitmap , при необходимости OnImageLoaderListener обратные вызовы интерфейса OnImageLoaderListener . Преимущество такого подхода – это просто, и у вас есть четкий обзор того, что происходит. Хороший способ пойти, если все, что вам нужно, это загрузить / отобразить и сохранить некоторые изображения, в то время как вы не заботитесь о сохранении кеша памяти / диска.

Примечание: в случае больших изображений вам может потребоваться уменьшить масштаб .

Android DownloadManager – это способ позволить системе обрабатывать загрузку для вас. На самом деле он способен загружать любые файлы, а не только изображения. Вы можете разрешить загрузке беззвучно и невидимо для пользователя, или вы можете разрешить пользователю видеть загрузку в области уведомлений. Вы также можете зарегистрировать BroadcastReceiver для получения уведомления после завершения загрузки. Настройка довольно проста, обратитесь к связанному проекту для образца кода.

Использование DownloadManager обычно не является хорошей идеей, если вы также хотите отображать изображение, так как вам нужно будет прочитать и декодировать сохраненный файл, а не просто установить загруженный Bitmap в ImageView . DownloadManager также не предоставляет API для вашего приложения, чтобы отслеживать ход загрузки.

Теперь введение большого материала – библиотеки. Они могут делать гораздо больше, чем просто загружать и отображать изображения, в том числе: создание и управление кешем памяти / диска, изменение размеров изображений, их преобразование и многое другое.

Я начну с Volley , мощной библиотеки, созданной Google и охватываемой официальной документацией. Будучи универсальной сетевой библиотекой, не специализирующейся на изображениях, Volley имеет довольно мощный API для управления изображениями.

Вам нужно будет реализовать класс Singleton для управления запросами Volley, и вам хорошо идти.

Возможно, вы захотите заменить свой ImageView на NetworkImageView Volley, поэтому загрузка в основном станет однострочным:

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

Если вам нужно больше контроля, это похоже на создание ImageRequest с 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 } }); 

Стоит отметить, что Volley имеет отличный механизм обработки ошибок, предоставляя класс VolleyError который поможет вам определить точную причину ошибки. Если ваше приложение много работает и управляет изображениями, это не его основная цель, тогда Volley идеально подходит для вас.

Square Picasso – это хорошо известная библиотека, которая сделает все необходимое для загрузки изображений. Просто показывать изображение с помощью Picasso так же просто, как:

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

По умолчанию Picasso управляет кешем диска / памяти, поэтому вам не нужно об этом беспокоиться. Для большего контроля вы можете реализовать интерфейс Target и использовать его для загрузки изображения – это обеспечит обратные вызовы, похожие на пример Volley. Проверьте демонстрационный проект на примерах.

Picasso также позволяет применять преобразования к загруженному изображению, и есть даже другие библиотеки, которые расширяют этот API. Также очень хорошо работает в RecyclerView / ListView / GridView .

Универсальный Image Loader – еще одна очень популярная библиотека, предназначенная для управления изображениями. Он использует свой собственный ImageLoader который (после инициализации) имеет глобальный экземпляр, который можно использовать для загрузки изображений в одной строке кода:

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

Если вы хотите отслеживать ход загрузки или получить доступ к загруженному 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 } }); 

Аргумент opts в этом примере является объектом DisplayImageOptions . Обратитесь к демонстрационному проекту, чтобы узнать больше.

Подобно Volley, UIL предоставляет класс FailReason который позволяет вам проверить, что пошло не так, как при загрузке. По умолчанию UIL поддерживает кеш памяти / диска, если вы явно не говорите ему об этом.

Примечание : автор упомянул, что он больше не поддерживает проект с 27 ноября 2015 года. Но поскольку есть много участников, мы можем надеяться, что Universal Image Loader будет жить.

Facebook Fresco – новейшая и (IMO) самая передовая библиотека, которая выводит управление изображениями на новый уровень: от сохранения Bitmaps от кучи java (до Lollipop) до поддержки анимированных форматов и прогрессивной потоковой передачи JPEG .

Чтобы узнать больше о идеях и методах, стоящих за Фреско, обратитесь к этому сообщению .

Основное использование довольно простое. Обратите внимание, что вам нужно вызвать Fresco.initialize(Context); Только один раз, предпочтительнее в классе Application . Инициализация Fresco более одного раза может привести к непредсказуемому поведению и ошибкам OOM.

Fresco использует Drawee для отображения изображений, вы можете думать о них как о ImageView s:

  <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" /> 

Как вы можете видеть, многие вещи (включая опции преобразования) уже определены в XML, поэтому все, что вам нужно сделать для отображения изображения, – это однострочный:

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

Fresco предоставляет расширенный API настройки, который при обстоятельствах может быть довольно сложным и требует, чтобы пользователь внимательно прочитал документы (да, иногда вам нужно RTFM).

Я включил примеры для прогрессивных JPEG и анимированных изображений в образец проекта.


Вывод: «Я узнал о великих вещах, что мне теперь использовать?»

Обратите внимание, что следующий текст отражает мое личное мнение и не следует воспринимать как постулат.

  • Если вам нужно только загрузить / сохранить / отобразить некоторые изображения, не Recycler-/Grid-/ListView использовать их в Recycler-/Grid-/ListView и не нуждайтесь в целых кучах изображений, которые должны быть готовы к отображению, BasicImageDownloader должен соответствовать вашим необходимо.
  • Если ваше приложение сохраняет изображения (или другие файлы) в результате пользователя или автоматическое действие, и вам не нужны изображения, которые нужно отображать часто, используйте приложение DownloadManager Android.
  • Если ваше приложение много сетей, передает / получает данные JSON , работает с изображениями, но это не основная цель приложения, идите с Volley .
  • Ваше приложение ориентировано на изображение / медиа, вы хотите применить некоторые преобразования к изображениям и не хотите беспокоиться о сложном API: используйте Picasso (Примечание: не предоставляет API для отслеживания промежуточного статуса загрузки) или Universal Image погрузчик
  • Если ваше приложение связано с изображениями, вам нужны расширенные функции, такие как отображение анимированных форматов, и вы готовы читать документы, идите с Fresco .

Если вы пропустили это, ссылка Github для демонстрационного проекта.


И вот 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; } } } 

Я только что пришел от решения этой проблемы, и я хотел бы поделиться полным кодом, который можно загрузить, сохранить на SD-карте (и скрыть имя файла) и получить изображения, и, наконец, он проверяет, есть ли изображение уже там. URL-адрес поступает из базы данных, поэтому имя файла может быть уникально легко с помощью id.

Первая загрузка изображений

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

Затем создайте класс для сохранения и извлечения файлов

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

Затем Для доступа к изображениям сначала проверьте, есть ли он там, если нет, затем загрузите

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

Зачем вам нужен собственный код для его загрузки? Как насчет передачи вашего URI менеджеру загрузки?

 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("/AnhsirkDasarpFiles", "fileName.jpg"); mgr.enqueue(request); } 

Это может помочь вам ..

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

Этот код отлично работает в моем проекте

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

Поскольку Google говорит, на данный момент, не забудьте добавить и прочитать на внешнем хранилище в манифесте:

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

Источник: http://developer.android.com/training/basics/data-storage/files.html#GetWritePermission

Попробуй это

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

У меня есть простое решение, которое отлично работает. Код не мой, я нашел его по этой ссылке . Ниже приведены следующие шаги:

1. Перед загрузкой изображения давайте напишем метод сохранения растрового изображения в файл изображения во внутреннем хранилище в android. Он нуждается в контексте, лучше использовать проход в контексте приложения getApplicationContext (). Этот метод может быть сброшен в ваш класс Activity или другие классы использования.

 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. Теперь у нас есть способ сохранить bitmap в файл изображения в andorid, давайте напишем AsyncTask для загрузки изображений по URL-адресу. Этот частный класс должен быть помещен в ваш класс Activity в качестве подкласса. После загрузки изображения в методе onPostExecute он вызывает метод saveImage, определенный выше, для сохранения изображения. Обратите внимание: имя изображения жестко запрограммировано как «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. AsyncTask для загрузки изображения определен, но нам нужно выполнить его для запуска этой AsyncTask. Для этого напишите эту строку в методе onCreate в классе Activity или в методе onClick кнопки или в других местах, которые, по вашему мнению, подходят.

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

Изображение должно быть сохранено в /data/data/your.app.packagename/files/my_image.jpeg, проверьте это сообщение для доступа к этому каталогу с вашего устройства.

ИМО это решает проблему! Если вам нужны дальнейшие шаги, такие как загрузка изображения, вы можете выполнить следующие дополнительные действия:

4. После загрузки изображения нам нужен способ загрузки растрового изображения из внутреннего хранилища, поэтому мы можем его использовать. Давайте напишем способ загрузки растрового изображения. Этот метод принимает два параметра, контекст и имя файла изображения без полного пути. Context.openFileInput (imageName) будет искать файл в каталоге сохранения, когда это имя файла было сохранено в вышеуказанном методе saveImage.

 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. Теперь у нас есть все необходимое для установки образа ImageView или любых других видов, на которые вы хотите использовать изображение. Когда мы сохраняем изображение, мы жестко закодировали имя изображения как «my_image.jpeg», теперь мы можем передать это имя изображения вышеупомянутому методу loadImageBitmap, чтобы получить растровое изображение и установить его в ImageView.

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

6. Получить полный путь изображения по имени изображения.

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

7. Проверьте, существует ли файл изображения.

Файл файла =

 getApplicationContext().getFileStreamPath("my_image.jpeg"); if (file.exists()) Log.d("file", "my_image.jpeg exists!"); 
  1. Чтобы удалить файл изображения.

    Файл file = getApplicationContext (). GetFileStreamPath ("my_image.jpeg"); If (file.delete ()) Log.d ("file", "my_image.jpeg deleted!");