Good day. In my application there are several activites, some of them with photos. I want to make password access and when I start the first Activation, open ProgressDialog , during which images and text information will be downloaded from the server.

Text information can be saved in SharedPreferences . And how can you save (subsequently to the user on the screen; access to the application and to the information in it should be without the Internet) images?

You can download from the server every time you enter the application, but this is not an option. Also, probably, perhaps, save to the Gallery and show from there. But this also does not fit.

In this regard, the question is : how can you save the downloaded image in some place (it is imperative that the user cannot see the image in the Gallery) so that it will be displayed in the application even without Internet access?

  • one
    Use, for example, the internal memory of the device. google.com.ua/… - Vladyslav Matviienko
  • @metalurgus, thanks for the advice! I thought about it, but will the image in the Gallery be displayed in the general list? Or, for example, appear as WhatsApp photos in a separate folder in the Gallery created for the application? - Dmitry
  • And most importantly: how to get this image to put in the same imageview? .setBackgroundResource? And how to indicate the way? - Dmitry
  • again give you a link to google? Can you try to look for yourself? - Vladyslav Matviienko
  • @metalurgus, this site is in order to help, and not to send to search engines. But, anyway, thanks for the advice. - Dmitry

1 answer 1

Can be cached.

Create a class which thread to work with the cache. I had something in the old project:

public static class FileHelper{ private static final String IMAGE_STORAGE = "images"; private static enum StorageType {INTERNAL, EXTERNAL}; private static StorageType preferStorage = StorageType.EXTERNAL; private static final Map<String, Bitmap> cache = Collections.synchronizedMap(new LinkedHashMap<String, Bitmap>()); private final static int MAX_CACHED = 50; /** * Number of bytes in one KB = 2<sup>10</sup> */ private final static long SIZE_KB = 1024L; /** * Number of bytes in one MB = 2<sup>20</sup> */ public final static long SIZE_MB = SIZE_KB * SIZE_KB; private static final long NEEDED_PLACE = 2; /** * Доступна ли внешняя память для записи * @return */ public static boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } /** * Доступна ли внешняя память для чтения * @return */ public static boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false; } private static boolean hasExternalAvailableSpace(Context c) { StatFs stat = new StatFs(c.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { long sdAvailSize = (long) stat.getAvailableBlocksLong() * (long) stat.getBlockSizeLong(); sdAvailSize = (long)(sdAvailSize*1.F/ SIZE_MB); return sdAvailSize > NEEDED_PLACE; } else { @SuppressWarnings("deprecation") double sdAvailSize = (double) stat.getAvailableBlocks() * (double) stat.getBlockSize(); sdAvailSize/=SIZE_MB; return sdAvailSize > NEEDED_PLACE; } } public static String getImagePath(Context c, String id){ String dir; // чекаем во внешней памяти dir = getExtImageStorageDir(c).getAbsolutePath(); File file = new File(dir+"/"+id+".png"); // если есть, берём её if(file.exists() ) return file.getAbsolutePath() ; // иначе чекаем во внутренней памяти dir = getIntImageStorageDir(c).getAbsolutePath(); file = new File(dir+"/"+id+".png"); // возвращаем if (file.exists()) return file.getAbsolutePath(); else throw new NoSuchElementException(file.getAbsolutePath()); } public static Bitmap getImage(Context c, String id){ synchronized (cache) { // если ещё нет в кеше битмапа с этим изображением if (!cache.containsKey("img"+id)) { try { Bitmap img = null; String imgPath; imgPath = getImagePath(c, id); // тогда декодим из файла img = BitmapFactory.decodeFile(imgPath); // добавляем в кэш cache.put("img"+id, img); return img; } catch (Exception e) { e.printStackTrace(); } } return cache.get("img"+id); } } public static boolean WriteImage(Context c, Bitmap img, String id) { File dir = getImagePreferStorageDir(c); String filename = dir.getAbsolutePath() +"/"+id+".png"; FileOutputStream outputStream; for(File f :dir.listFiles()) if(f.getName().substring(0, f.getName().indexOf(".png")).equals(id)) return true; try { cache.put("img"+id, img); outputStream = new FileOutputStream(filename); ByteArrayOutputStream stream = new ByteArrayOutputStream(); img.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); outputStream.write(byteArray); outputStream.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public static File getImagePreferStorageDir(Context c) { if(preferStorage == StorageType.EXTERNAL && isExternalStorageWritable() && hasExternalAvailableSpace(c)) return getExtImageStorageDir(c); else return getIntImageStorageDir(c); } public static File getExtImageStorageDir(Context c) { File file = new File(c.getExternalFilesDir(Environment.DIRECTORY_PICTURES), IMAGE_STORAGE); if(file.exists()); else if (!file.mkdirs()); return file; } public static File getIntImageStorageDir(Context c) { File file = new File(c.getFilesDir(), IMAGE_STORAGE); if(file.exists()) ; else if (!file.mkdirs()); return file; } private static void deleteFolder(File file){ if (file.exists()){ for(File f:file.listFiles()) f.delete(); file.delete(); } } public static void clearCache(){ LOG.d("clear cache"); cache.clear(); } public static void clear(Context c){ deleteFolder(getIntImageStorageDir(c)); deleteFolder(getExtImageStorageDir(c)); clearCache(); } } 

I added a little comment there to make it clearer.

The logic is as follows:

  1. Check FileHelper.getImagePath . If there is no file, there will be an exception. Then download the image from the network.
  2. Download the image.
  3. Save FileHelper.WriteImage . The image and the disk will be saved, and in memory in the cache will be. You can change the logic, remove the entire cache in memory, always load from disk. Depending on the choice, it will be saved either in external or in internal memory.
  4. If in 1 paragraph there was no exception, then get it FileHelper.getImage .

It can all simplify. Set explicitly so that only external memory is used, at times the code will be less. Can in memory cache remove. I just show the direction)

  • Thanks for such a detailed answer) And yet, there are a couple of questions left: if I just save the image to internal memory (for me, the cache code looks complicated for the time being, I will try to figure it out, but I need to write the application now), and then retrieve it, Will it be saved in the user’s Gallery? For me, this is quite important. And what method should I use? Will it look like something like this: Image_view.setBackgroundResource (....)? And the last question: what to indicate instead of points? Path of the form dir + "/" + id + ". Png" ? - Dmitry
  • @Dmitry what's the "user gallery"? Application standard for viewing images? If you save to internal memory, you will not see them in the gallery. image_view.setBackground(FileHelper.getImage(context, id)) to set the image. - Suvitruf