我需要帮助将图像存储在内部目录中,并且其路径已插入SQLite

时间:2019-05-31 09:46:48

标签: java android database sqlite android-sqlite

我想在SQLite数据库中存储较大的BLOBS或类似数据,因为现在我不能上传大小超过2mb的图像

此问题的解决方案是将我的图像存储在内部目录中,并且其路径是在SQLite DB中插入

过去3天,我一直在尝试解决此问题,因为我是Java的新手,而且我不知道如何存储它

如果您能帮助我解决这个问题,我将不胜感激

这是我的代码:

CrudActivity

    EditText mEdtName, mEdtStok, mEdtJual;
    Button mBtnAdd, mBtnList;
    ImageView mImageView;

    final int REQUEST_CODE_GALLERY = 999;

    public static SQLiteHelper mSQLiteHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crud);

        mEdtName = findViewById(R.id.edtName);
        mEdtStok = findViewById(R.id.edtStok);
        mEdtJual = findViewById(R.id.edtJual);
        mBtnAdd = findViewById(R.id.btnAdd);
        mBtnList = findViewById(R.id.btnList);
        mImageView = findViewById(R.id.imageView);

        //creating database
        mSQLiteHelper = new SQLiteHelper(this, "RECORDDB.sqlite", null, 1);

        //creating table in database
        mSQLiteHelper.queryData("CREATE TABLE IF NOT EXISTS RECORD(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, stok VARCHAR, jual VARCHAR, image BLOB)");


        //select image by on imageview click
        mImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //read external storage permission to select image from gallery
                //runtime permission for devices android 6.0 and above
                ActivityCompat.requestPermissions(
                        CrudActivity.this,
                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_CODE_GALLERY
                );
            }
        });

        //add record to sqlite
        mBtnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    mSQLiteHelper.insertData(
                            mEdtName.getText().toString().trim(),
                            mEdtStok.getText().toString().trim(),
                            mEdtJual.getText().toString().trim(),
                            imageViewToByte(mImageView)
                    );
                    Toast.makeText(CrudActivity.this, "Added successfully", Toast.LENGTH_SHORT).show();
                    //reset views
                    mEdtName.setText("");
                    mEdtStok.setText("");
                    mEdtJual.setText("");
                    mImageView.setImageResource(R.drawable.addphoto);
                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }
        });

        //show record list
        mBtnList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //start recordlist activity
                startActivity(new Intent(CrudActivity.this, RecordListActivity.class));
            }
        });


    }

    public static byte[] imageViewToByte(ImageView image) {
        Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        return byteArray;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_CODE_GALLERY){
            if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //gallery intent
                Intent galleryIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                galleryIntent.setType("image/*");
                startActivityForResult(galleryIntent, REQUEST_CODE_GALLERY);
            }
            else {
                Toast.makeText(this, "Don't have permission to access file location", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Intent intent;
        intent = new Intent(Intent.ACTION_GET_CONTENT);

        if (requestCode == REQUEST_CODE_GALLERY && resultCode == RESULT_OK){
            Uri imageUri = data.getData();
            final int takeFlags = intent.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
            getContentResolver().takePersistableUriPermission(imageUri, takeFlags);
            CropImage.activity(imageUri)
                    .setGuidelines(CropImageView.Guidelines.ON) //enable image guidlines
                    .setAspectRatio(1,1)// image will be square
                    .start(this);

        }
        if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){
            CropImage.ActivityResult result =CropImage.getActivityResult(data);
            if (resultCode == RESULT_OK){
                Uri resultUri = result.getUri();
                //set image choosed from gallery to image view
                mImageView.setImageURI(resultUri);
            }
            else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE){
                Exception error = result.getError();
            }

        }

        super.onActivityResult(requestCode, resultCode, data);
    }
}

SQLiteHelper

  public class SQLiteHelper extends SQLiteOpenHelper{

    //constructor
    SQLiteHelper(Context context,
                 String name,
                 SQLiteDatabase.CursorFactory factory,
                 int version){
        super(context, name, factory, version);
    }

    public void queryData(String sql){
        SQLiteDatabase database = getWritableDatabase();
        database.execSQL(sql);
    }

    //insertData
    public void insertData(String name, String stok, String jual, byte[] image){
        SQLiteDatabase database = getWritableDatabase();
        //query to insert record in database table
        String sql = "INSERT INTO RECORD VALUES(NULL, ?, ?, ?, ?)"; //where "RECORD" is table name in database we will create in mainActivity

        SQLiteStatement statement = database.compileStatement(sql);
        statement.clearBindings();

        statement.bindString(1, name);
        statement.bindString(2, stok);
        statement.bindString(3, jual);
        statement.bindBlob(4, image);

        statement.executeInsert();
    }

    //updateData
    public void updateData(String name, String stok, String jual, byte[] image, int id){
        SQLiteDatabase database = getWritableDatabase();
        //query to update record
        String sql = "UPDATE RECORD SET name=?, stok=?, jual=?, image=? WHERE id=?";

        SQLiteStatement statement = database.compileStatement(sql);

        statement.bindString(1, name);
        statement.bindString(2, stok);
        statement.bindString(3, jual);
        statement.bindBlob(4, image);
        statement.bindDouble(5, (double)id);

        statement.execute();
        database.close();
    }

    //deleteData
    public void deleteData(int id){
        SQLiteDatabase database = getWritableDatabase();
        //query to delete record using id
        String sql = "DELETE FROM RECORD WHERE id=?";

        SQLiteStatement statement = database.compileStatement(sql);
        statement.clearBindings();
        statement.bindDouble(1, (double)id);

        statement.execute();
        database.close();
    }

    public Cursor getData(String sql){
        SQLiteDatabase database = getReadableDatabase();
        return database.rawQuery(sql, null);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

RecordListActivity

public class RecordListActivity extends AppCompatActivity {

    ListView mListView;
    ArrayList<Model> mList;
    RecordListAdapter mAdapter = null;

    ImageView imageViewIcon;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record_list);

        mListView = findViewById(R.id.listView);
        mList = new ArrayList<>();
        mAdapter = new RecordListAdapter(this, R.layout.row, mList);
        mListView.setAdapter(mAdapter);

        //get all data from sqlite
        SQLiteHelper mSQLiteHelper = new SQLiteHelper(this, "RECORDDB.sqlite", null, 1);
        Cursor cursor = mSQLiteHelper.getData("SELECT * FROM RECORD");
        mList.clear();
        while (cursor.moveToNext()){
            int id = cursor.getInt(0);
            String name = cursor.getString(1);
            String stok = cursor.getString(2);
            String jual = cursor.getString(3);
            byte[] image  = cursor.getBlob(4);
            //add to list
            mList.add(new Model(id, name, stok, jual, image));
        }
        mAdapter.notifyDataSetChanged();
        if (mList.size()==0){
            //if there is no record in table of database which means listview is empty
            Toast.makeText(this, "No record found...", Toast.LENGTH_SHORT).show();
        }

        mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int position, long l) {
                //alert dialog to display options of update and delete
                final CharSequence[] items = {"Update", "Delete"};

                AlertDialog.Builder dialog = new AlertDialog.Builder(RecordListActivity.this);

                dialog.setTitle("Choose an action");
                dialog.setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (i == 0){
                            //update
                            Cursor c = CrudActivity.mSQLiteHelper.getData("SELECT id FROM RECORD");
                            ArrayList<Integer> arrID = new ArrayList<Integer>();
                            while (c.moveToNext()){
                                arrID.add(c.getInt(0));
                            }
                            //show update dialog
                            showDialogUpdate(RecordListActivity.this, arrID.get(position));
                        }
                        if (i==1){
                            //delete
                            Cursor c = CrudActivity.mSQLiteHelper.getData("SELECT id FROM RECORD");
                            ArrayList<Integer> arrID = new ArrayList<Integer>();
                            while (c.moveToNext()){
                                arrID.add(c.getInt(0));
                            }
                            showDialogDelete(arrID.get(position));
                        }
                    }
                });
                dialog.show();
                return true;
            }
        });


    }

    private void showDialogDelete(final int idRecord) {
        AlertDialog.Builder dialogDelete = new AlertDialog.Builder(RecordListActivity.this);
        dialogDelete.setTitle("Warning!!");
        dialogDelete.setMessage("Are you sure to delete?");
        dialogDelete.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                try {
                    CrudActivity.mSQLiteHelper.deleteData(idRecord);
                    Toast.makeText(RecordListActivity.this, "Delete successfully", Toast.LENGTH_SHORT).show();
                }
                catch (Exception e){
                    Log.e("error", e.getMessage());
                }
                updateRecordList();
            }
        });
        dialogDelete.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
            }
        });
        dialogDelete.show();
    }

    private void showDialogUpdate(Activity activity, final int position){
        final Dialog dialog = new Dialog(activity);
        dialog.setContentView(R.layout.update_dialog);
        dialog.setTitle("Update");

        imageViewIcon = dialog.findViewById(R.id.imageViewRecord);
        final EditText edtName = dialog.findViewById(R.id.edtName);
        final EditText edtStok = dialog.findViewById(R.id.edtStok);
        final EditText edtJual = dialog.findViewById(R.id.edtJual);
        Button btnUpdate = dialog.findViewById(R.id.btnUpdate);

        //set width of dialog
        int width = (int)(activity.getResources().getDisplayMetrics().widthPixels*0.95);
        //set hieght of dialog
        int height = (int)(activity.getResources().getDisplayMetrics().heightPixels*0.7);
        dialog.getWindow().setLayout(width,height);
        dialog.show();

        //in update dialog click image view to update image
        imageViewIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //check external storage permission
                ActivityCompat.requestPermissions(
                        RecordListActivity.this,
                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                        888
                );
            }
        });
        btnUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    CrudActivity.mSQLiteHelper.updateData(
                            edtName.getText().toString().trim(),
                            edtStok.getText().toString().trim(),
                            edtJual.getText().toString().trim(),
                            CrudActivity.imageViewToByte(imageViewIcon),
                            position
                    );
                    dialog.dismiss();
                    Toast.makeText(getApplicationContext(), "Update Successfull", Toast.LENGTH_SHORT).show();
                }
                catch (Exception error){
                    Log.e("Update error", error.getMessage());
                }
                updateRecordList();
            }
        });

    }

    private void updateRecordList() {
        //get all data from sqlite
        Cursor cursor = CrudActivity.mSQLiteHelper.getData("SELECT * FROM RECORD");
        mList.clear();
        while (cursor.moveToNext()){
            int id = cursor.getInt(0);
            String name = cursor.getString(1);
            String stok = cursor.getString(2);
            String jual = cursor.getString(3);
            byte[] image = cursor.getBlob(4);

            mList.add(new Model(id,name,stok,jual,image));
        }
        mAdapter.notifyDataSetChanged();
    }


    public static byte[] imageViewToByte(ImageView image) {
        Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        return byteArray;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 888){
            if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //gallery intent
                Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
                galleryIntent.setType("image/*");
                startActivityForResult(galleryIntent, 888);
            }
            else {
                Toast.makeText(this, "Don't have permission to access file location", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Intent intent;
        intent = new Intent(Intent.ACTION_GET_CONTENT);

        if (requestCode == 888 && resultCode == RESULT_OK){
            Uri imageUri = data.getData();
            final int takeFlags = intent.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
            getContentResolver().takePersistableUriPermission(imageUri, takeFlags);
            CropImage.activity(imageUri)
                    .setGuidelines(CropImageView.Guidelines.ON) //enable image guidlines
                    .setAspectRatio(1,1)// image will be square
                    .start(this);
        }
        if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){
            CropImage.ActivityResult result =CropImage.getActivityResult(data);
            if (resultCode == RESULT_OK){
                Uri resultUri = result.getUri();
                //set image choosed from gallery to image view
                imageViewIcon.setImageURI(resultUri);
            }
            else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE){
                Exception error = result.getError();
            }
        }

        super.onActivityResult(requestCode, resultCode, data);
    }
}

1 个答案:

答案 0 :(得分:4)

下面的演示会将图像存储在数据库中或应用程序的内部存储中。

如果图像大小小于256k(根据public static final int MAX_IMAGESIZETOSTORE = 1024 * 256;),它将存储在数据库中,并可从数据库中检索。

如果图像大于或等于256k(根据public static final int MAXIMAGEBUFFER = 1024 * 1024 * 16;,演示必须具有16MB的限制),则它将存储在应用程序的Files / myimagestores目录(演示创建的myimagestores目录)中,并且图像的路径存储在数据库中。

演示而不是从照相机中获取图像,而是从资产文件夹中获取图像(演示中使用了5个)。

如果图像不在资源文件夹中,并且没有按照以下匹配名称进行定义,则代码将无法正常工作:

String[] imagesToGet = new String[]{"sample001.jpg","sample002.jpg","sample003.jpg","sample004.jpg","sample005.jpg"};

代码

SQLiteHelper.java

  • 基本上,这是您的帮手,具有经过修改的 insertData 方法

:-

public long insertData(String name, String stok, String jual, byte[] image) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(RECORD_COL_NAME,name);
    cv.put(RECORD_COL_STOK,stok);
    cv.put(RECORD_COL_JUAL,jual);
    if (image.length > 0 && image.length < MAX_IMAGESIZETOSTORE) {
        cv.put(RECORD_COL_IMAGE,image);
    } else {
            cv.put(RECORD_COL_IMAGEPATH,StoreImage.storeImage(mContext,image,name));
    }
    return db.insert(TBLNAME_RECORD,null,cv);
} 

在类级别声明以下常量:-

public static final int MAX_IMAGESIZETOSTORE = 1024 * 256;

public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;

public static final String TBLNAME_RECORD = "record";
public static final String RECORD_COl_ID = BaseColumns._ID;
public static final String RECORD_COL_NAME = "name";
public static final String RECORD_COL_STOK = "stok";
public static final String RECORD_COL_JUAL = "jual";
public static final String RECORD_COL_IMAGE = "image";
public static final String RECORD_COL_IMAGEPATH = "imagepath";
  • 可以看到另外一列,添加了 imagepath 来存储图像的路径(如果图像存储在数据库中,则为null;反之亦然,如果未存储图像,则为null在数据库中,但图片列为文件)。

StoreImage.java是

:-

public class StoreImage {

    public static final String IMAGESTOREDIRECTORY = "myimagestore";

    public static String storeImage(Context context, byte[] image, String imagename) {

        File mFilesDirectory = context.getFilesDir();
        File mImageStoreDirectory = new File(mFilesDirectory.getPath() + File.separator + IMAGESTOREDIRECTORY);
        if (!mImageStoreDirectory.exists()) {
            mImageStoreDirectory.mkdirs();
        }
        File mImageStore = new File(mImageStoreDirectory.getPath() + File.separator + imagename);
        OutputStream os;
        try {
            os = new FileOutputStream(mImageStore);
            os.write(image);
            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mImageStore.getPath();
    }
}

从上面可以看到, StoreImage 类的 storeImage 方法存储图像((传递给 insertData 的byte [] SQliteHelper 类的方法。

也可以看到,上面将在需要时创建 myimagestore 目录。

MainActivity.java是

:-

public class MainActivity extends AppCompatActivity {

    public static final int MAXIMAGEBUFFER = 1024 * 1024 * 16;
    SQLiteHelper mDBHlpr;

    // The demo images copied into the assets folder
    String[] imagesToGet = new String[]{"sample001.jpg","sample002.jpg","sample003.jpg","sample004.jpg","sample005.jpg"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHlpr = new SQLiteHelper(this);

        for (String s: imagesToGet) {
            mDBHlpr.insertData(s,"stock for " + s,"jual for " + s,getImage(s));
        }

        Cursor csr = mDBHlpr.getData("SELECT * FROM RECORD;");
        DatabaseUtils.dumpCursor(csr);
        csr.close();
    }


    //Get a demo image from the assets folder
    private byte[] getImage(String name) {

        byte[] buffer = new byte[0];
        try {
            AssetFileDescriptor afd = this.getAssets().openFd(name);
            long fsz = afd.getLength();
            if (fsz < MAXIMAGEBUFFER) {
                InputStream is = this.getAssets().open(name);
                buffer = new byte[(int) fsz];
                is.read(buffer, 0, (int) fsz);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }
}

getImage 方法(大部分活动)从资产文件夹中检索图像(演示图像)。

5个演示图像进行循环处理,并通过 insertData 方法添加到数据库中。

插入后,所有数据都提取到游标中,然后将游标转储(写入日志)。

示例运行:-

根据:-

将图像复制到资源文件夹中

enter image description here

然后运行该应用,然后日志包含:-

06-01 08:59:14.828 7728-7728/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@cd7f7ce
06-01 08:59:14.828 7728-7728/? I/System.out: 0 {
06-01 08:59:14.828 7728-7728/? I/System.out:    _id=1
06-01 08:59:14.828 7728-7728/? I/System.out:    name=sample001.jpg
06-01 08:59:14.828 7728-7728/? I/System.out:    stok=stock for sample001.jpg
06-01 08:59:14.828 7728-7728/? I/System.out:    jual=jual for sample001.jpg
06-01 08:59:14.828 7728-7728/? I/System.out:    image=null
06-01 08:59:14.828 7728-7728/? I/System.out:    imagepath=/data/user/0/s.e.so56392635storeimage/files/myimagestore/sample001.jpg
06-01 08:59:14.828 7728-7728/? I/System.out: }
06-01 08:59:14.828 7728-7728/? I/System.out: 1 {
06-01 08:59:14.828 7728-7728/? I/System.out:    _id=2
06-01 08:59:14.828 7728-7728/? I/System.out:    name=sample002.jpg
06-01 08:59:14.828 7728-7728/? I/System.out:    stok=stock for sample002.jpg
06-01 08:59:14.828 7728-7728/? I/System.out:    jual=jual for sample002.jpg
06-01 08:59:14.828 7728-7728/? I/System.out:    image=null
06-01 08:59:14.828 7728-7728/? I/System.out:    imagepath=/data/user/0/s.e.so56392635storeimage/files/myimagestore/sample002.jpg
06-01 08:59:14.828 7728-7728/? I/System.out: }
06-01 08:59:14.829 7728-7728/? I/System.out: 2 {
06-01 08:59:14.829 7728-7728/? I/System.out:    _id=3
06-01 08:59:14.829 7728-7728/? I/System.out:    name=sample003.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    stok=stock for sample003.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    jual=jual for sample003.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    image=null
06-01 08:59:14.829 7728-7728/? I/System.out:    imagepath=/data/user/0/s.e.so56392635storeimage/files/myimagestore/sample003.jpg
06-01 08:59:14.829 7728-7728/? I/System.out: }
06-01 08:59:14.829 7728-7728/? I/System.out: 3 {
06-01 08:59:14.829 7728-7728/? I/System.out:    _id=4
06-01 08:59:14.829 7728-7728/? I/System.out:    name=sample004.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    stok=stock for sample004.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    jual=jual for sample004.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    image=<unprintable>
06-01 08:59:14.829 7728-7728/? I/System.out:    imagepath=null
06-01 08:59:14.829 7728-7728/? I/System.out: }
06-01 08:59:14.829 7728-7728/? I/System.out: 4 {
06-01 08:59:14.829 7728-7728/? I/System.out:    _id=5
06-01 08:59:14.829 7728-7728/? I/System.out:    name=sample005.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    stok=stock for sample005.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    jual=jual for sample005.jpg
06-01 08:59:14.829 7728-7728/? I/System.out:    image=<unprintable>
06-01 08:59:14.829 7728-7728/? I/System.out:    imagepath=null
06-01 08:59:14.829 7728-7728/? I/System.out: }
06-01 08:59:14.829 7728-7728/? I/System.out: <<<<<

这表示sample001.jpg-sample003.jpg已存储为文件,例如sample001.jpg(就数据库而言)存储在 /data/user/0/s.e.so56392635storeimage/files/myimagestore/sample001.jpg

  • 显然,软件包名称将与所使用的软件包相同,有时您可能会看到 /data/data/the_package_name/files/myimagestore/sample001.jpg

对于这3张图片,图片列也是

对于其他两个(较小)图像,图像列为不可打印(即BLOB),而图像路径列为

除了上述测试/检查以下两个屏幕截图外,请确认是否已存储较大的照片。

首先显示资产文件夹中每个资产文件夹的文件大小的资产:-

enter image description here

第二个应用程序的内部存储(数据/数据/):-

enter image description here

sample004.jpg sample005.jpg 不会出现,因为它们已存储在数据库中。

最后一个证据是已存储了较小的图像,然后对查询进行了简单的修改,按照:-

Cursor csr = mDBHlpr.getData("SELECT *, length(" + SQLiteHelper.RECORD_COL_IMAGE + ") FROM RECORD;");

结果:-

06-01 09:16:36.282 I/System.out:    _id=4
06-01 09:16:36.282 I/System.out:    name=sample004.jpg
06-01 09:16:36.282 I/System.out:    stok=stock for sample004.jpg
06-01 09:16:36.282 I/System.out:    jual=jual for sample004.jpg
06-01 09:16:36.282 I/System.out:    image=<unprintable>
06-01 09:16:36.282 I/System.out:    imagepath=null
06-01 09:16:36.282 I/System.out:    length(image)=9000 <<<<<<<<<<<<
06-01 09:16:36.283 I/System.out: }
06-01 09:16:36.283 I/System.out: 4 {
06-01 09:16:36.283 I/System.out:    _id=5
06-01 09:16:36.283 I/System.out:    name=sample005.jpg
06-01 09:16:36.283 I/System.out:    stok=stock for sample005.jpg
06-01 09:16:36.283 I/System.out:    jual=jual for sample005.jpg
06-01 09:16:36.283 I/System.out:    image=<unprintable>
06-01 09:16:36.283 I/System.out:    imagepath=null
06-01 09:16:36.283 I/System.out:    length(image)=28239 <<<<<<<<<<<<

其他SQliteHelper.java

这是完整的SQLiteHelper.java:-

public class SQLiteHelper extends SQLiteOpenHelper {

    public static final int MAX_IMAGESIZETOSTORE = 1024 * 256;

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String TBLNAME_RECORD = "record";
    public static final String RECORD_COl_ID = BaseColumns._ID;
    public static final String RECORD_COL_NAME = "name";
    public static final String RECORD_COL_STOK = "stok";
    public static final String RECORD_COL_JUAL = "jual";
    public static final String RECORD_COL_IMAGE = "image";
    public static final String RECORD_COL_IMAGEPATH = "imagepath";

    Context mContext;

    //constructor <<<<<<<<<< MODIFIED so just requires Context 
    //!!!!!!!!!!NOTE!!!!!!!!!! uses database/tables as defined in this class
    public SQLiteHelper(Context context){
        super(context,DBNAME, null, DBVERSION);
        mContext = context;
    }

    public void queryData(String sql){
        SQLiteDatabase database = getWritableDatabase();
        database.execSQL(sql);
    }

    public long insertData(String name, String stok, String jual, byte[] image) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(RECORD_COL_NAME,name);
        cv.put(RECORD_COL_STOK,stok);
        cv.put(RECORD_COL_JUAL,jual);
        if (image.length > 0 && image.length < MAX_IMAGESIZETOSTORE) {
            cv.put(RECORD_COL_IMAGE,image);
        } else {
                cv.put(RECORD_COL_IMAGEPATH,StoreImage.storeImage(mContext,image,name));
        }
        return db.insert(TBLNAME_RECORD,null,cv);
    }

    //insertData
    /**
    public void insertData(String name, String stok, String jual, byte[] image){
        SQLiteDatabase database = getWritableDatabase();
        //query to insert record in database table
        String sql = "INSERT INTO RECORD VALUES(NULL, ?, ?, ?, ?)"; //where "RECORD" is table name in database we will create in mainActivity

        SQLiteStatement statement = database.compileStatement(sql);
        statement.clearBindings();
        statement.bindString(1, name);
        statement.bindString(2, stok);
        statement.bindString(3, jual);
        statement.bindBlob(4, image);
        statement.executeInsert();
    }
     **/

    //updateData
    public void updateData(String name, String stok, String jual, byte[] image, int id){
        SQLiteDatabase database = getWritableDatabase();
        //query to update record
        String sql = "UPDATE RECORD SET name=?, stok=?, jual=?, image=? WHERE id=?";

        SQLiteStatement statement = database.compileStatement(sql);
        statement.bindString(1, name);
        statement.bindString(2, stok);
        statement.bindString(3, jual);
        statement.bindBlob(4, image);
        statement.bindDouble(5, (double)id);
        statement.execute();
        database.close();
    }

    //deleteData
    public void deleteData(int id){
        SQLiteDatabase database = getWritableDatabase();
        //query to delete record using id
        String sql = "DELETE FROM RECORD WHERE id=?";
        SQLiteStatement statement = database.compileStatement(sql);
        statement.clearBindings();
        statement.bindDouble(1, (double)id);
        statement.execute();
        database.close();
    }

    public Cursor getData(String sql){
        SQLiteDatabase database = getReadableDatabase();
        return database.rawQuery(sql, null);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TBLNAME_RECORD +
                "(" +
                RECORD_COl_ID + " INTEGER PRIMARY KEY," +
                RECORD_COL_NAME + " TEXT," +
                RECORD_COL_STOK + " TEXT," +
                RECORD_COL_JUAL + " TEXT," +
                RECORD_COL_IMAGE + " BLOB," +
                RECORD_COL_IMAGEPATH + " TEXT" +
                ")"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

在数据库中另外存储图像

选择256k限制是一个合理的大小,以不将图像存储在DB中。我猜想当您说 2MB下载限制时,您的意思是您遇到的CursorWindow限制为2MB,因此需要存储图像路径。

即使256k也可能太大,因为每个CursorWindow可能导致7行。因此可能会出现问题。但是,考虑到SQlite - 35% Faster Than The Filesystem的发现,那么在100k时,最好将图像存储在数据库中。 这样的实验可能会确定更好的限制。