[英]How to retrieve a large BLOB from database in android?
我這樣將圖像字節保存到數據庫中。
byte[] imagebyte = getBytes(bitmap);
boolean isuploaded = myDb.insertData("all_receipts",imagebyte);
public byte[] getBytes(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 70, stream);
return stream.toByteArray();
}
然后,我在數據庫助手類中創建了一個檢索方法來檢索所有數據。
public ArrayList<Model.Receipts> convertoArray(String tablename){
ArrayList<Model.Receipts> receiptsArrayList = new ArrayList<>();
Model.Receipts receipt;
SQLiteDatabase database = this.getReadableDatabase();
String selectQuery = "SELECT * FROM all_receipts";
if(tablename.equalsIgnoreCase("all_receipts")){
Cursor cursor = database.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
int indexnumber = cursor.getInt(0);
Bitmap image = getImage(cursor.getBlob(1));
receipt = new Model.Receipts(image,indexnumber);
receiptsArrayList.add(receipt);
}
while (cursor.moveToNext());
}
}
return receiptsArrayList;
}
這與我從相機捕獲的圖像的縮略圖配合正常。 但是,當我對完整尺寸的圖像使用相同的方法時,它不起作用。 我得到錯誤
Unable to start activity java.lang.IllegalStateException: Couldn't read row 0, col 0 from
CursorWindow。 在從游標訪問數據之前,請確保游標已正確初始化。 在
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)位於> android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2309)位於?> android.app.ActivityThread.access $ 700(ActivityThread.java:157)位於> android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1289)
From which I know that it's because that the BLOB is too big in the database.
那么如何從數據庫中調用所有圖像呢?
您應該將圖像的路徑存儲到數據庫中,並使用該路徑訪問/顯示圖像。
以下是為方便起見,將圖像(image001.JPG至image010.JPG)存儲在資源文件夾中的示例。
該示例顯示圖像的列表(ListView)以及1張圖像,單擊列表中的項目會更改顯示,以通過存儲的路徑顯示相應的圖像。
首先,布局activity_main.xml ( 注意,必須相應地更改程序包名稱 ):-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.sqliteexamples.MainActivity">
<ListView
android:id="@+id/imagelist"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/myimage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="myImage"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
DatabaseHelper ImgDBHelper.java
public class ImgDBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "myimagestore";
public static final String TBLNAME = "images";
public static final String ID_COL = "_id";
public static final String DSCR_COL = "description";
public static final String PATH_COL = "path"; //<<<<<<<<
SQLiteDatabase db;
ImgDBHelper(Context context) {
super(context,DBNAME,null,1);
db = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crtsql = "CREATE TABLE IF NOT EXISTS " + TBLNAME + "(" +
ID_COL + " INTEGER PRIMARY KEY, " +
DSCR_COL + " TEXT," +
PATH_COL + " TEXT" +
")";
db.execSQL(crtsql);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public void addImageRow(String path, String description) {
Cursor csr = db.query(TBLNAME,null,PATH_COL + "=?",new String[]{path},null,null,null);
// DO NOT ADD DUPLICATE IMAGES (according to path)
if (csr.getCount() > 0) {
csr.close();
return;
}
csr.close();
ContentValues cv = new ContentValues();
cv.put(DSCR_COL,description);
cv.put(PATH_COL,path);
db.insert(TBLNAME,null,cv);
}
public Cursor getAllImages() {
return db.query(TBLNAME,null,null,null,null,null,null);
}
public String getImagePathFromID(long id) {
String rv = "";
Cursor csr = db.query(TBLNAME,
null,
"_id=?",
new String[]{Long.toString(id)},
null,null,null
);
if (csr.moveToFirst()) {
rv = csr.getString(csr.getColumnIndex(PATH_COL));
}
csr.close();
return rv;
}
public boolean areImagesLoaded() {
Cursor csr = db.query(TBLNAME,null,null,null,null,null,null);
boolean rv = (csr.getCount() > 0);
csr.close();
return rv;
}
}
和活動MainActivity.java
public class MainActivity extends AppCompatActivity {
Drawable d; // drawable for the image
String imagepath = "image001.JPG"; // initial image
ImgDBHelper imgdbhlpr; // DB Helper
ListView imagelist; // ListView
SimpleCursorAdapter sca; // ListView's Cursor adapter
Cursor images; // Cursor for the ListView
ImageView iv; // The ImageView to display the image
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imagelist = (ListView) findViewById(R.id.imagelist);
iv = (ImageView) findViewById(R.id.myimage);
imgdbhlpr = new ImgDBHelper(this);
// Load the table if there are no images
if (!imgdbhlpr.areImagesLoaded()) {
for (int i=1;i < 11;i++) {
String path = "image" +
String.format("%03d",i) +
".JPG"
;
imgdbhlpr.addImageRow(path,"Image " +
String.format("%03d",i));
}
}
// get a cursor with all of the rows
images = imgdbhlpr.getAllImages();
// prepare the listview's adapter
sca = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
images,
new String[]{ImgDBHelper.DSCR_COL},
new int[]{android.R.id.text1},
0
);
// set the Listview's onItemClick listener so that clicking an
// item displays the respective image
imagelist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
iv.setImageDrawable(d = getImageFromAssets(
imgdbhlpr.getImagePathFromID(l)
));
}
});
imagelist.setAdapter(sca);
// set the initial image (image001.JPG)
d = getImageFromAssets(imagepath);
iv.setImageDrawable(d);
}
// routine to create a drawable according to the supplied path
private Drawable getImageFromAssets(String imagepath) {
Drawable drawable = null;
AssetManager am = this.getAssets();
InputStream is = null;
try {
is = am.open(imagepath);
} catch (Exception e) {
e.printStackTrace();
}
try {
drawable = Drawable.createFromStream(is,null);
} finally {
try {
is.close();
is = null;
} catch (Exception e) {
e.printStackTrace();
}
}
return drawable;
}
}
最初運行時:-
然后單擊Listview(image004)后:-
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.