簡體   English   中英

如何從Android中的數據庫檢索大型BLOB?

[英]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. 

那么如何從數據庫中調用所有圖像呢?

將圖像存儲在數據庫中不是一個好主意。而是存儲指向圖像的URI。並將圖像存儲在文件夾中。

如果您仍想將其存儲為字節形式在數據庫中,則可以在此處查看

但是請記住,游標大小不能超過1MB。

您應該將圖像的路徑存儲到數據庫中,並使用該路徑訪問/顯示圖像。


一個例子

以下是為方便起見,將圖像(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM