游标,SQLite和查询

时间:2014-09-21 11:08:44

标签: java android sqlite

我有一个sqlitedatabase我在我的应用程序中实现,并且在启动时我一直收到IllegalStateException。

09-21 22:48:26.749  15762-16277/nz.co.exium.panther E/AndroidRuntime﹕ FATAL EXCEPTION: SyncAdapterThread-2
java.lang.IllegalStateException: Couldn't read row 0, col 4 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:438)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at android.database.CursorWrapper.getString(CursorWrapper.java:114)
        at nz.co.exium.panther.sync.PantherSyncAdapter.getRegistrationId(PantherSyncAdapter.java:269)
        at nz.co.exium.panther.sync.PantherSyncAdapter.onPerformSync(PantherSyncAdapter.java:64)
        at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:254)

我认为这是由于查询返回一个相当空的表(自动增加的_ID除外)然后当我尝试从游标中获取一个String时引起的。

String registrationID = "";
    Uri uri = CustomerEntry.CONTENT_URI;
    Cursor cursor = mContext.getContentResolver().query(uri, CUSTOMER_PROJECTION, null, null, null);
    if (cursor.moveToFirst())   {

        registrationID = cursor.getString(INDEX_CUST_REGID);
    }

SQL create table call:

final String SQL_CREATE_CUSTOMER_TABLE = "CREATE TABLE " + CustomerEntry.TABLE_NAME + " (" +
            CustomerEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            CustomerEntry.COLUMN_CUST_NAME + " TEXT NOT NULL, " +
            CustomerEntry.COLUMN_CUST_EMAIL + " TEXT NOT NULL, " +
            CustomerEntry.COLUMN_CUST_QRHASH + " TEXT NOT NULL," +
            CustomerEntry.COLUMN_CUST_REGID + " TEXT NOT NULL)";

在这种情况下,INDEX_CUST_REGID是与String []投影中的位置相关的最终静态int,在这种情况下是第3个位置。这是有意义的,但是有一种方法或方法来查询SyncAdapter以查找特定列(如CUST_REGID)或方法来检查在尝试cursor.getString()之前是否返回了所请求的列?

这也可以解决我在知道EMAIL,NAME,QRHASH之前保存Reg ID的另一个问题。无法插入一列而其余列也没有值(NOT NULL),即使它是无用的数据并且会被覆盖。

尝试存储Reg ID的方法。

private void storeRegistrationID(Context context, String regID) {
    //DB insert regid
    ContentValues cValues = new ContentValues();
    cValues.put(CustomerEntry.COLUMN_CUST_NAME, "");
    cValues.put(CustomerEntry.COLUMN_CUST_EMAIL, "");
    cValues.put(CustomerEntry.COLUMN_CUST_QRHASH, "");
    cValues.put(CustomerEntry.COLUMN_CUST_REGID, regID);
    mContext.getContentResolver().insert(CustomerEntry.CONTENT_URI, cValues);
}

按要求投影:

 String[] CUSTOMER_PROJECTION = new String[]{
        CustomerEntry._ID,
        CustomerEntry.COLUMN_CUST_NAME,
        CustomerEntry.COLUMN_CUST_EMAIL,
        CustomerEntry.COLUMN_CUST_QRHASH,
        CustomerEntry.COLUMN_CUST_REGID
};

1 个答案:

答案 0 :(得分:1)

你确定这张桌子真的被创造了吗?从SQL_CREATE_CUSTOMER_TABLE文本字符串的末尾开始有一个分号 - 虽然我不确定是否必须运行sql来创建表。我建议在Eclipse模拟器上运行它,然后从DDMS的角度,在数据库的某个地方获取一个数据库的副本,你可以用Firefox的SQLite Manager插件打开它 - 这将显示数据库表。