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

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

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

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

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

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

Вопрос: есть ли более простой способ реализовать задуманное, может как-то сохранять например на SD карту, а потом извлекать по ссылке (указывая путь)?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2014, 12:39
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сохранение картинки в БД SQ Lite (Программирование Android):

Сохранение картинки - Программирование Android
Всем привет! Подскажите шаги для реализации: Нужно, чтобы если картинка image ещё не сохранена на устройстве, скачивать её с интернета по...

Сохранение картинки в SharedPreferences - Программирование Android
Здравствуйте, подскажите, если ли способ хранения небольшой картинки в SharedPreferences, например, в байтовом виде? Записать туда строку...

Сохранение картинки из интернета по url - Программирование Android
Привет, помогите в решении следующей проблемы: необходимо произвести сохранение картинки из интернета в память планшетника, для...

Sql lite, установка - Программирование Android
господа, прошу сильно не закидывать меня тапками ибо я только учусь. Добрался в изучении андроид приложений до баз данных, во всех книжках...

Сортировка в SQL lite - Программирование Android
Не могу сортировать строку (адрес. формат: идекс, город, улица, номер дома, номер квартиры) Сортирует не правильно, как будто не...

Поиск и сохранение изображений от Google.Картинки и Яндекс.Картинки - PHP Сети
Мир вам, братья по увлечению! Я на вашем форуме впервые, давно хотел влиться в какое-нибудь сообщество веб-девелоперов, т.к. сам уже...

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

Добавлено через 17 минут
YuraAAA, все равно спасибо!
Если получится задуманное, то выложу пример, но было бы не плохо, если бы кто-нибудь подсказал )
0
YuraAAA
1576 / 1317 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
24.01.2014, 12:08 #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. код я даже не запускал, но работать должно
1
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 101
24.01.2014, 15:03  [ТС] #7
YuraAAA, вот это ответ! Супер! Спасибо огромное!:good:
0
YuraAAA
1576 / 1317 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
24.01.2014, 16:23 #8
mcGurov, пока что не за что) Вы проверьте сначала. В данном случае хранить картинку в базе возможно лишний шаг, ибо мы храним её в файловой системе на основе URL, а именно по ендпоинту. Т.е. из http://some_url/1.jpg мы берём 1.jpg
1
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 101
24.01.2014, 22:34  [ТС] #9
Получается данный код не подходит Для андроида 2.2, из-за API version 9...

Добавлено через 15 минут
Точнее API version 8...
0
YuraAAA
1576 / 1317 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
25.01.2014, 11:47 #10
mcGurov, что именно? lruCache? Так он есть и в supportv4
1
mcGurov
3 / 3 / 0
Регистрация: 30.07.2013
Сообщений: 101
25.01.2014, 12:17  [ТС] #11
Может с импортами накосячил... Посмотрю, но отпишусь не скоро, всё-равно буду немного переделывать, захват изо будет через камеру, и интернет мне будет не нужен...
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.01.2014, 12:17
Привет! Вот еще темы с ответами:

Сохранение картинки в БД - Delphi БД
Помогите, плиз! Необходимо сохранить в БД в поле картинку с Image. Не могу определить как передать параметр, т.е. нужно получить типа...

Сохранение картинки - C#
Как через шарп сохранить картинку из интернета на комп, имея URL адрес картинки....

Сохранение картинки в БД - C#
Здраствуйте. На форме я добавляю картинку до каких то даных как мне ету картинку сохранить в БД и в дальнейшем просматривать при...

Сохранение картинки - C++ Builder
Помогите с сохранением составленной картинки. У самого ничего не получается.


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

Или воспользуйтесь поиском по форуму:
11
Yandex
Объявления
25.01.2014, 12:17
Ответ Создать тему
Опции темы

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