0

I am trying to create local image database using SQLite. The app works well in the AVD, but when I try to run in my Samsung S6(Android 7.0, API 24). After several attempts of failures in running the app I have restore my device. Then app worked once or twice then it started showing the same errors as given below.

    06-12 19:34:10.292 17670-22492/com.example.eberhardt.test16 E/CursorWindow: Failed to read row 0, column 1 from a CursorWindow which has 0 rows, 2 columns.
06-12 19:34:10.343 17670-22492/com.example.eberhardt.test16 E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
    Process: com.example.eberhardt.test16, PID: 17670
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:318)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:762)
     Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetBlob(Native Method)
        at android.database.CursorWindow.getBlob(CursorWindow.java:416)
        at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:45)
        at com.example.eberhardt.test16.MainActivity$featureDetection.doInBackground(MainActivity.java:343)
        at com.example.eberhardt.test16.MainActivity$featureDetection.doInBackground(MainActivity.java:314)
        at android.os.AsyncTask$2.call(AsyncTask.java:304)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
        at java.lang.Thread.run(Thread.java:762)

 Codes for creating the image database is

package com.example.eberhardt.test16;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import static android.provider.BaseColumns._ID;

public class imageDatabase extends SQLiteOpenHelper {
    private static final String TAG = imageDatabase.class.getSimpleName();

    private static final String DATABASE_NAME = "features.db";
    private static final int DATABASE_VERSION = 1;
    ContentResolver mContentResolver;

    public final static String COLUMN_NAME = "imagename";
    public final static String TABLE_NAME = "imagetable";

    public imageDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        final String SQT_CREATE_IMAGE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_NAME + " BLOB" + ");";
        db.execSQL(SQT_CREATE_IMAGE_TABLE);
        Log.e(TAG, "Database creates successfully");
    }

    public void addToDb(byte[] image) throws SQLException {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_NAME, image);
        SQLiteDatabase db = this.getWritableDatabase();
        db.insert(TABLE_NAME, null, cv);
        db.close();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(" DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}

To store the Images

switch (requestCode){
            case OPEN_GALLERY:
                if(resultCode == RESULT_OK && data != null){
                    Uri uri = data.getData();
                    try {
                        imageBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
                    byte[] uploadData = outputStream.toByteArray();

                    imageDatabase dataBase = new imageDatabase(this);
                    dataBase.addToDb(uploadData);
                }
                break;
        }

To read the images

protected Void doInBackground(Void... voids) {
            imageDatabase imageDatabase = new imageDatabase(MainActivity.this);
            SQLiteDatabase mDatabase = imageDatabase.getReadableDatabase();
            Cursor cursor = mDatabase.rawQuery("Select * FROM imagetable", null);

            cursor.moveToFirst();
            Log.e("Number of rows", String.valueOf(cursor.getCount()));
            for(int i = 1; i <= cursor.getCount(); i++) {
                foundImage = false;
                byte[] imageReceive = cursor.getBlob(1);

                imageRDBitmap = BitmapFactory.decodeByteArray(imageReceive, 0, imageReceive.length);
                Mat imageConverted = new Mat(imageRDBitmap.getHeight(), imageRDBitmap.getWidth(), CvType.CV_8UC4);
                Utils.bitmapToMat(imageRDBitmap, imageConverted);

                initializeFeatures(imageConverted);
                int matchedPoints = recognizeFeature(ImageFrame);
                //Log.e("Checking for matched", String.valueOf(matchedPoints));
                if (matchedPoints > 20){
                    columnID = cursor.getInt(0);
                    foundImage = true;
                    break;
                }else{
                    cursor.moveToNext();
                }


            }
            if(cursor != null && !cursor.isClosed()){
                cursor.close();
                Log.e("RECEIVED FROM DATABASE", "is empty");
            }
            return null;
        }

The above piece of code is to store and retrieve the images. Also in the Android manifest, I have given permission to READ and WRITE. Kindly help to find the solution for this problem.

Thank you.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115

1 Answers1

0

The main line in the error log we need to understand is:

Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

So the Cursor is opened here:

Cursor cursor = mDatabase.rawQuery("Select * FROM imagetable", null);

Looks like it is not getting anything back from that query. I would check your database on your devices to make sure that there is a row in the table.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
trigster
  • 87
  • 9
  • `Log.e("Number of rows", String.valueOf(cursor.getCount()));` This shows the number of rows in my database. In the logcat, this commands returns the positive values, i.e., the database rows are created. This command works perfectly on both emulators and my device. However, even though above command returns the positive values, I can not find ".db" created in my device. – Vishnu Prasad P Jun 12 '18 at 16:30