2011-11-13 13 views
2

android developmentに関連して、私は単にアクティビティが初めて起動されたとき(環境設定を使用して)SQLデータベースを作成しようとしています。アクティビティが2回目に起動されると、データベースからデータを取得してログメッセージを出力する必要があります。最初の起動時にSQLデータベースを作成し、次の起動時にデータベースデータを取得します

Iveは、データベースがここで作成されたと仮定して最初にアクティビティを起動しましたが、2回目にIllegalStateExceptionエラーが発生しました:行0から列-1へのフィールドスロットの取得に失敗しました。ここでどこが間違っていたのかは分かりません。誰か確認してもらえますか?おかげ

メインクラス

public class MainMenu extends Activity implements OnClickListener{ 
private ModulesDbAdapter mpDbHelper; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    //create database here 
    SharedPreferences initialPref = getSharedPreferences("INITIAL", 0); 
    boolean firsttimer = initialPref.getBoolean("INITIAL", false); 

    if (!firsttimer){ 
     //create database here 
     mpDbHelper = new ModulesDbAdapter(this); 
     mpDbHelper.open(); 

     long id1 = mpDbHelper.createReminder("Hello1", "Test 1", "Date1"); 
     long id2 = mpDbHelper.createReminder("Hello2", "Test 2", "Date2"); 
     long id3 = mpDbHelper.createReminder("Hello3", "Test 3", "Date3"); 

     /*Cursor c = mpDbHelper.fetchModules((String)"CS118"); 
     Log.d("TESTING",c.getString(c.getColumnIndex("KEY_MOD_NAME")));*/ 

     //get boolean preference to true 
     SharedPreferences.Editor editorPref = initialPref.edit(); 
     editorPref.putBoolean("INITIAL", true); 
     editorPref.commit(); 
    }else { 
     fetchData(); 
    } 
} 

private void fetchData(){ 
    mpDbHelper = new ModulesDbAdapter(this); 
    mpDbHelper.open(); 
    long input = 2; 

    Cursor c = mpDbHelper.fetchReminder(input); 
    startManagingCursor(c); 
    Log.d("TESTING",c.getString(c.getColumnIndex("KEY_BODY"))); 
} 

/*@Override 
protected void onPause() { 
    super.onPause(); 
    mpDbHelper.close(); 
} 

@Override 
protected void onStop() { 
    super.onPause(); 
    mpDbHelper.close(); 
}*/ 

} 
} 

アダプタクラス

public class ModulesDbAdapter { 
private static final String DATABASE_NAME = "data"; 
private static final String DATABASE_TABLE = "reminders"; 
private static final int DATABASE_VERSION = 1; 

public static final String KEY_TITLE = "title"; 
public static final String KEY_BODY = "body"; 
public static final String KEY_DATE_TIME = "reminder_date_time"; 
public static final String KEY_ROWID = "_id"; 

private DatabaseHelper mDbHelper; 
private SQLiteDatabase mDb; 

//defines the create script for the database 
private static final String DATABASE_CREATE = 
     "create table " + DATABASE_TABLE + " (" 
     + KEY_ROWID + " integer primary key autoincrement, " 
     + KEY_TITLE + " text not null, " 
     + KEY_BODY + " text not null, " 
     + KEY_DATE_TIME + " text not null);"; 

//Context object that will be associated with the SQLite database object 
private final Context mCtx; 

//The Context object is set via the constructor of the class 
public ModulesDbAdapter(Context ctx) { 
    this.mCtx = ctx; 
} 

//helps with the creation and version management of the SQLite database. 
private static class DatabaseHelper extends SQLiteOpenHelper { 

    //call made to the base SQLiteOpenHelper constructor. This call creates, opens, and/or manages a database 
    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DATABASE_CREATE); 
    } 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion,int newVersion) { 
     // Not used, but you could upgrade the database with ALTER 
     // Scripts 
    } 
} 

//now create the database by calling the getReadableDatabase() 
public ModulesDbAdapter open() throws android.database.SQLException { 
    mDbHelper = new DatabaseHelper(mCtx); 
    mDb = mDbHelper.getWritableDatabase(); 
    return this; 
} 

//close the database 
public void close() { 
    mDbHelper.close(); 
} 

public long createReminder(String title, String body, String 
    reminderDateTime) { 
    ContentValues initialValues = new ContentValues(); 
    initialValues.put(KEY_TITLE, title); 
    initialValues.put(KEY_BODY, body); 
    initialValues.put(KEY_DATE_TIME, reminderDateTime); 

    //insert row into database 
    return mDb.insert(DATABASE_TABLE, null, initialValues); 
} 



public boolean deleteReminder(long rowId) { 
    return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; 
} 

//utilizes the query() method on the SQLite database to find all the reminders in the system 
public Cursor fetchAllReminders() { 
    return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE, 
    KEY_BODY, KEY_DATE_TIME}, null, null, null, null, null); 
} 

public Cursor fetchReminder(long rowId) throws SQLException { 
    Cursor mCursor = 
    mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, 
    KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, KEY_ROWID + "=" + 
    rowId, null, null, null, null, null); 



    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 
} 

public boolean updateReminder(long rowId, String title, String body, String reminderDateTime) { 
    ContentValues args = new ContentValues(); 
    args.put(KEY_TITLE, title); 
    args.put(KEY_BODY, body); 
    args.put(KEY_DATE_TIME, reminderDateTime); 
    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; 
} 
     // The SQLiteOpenHelper class was omitted for brevity 
     // That code goes here. 

}

答えて

1

エラーは単純です。 KEY_BODYをDbAdapterクラスの静的文字列定数値として定義しましたが、アクセスコードに文字列リテラル "KEY_BODY"を使用しました。

Log.d("TESTING",c.getString(c.getColumnIndex("KEY_BODY"))); 

は、あなたのデータベースが作成された場合、明示的にチェックする必要はありません

Log.d("TESTING",c.getString(c.getColumnIndex(ModulesDbAdapter.KEY_BODY))); 
+0

私はいくつかのコメントを追加したいと思います。私は 'firsttimer'のものを全て取り出して、dbを開いて行を数えます。 0の場合は、initを挿入します。また、最初のタイマーは混乱しています。なぜなら最初に実行すると、その論理は正しいと言えますが、誤っているからです。 –

+0

オハイオ州の親愛なる、なぜ私はそれを見なかった!ありがとう、ありがとうございました。 firsttimerについては、最初の実行ではfalseですが、データベースの作成後はtrueになります。今のところ真実なので、データベースをもう一度作成する必要はありません。 –

+0

変数についての意味は、名前が意味をなさないということです。最初の実行時に 'firsttimer'はfalseですが、その名前はそれが真実であることを暗示します。コードはそのままで動作しますが、私はその名前を変更して、あなた自身を混乱させることはありません。 –

0

は、私はあなたの問題は、あなたのログの行であると考えています。文字列をリテラルに変更します。

Log.d("TESTING",c.getString(c.getColumnIndex(KEY_BODY))); 
1

でなければなりません。 onUpgrade(SQLiteDatabase、int、int)onCreate(SQLiteDatabase)を実装しているSQLiteOpenHelperのサブクラスを作成すると、既にデータベースが作成されていれば作成されていないことを「認識」します。

そうでなければ、あなたのエラーがラインに発生している:あなたは、列のインデックスとして文字列「KEY_BODY」ではなく、あなたの静的な文字列変数KEY_BODYの値を使用しているので、

Log.d("TESTING",c.getString(c.getColumnIndex("KEY_BODY"))); 

関連する問題