You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将图片Uri或Bitmap适配为SQLite插入方法的int类型参数以实现图片存储?

解决SQLite存储相册图片的类型不匹配问题

兄弟,你现在的核心问题是数据库存储图片的思路错了——int类型只能存储像R.drawable.xxx这种APP内置资源的ID,根本存不了从相册选来的图片内容。想要把图片存入SQLite,必须把图片转成二进制字节数组(byte[]),然后用SQLite的BLOB类型字段来存储。下面给你一步步修正的方案:

1. 修改数据库表结构(SQ_Lite_DB类中)

首先要把原来存图片的int类型字段改成BLOB类型,在onCreate方法里的建表语句要更新:

@Override
public void onCreate(SQLiteDatabase db) {
    // 把image字段类型从INTEGER改成BLOB
    String createTable = "CREATE TABLE orders (id INTEGER PRIMARY KEY AUTOINCREMENT, image BLOB, name TEXT)";
    db.execSQL(createTable);
}

如果已经创建过表,记得要么卸载重装APP,要么在onUpgrade里处理表结构更新(比如删除旧表重建,或者添加字段)。

2. 修正insertData方法的参数和逻辑

把原来接收int类型图片的参数改成byte[],同时注意写入数据库要用getWritableDatabase()(之前用getReadableDatabase()虽然能凑合用,但写入操作明确用前者更规范):

public boolean insertData(byte[] image, String name){
    SQLiteDatabase database = getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("image", image);
    values.put("name", name);
    long id = database.insert("orders", null, values);
    database.close();
    return id > 0;
}

3. 在onActivityResult中调用修正后的方法

你已经把Bitmap转成了byte[],现在直接把这个数组传给insertData就行,同时修正代码里的小错误(比如editText的拼写和getText()的调用):

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    edittext = findViewById(R.id.edittext);
    SQ_Lite_DB db = new SQ_Lite_DB(SQLite.this);
    if (resultCode == RESULT_OK && requestCode == 11){
        try {
            InputStream inputStream = getContentResolver().openInputStream(data.getData());
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            
            // 可选:如果图片太大,建议先缩放压缩,避免数据库体积暴涨
            int targetSize = 500;
            float scale = Math.min((float)targetSize/bitmap.getWidth(), (float)targetSize/bitmap.getHeight());
            Matrix matrix = new Matrix();
            matrix.postScale(scale, scale);
            Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            scaledBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] img = baos.toByteArray();
            
            // 调用修正后的insertData方法
            boolean isSuccess = db.insertData(img, edittext.getText().toString());
            Toast.makeText(this, isSuccess ? "数据插入成功" : "插入失败", Toast.LENGTH_SHORT).show();
            
            // 插入成功后记得刷新RecyclerView的数据,让新内容显示出来
            // 比如重新调用ReadSqliteData更新list,然后通知adapter刷新
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(this, "读取图片失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            Log.d("tag", e.getMessage());
        }
    }
}

4. 读取数据时转成Bitmap的补充

之后从数据库读取图片时,要把BLOB转回Bitmap,比如在你的ReadSqliteData方法里:

// 假设cursor是查询结果
byte[] imageBytes = cursor.getBlob(cursor.getColumnIndexOrThrow("image"));
Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
// 把bitmap传给Model,再刷新RecyclerView

最后提醒

  • 不要每次操作数据库都新建SQ_Lite_DB实例,建议在Activity里全局持有一个,减少资源开销
  • 大图片存SQLite会导致数据库体积急剧增大,甚至影响性能,所以压缩很有必要;如果图片很多,更推荐只存图片的Uri路径到数据库,图片本身存在外部存储里,这样更高效

内容的提问来源于stack exchange,提问作者Sachin Burdak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:52:43