我想在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);
}
}
答案 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"};
:-
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";
:-
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 目录。
:-
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 方法添加到数据库中。
插入后,所有数据都提取到游标中,然后将游标转储(写入日志)。
根据:-
将图像复制到资源文件夹中然后运行该应用,然后日志包含:-
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
对于这3张图片,图片列也是空。
对于其他两个(较小)图像,图像列为不可打印(即BLOB),而图像路径列为空。
除了上述测试/检查以下两个屏幕截图外,请确认是否已存储较大的照片。
首先显示资产文件夹中每个资产文件夹的文件大小的资产:-
第二个应用程序的内部存储(数据/数据/):-
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:-
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时,最好将图像存储在数据库中。 这样的实验可能会确定更好的限制。