Загрузка изображений c интернета на SD карту Android

288
26 ноября 2016, 19:11

Стоит задача скачать изображения с сайта, создать их файлы на SD карте и поместить в базу пути к ним. Для последующего вызова их без подключение к интернету. Обновление данных тоже предусмотрено, поэтому файлы картинок должны перезаписываться. На сайте изображения в JPEG. Пытаюсь загрузить изображения через Picasso и вывести их тоже через это библиотеку.

Код загрузки:

 for (k = 0; k < 5; k++) {
            Picasso.with(context).load(image_ar.get(k)).into(new Target() {
                @Override
                public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
                    File filename = new File(context.getCacheDir().getAbsolutePath() + "/img" + k + ".jpg");
                    FileOutputStream out = null;
                    try {
                        if (filename.exists()) {
                            if (filename.delete()) {
                                System.out.println("Удалено");
                            }
                        }
                        if (filename.createNewFile()) {
                            System.out.println("New Create");
                        }
                        out = new FileOutputStream(filename);
                        contentValues.put(DBHelperNews.KEY_HREF_TO_IMAGE, filename.getPath());
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 40, out);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            if (out != null) {
                                out.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                }
                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                }
            });
            database.insert(DBHelperNews.TABLE_NEWS, null, contentValues);
        }

Код вывода:

  Picasso.with(context)
                .load("file:///" + image)
                .into(viewHolder.itemImage);

Помимо картинок загружается так же текст. Текст работает нормально, а вот картинки загружаются через раз. Причем один раз они загружаются, а при следующем обновлении picasso даже не делает запись. И так постоянно, но иногда бывает и такое, что просто не записывается фотография, и заместо неё в приложении выводится предыдущая. Если будет легче осуществить этот не через picasso, то как? Заранее благодарю!

Answer 1

Вы можете использовать Android-Universal-Image-Loader, где указать срок кеширования файлов какой то очень большой. Таким образом, если картинки ещё нет - ImageLoader сходит на сервер, скачает картинку и сам её закеширует (в базу ничего сохранять не нужно). Затем, всю оставшуюся жизнь, ImageLoader будет использовать кеш.

Как только пользователь очистит приложение/переустановит/обновит или заменит SD-карту, в общем, как только с картинкой что-нибудь случится, у вас не будет креша приложения, а просто ImageLoader опять сходит на сервер и опять закеширует.

Нажеюсь, это поможет вам. Удачи!

update: вот пример создания конфигурации:

private static ImageLoaderConfiguration getImageLoaderConfiguration(Context context) {
        if (imageLoaderConfiguration == null) {
            File cacheDir = StorageUtils.getCacheDirectory(context);
            ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(context);
            builder.diskCache(new LimitedAgeDiskCache(cacheDir, 60 * 60 * 24 * 14)); //время кеширования фотографий 14 дней
            builder.diskCacheFileCount(2000); //максимальное количество фотографий в кеше
            builder.defaultDisplayImageOptions(getDisplayImageOptions());
            imageLoaderConfiguration = builder.build();
        }
        return imageLoaderConfiguration;
    }

 public static DisplayImageOptions getDisplayImageOptions() {
        if (options == null) {
            options = new DisplayImageOptions.Builder()
                    .cacheInMemory(true) // default - false
                    .cacheOnDisk(true) // default - false
                    .imageScaleType(ImageScaleType.NONE_SAFE) // default ImageScaleType.IN_SAMPLE_POWER_OF_2
                    .build();
        }
        return options;
    }