【问题标题】:Images and SQLite Database图像和 SQLite 数据库
【发布时间】:2017-06-05 15:41:16
【问题描述】:

我是 android 新手,使用教程自学应用程序中的 SQLite 数据库。

目前,我遇到了如何处理 SQLite 中的图像并将其显示在 ListView 中并带有 TextView 描述的问题...这些是我的类:

数据库助手

public class DatabaseHelper extends SQLiteOpenHelper {

 // Table Name
 public static final String TABLE_NAME = "COUNTRIES";

 // Table columns
 public static final String _ID = "_id";
 public static final String SUBJECT = "subject";
 public static final String DESC = "description";
 public static final String KEY_IMAGE = "image";

 // Database Information
 static final String DB_NAME = "JOURNALDEV_COUNTRIES.DB";

 // database version
 static final int DB_VERSION = 5;

 // Creating table query
 private static final String CREATE_TABLE = "create table " + TABLE_NAME + "(" + _ID
         + " INTEGER PRIMARY KEY AUTOINCREMENT, " + SUBJECT + " TEXT NOT NULL, " + DESC + " TEXT," +
         KEY_IMAGE + " BLOB);";

 public DatabaseHelper(Context context) {
     super(context, DB_NAME, null, DB_VERSION);
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
     db.execSQL(CREATE_TABLE);
 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
     onCreate(db);
 }

 public void insertBitmap(Bitmap bm)  {

     // Convert the image into byte array
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
     byte[] buffer=out.toByteArray();
     // Open the database for writing
     SQLiteDatabase db = this.getWritableDatabase();
     // Start the transaction.
     db.beginTransaction();
     ContentValues values;

     try
     {
         values = new ContentValues();
         values.put("image", buffer);
         // Insert Row
         long i = db.insert(TABLE_NAME, null, values);
         Log.i("Insert", i + "");
         // Insert into database successfully.
         db.setTransactionSuccessful();

     }
     catch (SQLiteException e)
     {
         e.printStackTrace();

     }
     finally
     {
         db.endTransaction();
         // End the transaction.
         db.close();
         // Close database
     }
 }

 public Bitmap getBitmap(int id){
     Bitmap bitmap = null;
     // Open the database for reading
     SQLiteDatabase db = this.getReadableDatabase();
     // Start the transaction.
     db.beginTransaction();

     try
     {
         String selectQuery = "SELECT * FROM "+ TABLE_NAME+" WHERE id = " + id;
         Cursor cursor = db.rawQuery(selectQuery, null);
         if(cursor.getCount() >0)
         {
             while (cursor.moveToNext()) {
                 // Convert blob data to byte array
                 byte[] blob = cursor.getBlob(cursor.getColumnIndex("image"));
                 // Convert the byte array to Bitmap
                 bitmap= BitmapFactory.decodeByteArray(blob, 0, blob.length);

             }

         }
         db.setTransactionSuccessful();

     }
     catch (SQLiteException e)
     {
         e.printStackTrace();

     }
     finally
     {
         db.endTransaction();
         // End the transaction.
         db.close();
         // Close database
     }
     return bitmap;

 } }

数据库管理器

public class DBManager {

  private DatabaseHelper dbHelper;

 private Context context;

 private SQLiteDatabase database;

 public DBManager(Context c) {
     context = c;
 }

 public DBManager open() throws SQLException {
     dbHelper = new DatabaseHelper(context);
     database = dbHelper.getWritableDatabase();
     return this;
 }

 public void close() {
     dbHelper.close();
 }

 public void insert(String name, String desc, String image) {
     ContentValues contentValue = new ContentValues();
     contentValue.put(DatabaseHelper.SUBJECT, name);
     contentValue.put(DatabaseHelper.DESC, desc);
     contentValue.put(DatabaseHelper.KEY_IMAGE, image);
     database.insert(DatabaseHelper.TABLE_NAME, null, contentValue);
 }

 public Cursor fetch() {
     String[] columns = new String[] { DatabaseHelper._ID, DatabaseHelper.SUBJECT, DatabaseHelper.DESC,
             DatabaseHelper.KEY_IMAGE };
     Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, null, null, null, null, null);
     if (cursor != null) {
         cursor.moveToFirst();
     }
     return cursor;
 }

 public int update(long _id, String name, String desc, String image) {
     ContentValues contentValues = new ContentValues();
     contentValues.put(DatabaseHelper.SUBJECT, name);
     contentValues.put(DatabaseHelper.DESC, desc);
     contentValues.put(DatabaseHelper.KEY_IMAGE, image);
     int i = database.update(DatabaseHelper.TABLE_NAME, contentValues, DatabaseHelper._ID + " = " + _id, null);
     return i;
 }

 public void delete(long _id) {
     database.delete(DatabaseHelper.TABLE_NAME, DatabaseHelper._ID + "=" + _id, null);
 }

 }

国家列表活动

public class CountryListActivity extends ActionBarActivity {

 private DBManager dbManager;

 private ListView listView;

 private SimpleCursorAdapter adapter;


 final String[] from = new String[] {
         DatabaseHelper.SUBJECT, DatabaseHelper.DESC, DatabaseHelper.KEY_IMAGE };

 final int[] to = new int[] { R.id.title, R.id.desc, R.id.ivSlika };

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);

     setContentView(R.layout.fragment_emp_list);

     dbManager = new DBManager(this);
     dbManager.open();
     Cursor cursor = dbManager.fetch();

     listView = (ListView) findViewById(R.id.list_view);
     listView.setEmptyView(findViewById(R.id.empty));

     adapter = new SimpleCursorAdapter(this, R.layout.activity_view_record, cursor, from, to, 0);
     adapter.notifyDataSetChanged();

     listView.setAdapter(adapter);

     // OnCLickListiner For List Items
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long viewId) {
             //TextView idTextView = (TextView) view.findViewById(R.id.id);
             TextView titleTextView = (TextView) view.findViewById(R.id.title);
             TextView descTextView = (TextView) view.findViewById(R.id.desc);
             ImageView slikaImageView = (ImageView) findViewById(R.id.ivSlika);

             //String id = idTextView.getText().toString();
             String title = titleTextView.getText().toString();
             String desc = descTextView.getText().toString();
             String image = slikaImageView.toString();

             //ByteArrayOutputStream blob = new ByteArrayOutputStream();
             //byte[] bitmapdata = blob.toByteArray();
             //Bitmap bm = BitmapFactory.decodeByteArray(bitmapdata, 0, bitmapdata.length);

             Intent modify_intent = new Intent(getApplicationContext(), ModifyCountryActivity.class);
             modify_intent.putExtra("title", title);
             modify_intent.putExtra("desc", desc);
             //modify_intent.putExtra("id", id);
             modify_intent.putExtra("image", image);


             startActivity(modify_intent);
         }
     });
 }

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

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {

     int id = item.getItemId();
     if (id == R.id.add_record) {

         Intent add_mem = new Intent(this, AddCountryActivity.class);
         startActivity(add_mem);

     }
     return super.onOptionsItemSelected(item);
 }

 }

我已尝试将图像放入 ListView,但它似乎无法正常工作,因为 ListView 仅显示文本。我试过使用上面的代码,但是没有用。

我应该怎么做才能在 ListView 中显示图像并将其保存在 SQLite 中,以便在应用重新启动后重新出现?

谢谢!

【问题讨论】:

  • 不,请,不。您不得将图像存储在数据库中。将其存储在您想要的任何位置,但 databasesharedpreferences
  • 不要将图像存储在数据库中。将图像存储在应用程序的私有存储中,并将它们的路径存储在数据库表中。 2nd使用自定义适配器在ListView中显示图像
  • @SharpEdge 你能帮我更正我的代码吗?

标签: android sqlite listview imageview


【解决方案1】:

首先,您不应该将图像存储在数据库中。您应该将图像作为文件存储在应用程序的目录或缓存中,并将这些文件的 URI 存储在数据库中。或者将它们作为资源包含在您的应用中。

其次,您的图片来自哪里?它们是由应用程序本身生成的,还是您从服务器上下载的?如果是后者,那么你应该查看一个库来帮助你处理这个问题,像 Picasso 这样的东西会很好。

最后,不要使用ListView 让您的生活更加艰难。查看RecyclerView,因为它是一个更好的 API。

【讨论】:

  • 嗨 vkislicins,我可以快速询问一下您上面的所有答案,将图像编码为 base64 并将字符串存储在数据库中怎么样?这样做可以吗?
  • 嘿@chirag90。你有理由这样做吗? Base64 编码不会改变您在数据库中存储文件表示的事实。在我看来 - 存储参考,而不是文件。您不想从数据库读取/写入太多数据。此外,您不希望您的数据库过于臃肿,因为它通常由 Android 备份。
  • 嗨,这完全有道理,它只是我想知道的。感谢您的解释。
  • @vkislicins 好的,你能帮我修改代码,关于不在数据库中保存图像吗?
  • @vkislicins 图片在 res/drawable 文件夹中
猜你喜欢
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
  • 2015-03-16
  • 2016-06-25
  • 2018-11-11
  • 2016-01-08
  • 2020-03-25
  • 2017-11-17
相关资源
最近更新 更多