提问者:小点点

如何实现SQLite数据库存储位图图像和文本?


hello all我正在开发一个android应用程序,它可以监听传入的whatsapp通知,并使用NotificationListenerService在listView中显示它。我需要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 

首先,当我在没有sqlite数据库的情况下工作时,我使用位图imaBitmap,然后将其更改为byte[]...

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;
}
}

现在问题来了。我只想要这个数据字符串标题 = intent.getStringExtra(“title”);字符串文本 = 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 plz教我


共3个答案

匿名用户

如果您的图像非常小,您可以通过android.util.Base64编码将其隐藏在String中,并将此字符串放入SQLite数据库中:

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);
}

匿名用户

创建一个名为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);

但是如果图像很小,如果不使用在线存储和检索,则建议这样做。小心内存溢出,因为这在处理位图时很常见。

匿名用户

在 SQL 中存储位图图像实际上是个坏主意。

我的建议是将你的图片保存在网上,并将URL链接保存在数据库中。

您可以从数据库中获取URL,并使用< code>Picasso(链接)将其显示在您的应用程序中。

此外,请记住在您的应用程序中请求internet许可以从url加载图像。