Как реализовать базу данных SQLite для хранения растрового изображения и текста?

avatar
PrincEVergil
8 апреля 2018 в 07:14
2528
3
0

привет всем, я разрабатываю приложение для Android, которое прослушивает входящие уведомления WhatsApp и показывает их в listView, используя NotificationListenerService. Мне нужна помощь в базе данных sqlite для хранения уведомлений и извлечения данных и отображения в listView. данные - это одно растровое изображение и текстовая строка... следующий код я пытаюсь..

обработчик базы данных

public class DatabaseHandler extends SQLiteOpenHelper{
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "wnoti";
//  table name
private static final String TABLE_NOTI = "noti";
//table attributes
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_POTO = "poto";

public DatabaseHandler(Context context){
    super(context,DATABASE_NAME,null,DATABASE_VERSION);

}
//create table
@Override
public void onCreate(SQLiteDatabase db){
    String CREATE_TABLE=" CREATE TABLE "+TABLE_NOTI + "("
            + KEY_ID +" INTEGER PRIMARY KEY,"
            + KEY_NAME +" TEXT,"
            + KEY_POTO  +" BLOB" + ")";
    db.execSQL(CREATE_TABLE);
}

//upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_NOTI);

    // Create tables again
    onCreate(db);
}
//Insert values to the table contacts
public void addContacts(Model model){
    SQLiteDatabase db = this.getReadableDatabase();
    ContentValues values=new ContentValues();

    values.put(KEY_NAME, model.getName());
    values.put(KEY_POTO, model.getImage());


    db.insert(TABLE_NOTI, null, values);
    db.close();
}

public List<Model> getAllnoti() {
    List<Model> notiList = new ArrayList<Model>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_NOTI;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Model model = new Model();
            model.setID(Integer.parseInt(cursor.getString(0)));
            model.setName(cursor.getString(1));
            model.setImage(cursor.getBlob(2));


            // Adding notification to list
            notiList.add(model);
        } while (cursor.moveToNext());
    }

    // return notification list
    return notiList;
}
}


my model class 

1-й, когда я работаю без базы данных sqlite, я использую Bitmap imaBitmap затем я меняю его на байт []...

public class Model {
String name;
byte[] imaBitmap;
int _id;

public Model(){

}
public Model(int id,String name,byte[] imaBitmap)
{
    this._id=id;
    this.name=name;
    this.imaBitmap=imaBitmap;
}
public Model(String name,byte[] imaBitmap){
    this.name=name;
    this.imaBitmap=imaBitmap;
}
// getting ID
public int getID(){
    return this._id;
}

// setting id
public void setID(int id){
    this._id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public byte[] getImage() {
    return imaBitmap;
}

public void setImage(byte[] imaBitmap) {
    this.imaBitmap = imaBitmap;
}
}

теперь вот проблема.... мне просто нужны эти данныеString title = intent.getStringExtra("title"); String text = intent.getStringExtra("text"); byte[] byteArray = intent.getByteArrayExtra("icon"); в мою БД мой разум полностью заблокирован.........

public class MainActivity extends Activity {
  private DatabaseHandler db;
ListView list;
CustomListAdapter adapter;
ArrayList<Model> modelList;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    modelList = new ArrayList<Model>();
    adapter = new CustomListAdapter(getApplicationContext(), modelList);
    list = (ListView) findViewById(R.id.list);
    list.setAdapter(adapter);
    LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_settings:
            Intent intent = new Intent(
                    "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"
            );
            startActivity(intent);
            return true;
        default:
            return super.onOptionsItemSelected(item);

    }
}

private BroadcastReceiver onNotice = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // String pack = intent.getStringExtra("package");
        String title = intent.getStringExtra("title");
        String text = intent.getStringExtra("text");
        //int id =intent.getIntExtra("icon",0);
        Context remotePackageContext = null;
        try {
        //                    remotePackageContext = 
        getApplicationContext().createPackageContext(pack, 0);
        //                Drawable icon = 
         remotePackageContext.getResources().getDrawable(id);
        //                if(icon !=null) {
       //                    ((ImageView) 
          findViewById(R.id.imageView)).setBackground(icon);
            //}
            byte[] byteArray = intent.getByteArrayExtra("icon");
         //   Bitmap bmp = null;
          //  if (byteArray != null) {
           //     bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);

          //  }

            Model model = new Model();
          //  model.setName(title + "" + text);
           // model.setImage(byteArray);
              db.addContacts(new Model(title + "" + text,byteArray));
            Toast.makeText(getApplicationContext(),"Saved ",Toast.LENGTH_LONG).show();

            if (modelList != null) {
                modelList.add(model);
                adapter.notifyDataSetChanged();
            } else {
                modelList = new ArrayList<Model>();
                modelList.add(model);
                adapter = new CustomListAdapter(getApplicationContext(), modelList);
                list = (ListView) findViewById(R.id.list);
                list.setAdapter(adapter);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    };
    }

мне кажется, я многое делаю неправильно, я изучаю Android, пожалуйста, научите меня

Источник
pradithya aria
8 апреля 2018 в 07:25
3

Я предлагаю не хранить изображение внутри базы данных, так как существует ограничение на максимальный размер, который может хранить курсор, что может привести к неэффективности для больших запросов. Лучше хранить изображение в виде файла в локальном хранилище приложения и хранить URI, ссылающийся на файл изображения, в db.

PrincEVergil
8 апреля 2018 в 07:59
0

у меня есть инструкции по хранению в БД ;(

Phantômaxx
8 апреля 2018 в 08:57
0

... SQLite database to store Bitmap Image ... Это ужасная идея.

PrincEVergil
8 апреля 2018 в 09:02
0

любое решение ;(

Ответы (3)

avatar
Ajay J G
8 апреля 2018 в 16:08
1

Создайте класс с именем BitmapBase64.class и используйте его везде, где вам нужно. Любой способ преобразования может быть выполнен.

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;

public class BitmapBase64
{
    public static Bitmap convert(String base64Str) throws IllegalArgumentException
    {
        byte[] decodedBytes = Base64.decode(
            base64Str.substring(base64Str.indexOf(",")  + 1),
            Base64.DEFAULT
        );
        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
    }

    public static String convert(Bitmap bitmap)
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);    
        return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT);
    }    
}

Использование:

Bitmap bitmap = BitmapBase64.convert(BASE_64_STRING);

String base64String = BitmapBase64.convert(BITMAP);

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

avatar
isabsent
8 апреля 2018 в 14:25
1

Если ваше изображение действительно маленькое, вы можете преобразовать его в String с помощью кодировки android.util.Base64 и поместить эту строку в базу данных SQLite:<37469810>75833

public static String getPngAsString(Bitmap bitmap){
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos);
    byte[] bitmapBytes = bos.toByteArray();
    return Base64.encodeToString(bitmapBytes, Base64.NO_WRAP);
}

avatar
FlyingNades
8 апреля 2018 в 13:59
0

Сохранение Bitmap изображений в SQL на самом деле является плохой идеей.

Я предлагаю сохранить изображения в Интернете и сохранить URL-ссылку в базе данных.

Вы можете взять URL-адрес из базы данных и показать его в своем приложении, используя Picasso (ссылка).

Кроме того, не забудьте запросить разрешение в Интернете в своем приложении для загрузки изображений с URL-адреса.