Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 99
#1

Сохранение картинки в БД SQ Lite - Программирование Android

23.01.2014, 12:39. Просмотров 2095. Ответов 10
Метки нет (Все метки)

Есть необходимость в планировщике при сохранении задачи прикреплять фото, но читал что вставлять картинки напрямую в базу данных не самая лучшая идея, так как SQLite не работает с изображениями напрямую и что нужно сконвертировать картинку в байтовый массив, а потом при извлечении конвектировать обратно.

Вопрос: есть ли более простой способ реализовать задуманное, может как-то сохранять например на SD карту, а потом извлекать по ссылке (указывая путь)?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
23.01.2014, 13:07     Сохранение картинки в БД SQ Lite #2
mcGurov, можно хранить в базе имя картинки. Потом по этому имени генерировать полный путь (например используя getCacheDir()) и декодить её.
Н-р. Имя в базе - some_image.jpg. Делаем полный путь - getCacheDir() + "/" + some_image.jpg
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 99
23.01.2014, 13:24  [ТС]     Сохранение картинки в БД SQ Lite #3
Хоть бы какой-нибудь пример кода посмотреть по этому вопросу, в инете не могу найти подобного...
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
23.01.2014, 17:20     Сохранение картинки в БД SQ Lite #4
mcGurov, что именно вызывает затруднения? Работа с базой? работа с файловой системой? Декодирование?
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 99
23.01.2014, 18:22  [ТС]     Сохранение картинки в БД SQ Lite #5
Затруднение вызывает совместить всё это в одном коде... А так на примере сразу становится понятнее...

Добавлено через 17 минут
YuraAAA, все равно спасибо!
Если получится задуманное, то выложу пример, но было бы не плохо, если бы кто-нибудь подсказал )
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
24.01.2014, 12:08     Сохранение картинки в БД SQ Lite #6
mcGurov, сейчас покажу как это делается.

Добавлено через 11 минут
У нас будет использоваться файловый кэш + mem cache (LruCache).
Начнём с файла приложения.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.example.dbImageExample;
 
import android.app.Application;
import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;
 
import java.io.ByteArrayOutputStream;
 
public class TheApplication extends Application{
    private static TheApplication instance;
    private static LruCache<String, Bitmap> mMemoryCache;
 
    public static TheApplication getInstance() {
        return instance;
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        initMemoryCache();
    }
 
    public static LruCache<String, Bitmap> getMemoryCache() {
        return mMemoryCache;
    }
 
    private void initMemoryCache() {
        final int kilo = 1024;
        int maxMemory = (int) Runtime.getRuntime().maxMemory() / kilo;
        int cacheSize = maxMemory / 8;
        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                ByteArrayOutputStream bao = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bao);
                int size = bao.size();
                try {
                    bao.close();
                } catch (Exception e) {
                    Log.e(getClass().getSimpleName(), "Unable to init memoryCache", e);
                }
                return size / kilo;
            }
        };
    }
}
Мы используем кэш в памяти для быстрого доступа к изображениям. Чтобы он работал добавляем в тэг application в манифесте следующее:

XML
1
 <application android:name=".TheApplication"
Также нам потребуется доступ к файловой системе и интернету, значит запрашиваем persmission в манифесте:

Java
1
2
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Опишем хелпер-класс, который сможет декодировать изображения, а также работать с кэшем.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package com.example.dbImageExample;
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.DisplayMetrics;
import android.util.Log;
 
import java.io.File;
import java.io.IOException;
import java.lang.ref.SoftReference;
 
public class FileUtils {
    public static final String TEMP_FOLDER = "temp/";
 
    public static int getDimensions(boolean isWidth) {
        DisplayMetrics m = TheApplication.getInstance().getResources().getDisplayMetrics();
        return isWidth ? m.widthPixels : m.heightPixels;
    }
 
    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight, boolean canBeCropped) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
 
        if (height > reqHeight || width > reqWidth) {
            // Calculate ratios of height and width to requested height and width
            int imageMaxSize = reqHeight > reqWidth ? reqHeight : reqWidth;
 
            if (height > imageMaxSize || width > imageMaxSize) {
                inSampleSize = (int) Math.pow(2, (int) Math.round(Math.log(imageMaxSize /
                        (double) Math.max(height, width)) / Math.log(0.5)));
            }
        }
        return inSampleSize;
    }
 
    private static int calculateInSampleSizeOnWidth(BitmapFactory.Options options, int reqWidth, boolean canBeCropped) {
        return calculateInSampleSize(options, reqWidth, reqWidth, canBeCropped);
    }
 
    public static Bitmap decodeUri(String filePath, int reqWidth, int reqHeight, boolean canBeCropped) {
        // First decode with inJustDecodeBounds=true to check dimensions
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
 
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight, canBeCropped);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPurgeable = true;
        SoftReference<Bitmap> bsoft = new SoftReference<Bitmap>(BitmapFactory.decodeFile(filePath, options));
        return bsoft.get();
    }
 
 
    public static Bitmap decodeUriResizeOnWidth(String filePath, int reqWidth, boolean canBeCropped) {
        // First decode with inJustDecodeBounds=true to check dimensions
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
 
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSizeOnWidth(options, reqWidth, canBeCropped);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPurgeable = true;
        SoftReference<Bitmap> bsoft = new SoftReference<Bitmap>(BitmapFactory.decodeFile(filePath, options));
        return bsoft.get();
    }
 
 
    public static Bitmap decodeUriResizeOnWidth(String filePath, int reqWidth) {
        return decodeUriResizeOnWidth(
                filePath,
                reqWidth,
                false
        );
    }
 
    public static Bitmap decodeUri(String filePath, int reqWidth, int reqHeight) {
        return decodeUri(
                filePath,
                reqWidth,
                reqHeight,
                false
        );
    }
 
    public static Bitmap decodeUri(String filePath) {
        return decodeUri(
                filePath,
                getDimensions(true),
                getDimensions(false)
        );
    }
 
    public static Bitmap decodeUri(String filePath, boolean canBeCropped) {
        return decodeUri(
                filePath,
                getDimensions(true),
                getDimensions(false),
                canBeCropped
        );
    }
 
    private static String getStorageDir() {
        //PackageInfo pi = application.getPackageManager().getPackageInfo(application.getPackageName(), PackageInfo.PARCELABLE_WRITE_RETURN_VALUE);
        File dir = TheApplication.getInstance().getCacheDir();//new File(pi.applicationInfo.dataDir);
        String storageDirPath = dir.getAbsolutePath() + "/";
        if (!dir.exists()) dir.mkdirs();
        requestFilePermission(dir.getAbsolutePath());
 
        dir = new File(storageDirPath + TEMP_FOLDER);
        if (!dir.exists()) dir.mkdirs();
        requestFilePermission(dir.getAbsolutePath());
 
        dir = new File(storageDirPath + TEMP_FOLDER);
        if (!dir.exists()) dir.mkdirs();
        requestFilePermission(dir.getAbsolutePath());
        return storageDirPath;
    }
 
 
    public static void requestFilePermission(String filePath) {
        if (filePath != null && !filePath.trim().isEmpty()) {
            //solution for 2.3.3. problem with reading cache dir in file system
            try {
                Runtime.getRuntime().exec("chmod 755 " + filePath);
            } catch (IOException e) {
                Log.e("Utils.getStorageDir", e.getMessage(), e);
            }
        }
    }
 
    public static String getFilePath(String fileName) {
        return getStorageDir() + fileName;
    }
 
 
    /*------------------mem_cache---------------*/
 
    public static synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (bitmap != null && key != null && !key.trim().isEmpty() && getBitmapFromMemoryCache(key) == null && !bitmap.isRecycled()) {
            TheApplication.getMemoryCache().put(key, bitmap);
        }
    }
 
    public static Bitmap getBitmapFromMemoryCache(String key) {
        if (key != null && !key.trim().isEmpty()) {
            Bitmap b = TheApplication.getMemoryCache().get(key);
            if (b != null && b.isRecycled()) {
                removeBitmapFromMemoryCache(key);
            } else {
                return b;
            }
        }
        return null;
    }
 
    public static Bitmap removeBitmapFromMemoryCache(String key) {
        try {
            if (key != null && !key.trim().isEmpty()) {
                return TheApplication.getMemoryCache().remove(key);
            }
        } catch (IllegalStateException e) {
            Log.e("FileUtils", "Utils.removeBitmapFromMemoryCache", e);
        }
        return null;
    }
 
}
Android откровеено хреново работает с bitmap, и чтобы декодировать bitmap необходимо его ужимать.


Приступим к базе данных. Опишем хэлпер синглтон класс:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package com.example.dbImageExample.database;
 
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.example.dbImageExample.TheApplication;
import com.example.dbImageExample.database.entity.ImageObject;
import com.example.dbImageExample.database.utils.ImageTable;
 
import java.util.LinkedList;
import java.util.List;
 
public class DBHelper extends SQLiteOpenHelper {
 
    public static final int DB_VERSION = 1;
    public static final String DB_NAME = "ImageExampleDB";
    private static DBHelper instance;
    public static final String CREATE_TABLE_PREFIX = "CREATE TABLE IF NOT EXISTS ";
 
    public static DBHelper getInstance() {
        if (instance == null) {
            instance = new DBHelper();
        }
        return instance;
    }
 
    public DBHelper() {
        super(TheApplication.getInstance().getApplicationContext(), DB_NAME, null, DB_VERSION);
    }
 
    private void initDataTables() {
        getWritableDatabase().rawQuery(CREATE_TABLE_PREFIX + ImageTable.TABLE_NAME + " ("
                + ImageTable.IMAGE_ID + ", " + ImageTable.IMAGE_PATH + ");", null);
    }
 
    public ImageObject getImageObjectById(int id) {
        ImageObject model = null;
        String sql = "SELECT * FROM " + ImageTable.TABLE_NAME + " WHERE " + ImageTable.IMAGE_ID + " = " + id;
        Cursor cursor = getWritableDatabase().rawQuery(sql, null);
        if (cursor != null && cursor.moveToFirst()) {
            model = ImageTable.parseCursor(cursor);
        }
        closeCursor(cursor);
        return model;
    }
 
    public List<ImageObject> getImageObjects() {
        List<ImageObject> imageObjects = new LinkedList<ImageObject>();
        String sql = "SELECT * FROM " + ImageTable.TABLE_NAME;
        Cursor cursor = getWritableDatabase().rawQuery(sql, null);
        if (cursor != null && cursor.moveToFirst()) {
            do {
                imageObjects.add(ImageTable.parseCursor(cursor));
            } while (cursor.moveToNext());
        }
        closeCursor(cursor);
        return imageObjects;
    }
 
    public long saveImageObject(ImageObject imageObject) {
        String sql = "SELECT * FROM " + ImageTable.TABLE_NAME + " WHERE " + ImageTable.IMAGE_ID + " = " + imageObject.getId();
        Cursor cursor = getWritableDatabase().rawQuery(sql, null);
        long pointer;
        if (cursor == null || !cursor.moveToFirst()) {
            //insert new raw
            pointer = getWritableDatabase().insertWithOnConflict(ImageTable.TABLE_NAME, null, ImageTable.getCV(imageObject), SQLiteDatabase.CONFLICT_REPLACE);
        } else {
            //update existing
            pointer = getWritableDatabase().updateWithOnConflict(ImageTable.TABLE_NAME, ImageTable.getCV(imageObject), ImageTable.IMAGE_ID + " = " + imageObject.getId(), null, SQLiteDatabase.CONFLICT_REPLACE);
        }
        closeCursor(cursor);
        return pointer;
    }
 
    private void closeCursor (Cursor cursor) {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
    }
 
    @Override
    public void onCreate(SQLiteDatabase db) {
        initDataTables();
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
Сущность с которой мы будем работать:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.example.dbImageExample.database.entity;
 
public class ImageObject {
    private int id;
    private String path;
 
    public ImageObject(int id, String path) {
        this.id = id;
        this.path = path;
    }
 
    public ImageObject() {
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getPath() {
        return path;
    }
 
    public void setPath(String path) {
        this.path = path;
    }
}
и утилита, которая нам будет помогать парсить cursor и создавать contentValues для работы с БД

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.example.dbImageExample.database.utils;
 
import android.content.ContentValues;
import android.database.Cursor;
import com.example.dbImageExample.database.entity.ImageObject;
 
public class ImageTable {
    public static final String TABLE_NAME = "image_table";
    public static final String IMAGE_ID = "image_id";
    public static final String IMAGE_PATH = "image_path";
 
    public static ImageObject parseCursor(Cursor cursor) {
        ImageObject model = new ImageObject();
        model.setPath(cursor.getString(cursor.getColumnIndex(IMAGE_PATH)));
        model.setId(cursor.getInt(cursor.getColumnIndex(IMAGE_ID)));
        return model;
    }
 
    public static ContentValues getCV(ImageObject imageObject) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(IMAGE_ID, imageObject.getId());
        contentValues.put(IMAGE_PATH, imageObject.getPath());
        return contentValues;
    }
 
}
Идём дальше. Мы будем скачивать картинку из интернета, если её у нас нет, но перед этим создадим ещё один класс.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.example.dbImageExample.remote;
 
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
 
public class HttpClientFactory {
 
    public static final int SOCKET_TIMEOUT = 25000;
    public static final int CONNECTION_TIMEOUT = 15000;
    public static final String HTTPS = "https";
    public static final String HTTP = "http";
    public static final int PORT80 = 80;
    public static final int PORT443 = 443;
    private static DefaultHttpClient client;
 
    public synchronized static DefaultHttpClient getThreadSafeClient() {
        if (client != null) {
            return client;
        }
        client = new DefaultHttpClient();
        ClientConnectionManager mgr = client.getConnectionManager();
        mgr.getSchemeRegistry().register(new Scheme(HTTP, PlainSocketFactory.getSocketFactory(), PORT80));
        mgr.getSchemeRegistry().register(new Scheme(HTTPS, SSLSocketFactory.getSocketFactory(), PORT443));
        HttpParams params = client.getParams();
        HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT);
        HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
        client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, mgr.getSchemeRegistry()), params);
        return client;
    }
}
Фактически это ни разу не factory, а singleton, но пусть будет так)
Класс, который будет загружать и кэшировать изображения:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.example.dbImageExample.remote;
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.example.dbImageExample.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URI;
 
public class DownloadModule {
    public static final String TAG = DownloadModule.class.getSimpleName();
 
    public Bitmap downloadImage(String url, boolean deleteIfExists) {
        if (url == null) {
            Log.e(TAG, "Warning! Url is null", new IllegalArgumentException());
            return null;
        }
 
        WeakReference<Bitmap> reference = new WeakReference<Bitmap>(FileUtils.getBitmapFromMemoryCache(url));
        if (reference.get() != null) { //Try to find it in the mem-cache
            if (!reference.get().isRecycled()) {
                return reference.get();
            } else {
                FileUtils.removeBitmapFromMemoryCache(url);
            }
        }
 
 
        URI uri;
        try {
            uri = URI.create(url);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Warning! Can't decode URI", new IllegalArgumentException());
            return null;
        }
        String[] split = uri.getPath().split("/");
        if (split.length < 2) {
            Log.e(TAG, "Warning! Incorrect uri? " + uri, new IllegalArgumentException());
            return null;
        }
        String filePath = split[split.length - 2] + "_" + split[split.length - 1];
        File file = new File(FileUtils.getFilePath(filePath));
        if (file.exists()) {
            if (deleteIfExists) {
                //noinspection ResultOfMethodCallIgnored
                file.delete();
            } else {
                reference = new WeakReference<Bitmap>(FileUtils.decodeUri(FileUtils.getFilePath(filePath)));
                if (reference.get() == null) {
                    //Something goes wrong
                    //noinspection ResultOfMethodCallIgnored
                    file.delete();
                } else {
                    return reference.get();
                }
            }
        }
        reference = processDownload(url, filePath);
        return reference != null ? reference.get() : null;
    }
 
    private WeakReference<Bitmap> processDownload(String uri, String filePath) {
        HttpClient client = HttpClientFactory.getThreadSafeClient();
        HttpGet httpGet = new HttpGet(uri);
        HttpEntity httpEntity;
        WeakReference<Bitmap> reference = null;
        try {
            FileOutputStream stream = new FileOutputStream(new File(FileUtils.getFilePath(filePath)));
            httpEntity = client.execute(httpGet).getEntity();
            BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
            InputStream is = bufferedHttpEntity.getContent();
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            reference = new WeakReference<Bitmap>(bitmap);
            is.close();
            stream.close();
            FileUtils.addBitmapToMemoryCache(filePath, bitmap);
        } catch (IOException e) {
            Log.e(TAG, "Unable to execute request", e);
            return reference;
        }
        return reference;
    }
}
Теперь осталось всё это связать.
Работа с базой и сетью должна быть асинхронная, а асинхронность предполагает методы обратного вызова.

Опишем generic интерфейс для возврата результата.
Java
1
2
3
4
5
6
7
package com.example.dbImageExample.remote;
 
public interface IDataCallback<T> {
    void onSuccess(T data);
 
    void onError(String reason);
}

Асинхронный абстрактный обработчик:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.dbImageExample.remote;
 
import android.os.AsyncTask;
 
public abstract class AbsAsyncTask<T> extends AsyncTask<Void, Void, T> {
    private IDataCallback<T> callback;
    private Throwable throwable;
 
    protected AbsAsyncTask(IDataCallback<T> callback) {
        this.callback = callback;
    }
 
    @Override
    protected T doInBackground(Void... params) {
        try {
            return doAction();
        } catch (Throwable throwable) {
            this.throwable = throwable;
            return null;
        }
    }
 
    @Override
    protected void onPostExecute(T t) {
        super.onPostExecute(t);
        if (callback != null) {
            if (t != null) {
                callback.onSuccess(t);
            } else if (throwable != null) {
                callback.onError(throwable.getMessage());
            } else {
                callback.onError("Something goes wrong!");
            }
        }
    }
 
    protected abstract T doAction() throws Throwable;
 
}
И за всё у нас будет отвечать менеджер
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.example.dbImageExample.remote;
 
import android.graphics.Bitmap;
import com.example.dbImageExample.FileUtils;
import com.example.dbImageExample.database.DBHelper;
import com.example.dbImageExample.database.entity.ImageObject;
 
import java.io.File;
 
public class RemoteManager {
    private static RemoteManager instance;
 
    public static RemoteManager getInstance() {
        if (instance == null) {
            instance = new RemoteManager();
        }
        return instance;
    }
 
    public void getImageById(IDataCallback<Bitmap> callback, final int id, final String serverUrl) {
        new AbsAsyncTask<Bitmap>(callback) {
            @Override
            protected Bitmap doAction() throws Throwable {
                ImageObject imageObjectById = DBHelper.getInstance().getImageObjectById(id);
 
                if (imageObjectById != null && imageObjectById.getPath() != null && !imageObjectById.getPath().isEmpty()) {
                    Bitmap bitmapFromMemoryCache = FileUtils.getBitmapFromMemoryCache(imageObjectById.getPath());
                    if (bitmapFromMemoryCache == null) {
                        String path = imageObjectById.getPath();
                        File file = new File(FileUtils.getFilePath(path));
                        if (file.exists() && file.canRead()) {
                            Bitmap bitmap = FileUtils.decodeUri(path);
                            FileUtils.addBitmapToMemoryCache(path, bitmap);
                            return bitmap;
                        } else {
                            return getBitmap();
 
                        }
                    } else {
                        return bitmapFromMemoryCache;
                    }
                } else {
                    return getBitmap();
                }
            }
 
            private Bitmap getBitmap() {
                //Download file
                String[] split = serverUrl.split("/");
                String newFilePath = split[split.length - 1];
                Bitmap bitmap = new DownloadModule().downloadImage(serverUrl, true);
                if (bitmap != null) {
                    FileUtils.addBitmapToMemoryCache(newFilePath, bitmap);
                    DBHelper.getInstance().saveImageObject(new ImageObject(id, newFilePath));
                }
                return bitmap;
            }
        }.execute();
    }
 
}
Финал. Использование:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        RemoteManager.getInstance().getImageById(new IDataCallback<Bitmap>() {
            @Override
            public void onSuccess(Bitmap data) {
                Toast.makeText(MyActivity.this, "Complete!", Toast.LENGTH_LONG).show();
            }
 
            @Override
            public void onError(String reason) {
                Toast.makeText(MyActivity.this, "Oops!\n" + reason, Toast.LENGTH_LONG).show();
            }
        }, 1, "http://someHost.domain/static/1.jpg");
    }
}
P.S. можно было бы сделать и проще
P.P.S. код я даже не запускал, но работать должно
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 99
24.01.2014, 15:03  [ТС]     Сохранение картинки в БД SQ Lite #7
YuraAAA, вот это ответ! Супер! Спасибо огромное!:good:
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
24.01.2014, 16:23     Сохранение картинки в БД SQ Lite #8
mcGurov, пока что не за что) Вы проверьте сначала. В данном случае хранить картинку в базе возможно лишний шаг, ибо мы храним её в файловой системе на основе URL, а именно по ендпоинту. Т.е. из http://some_url/1.jpg мы берём 1.jpg
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 99
24.01.2014, 22:34  [ТС]     Сохранение картинки в БД SQ Lite #9
Получается данный код не подходит Для андроида 2.2, из-за API version 9...

Добавлено через 15 минут
Точнее API version 8...
YuraAAA
1566 / 1308 / 269
Регистрация: 25.10.2009
Сообщений: 3,424
Записей в блоге: 2
25.01.2014, 11:47     Сохранение картинки в БД SQ Lite #10
mcGurov, что именно? lruCache? Так он есть и в supportv4
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.01.2014, 12:17     Сохранение картинки в БД SQ Lite
Еще ссылки по теме:
Delphi БД Сохранение картинки в БД
Сохранение картинки C++ Builder
C# Сохранение картинки в БД
Windows Phone Сохранение картинки на телефон
Delphi Сохранение картинки из Image

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 99
25.01.2014, 12:17  [ТС]     Сохранение картинки в БД SQ Lite #11
Может с импортами накосячил... Посмотрю, но отпишусь не скоро, всё-равно буду немного переделывать, захват изо будет через камеру, и интернет мне будет не нужен...
Yandex
Объявления
25.01.2014, 12:17     Сохранение картинки в БД SQ Lite
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru