I’m new to the Android framework and I can’t get past first base with SQLite.
I’m trying to build a very simple application that has a EditText search box, which when a key is pressed performs a Like %word% search on a SQLite database for for the text entered in the EditText box, and displays the results in a ListView.
N.B. the below code included debugging and commented code, sorry I haven’t got round to cleaning it up yet.
The Activate is
public class sustainable_fish extends Activity {
private String keycodeToAscii(int arg2){
String retvar = "";
switch(arg2){
case KeyEvent.KEYCODE_A: retvar = "a";break;
case KeyEvent.KEYCODE_B: retvar = "b";break;
snipped, but you get the idea.
case KeyEvent.KEYCODE_RIGHT_BRACKET: retvar = ")";break;
default: retvar = ""; break;
};
return retvar;
}
Context that = getApplicationContext();
fishDB dh = new fishDB(getApplicationContext());
private OnKeyListener search = new OnKeyListener() {
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
@SuppressWarnings("unused")
Cursor cur = null;
String searchData;
EditText myEditText = (EditText) findViewById(R.id.fish_search);
CharSequence edit_text_value = myEditText.getText();
searchData = edit_text_value.toString();
searchData = searchData + keycodeToAscii(arg2.getKeyCode() );
Log.d("onKey", "searchData = "+searchData);
/*
Commented out because as the database doesn't work, so theirs no point just yet searching.
cur = fish.search(searchData);
if (cur != null)
{
String[] displayFields = new String[] {cur.getString(2),
cur.getString(1)};
int[] displayViews = new int[] { R.id.fish_rank,
R.id.fish_name};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(that,
R.layout.text_list, cur,
displayFields, displayViews);
ListView myList=(ListView)findViewById(android.R.id.list);
myList.setAdapter(adapter);
}
*/
return false;
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
EditText searchBar = (EditText) findViewById(R.id.fish_search);
searchBar.setOnKeyListener(search);
}
}
The SQLite database is handled by fishDB
public class fishDB {
public static final String DATABASE_NAME = "fish.db3";
public static final int DATABASE_VERSION = 1;
private SQLiteDatabase database;
private Context myContext;
private static boolean booFirstrun = false;
fishDB(Context inContext){
myContext = inContext;
OpenHelper helper = new OpenHelper(myContext);
Log.w("fishDB", "Called OpenHelper");
// Here be the problem...
database = helper.getWritableDatabase();
}
public boolean firstRun(){
return booFirstrun;
}
private static class OpenHelper extends SQLiteOpenHelper {
private static final String CREATE_TABLE_FEEDS = "create table feeds (feed_id integer primary key autoincrement, "
+ "title text not null, url text not null);";
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.w("OpenHelper", "Called superconstructor");
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
Log.w("OpenHelper", "in onCreate");
booFirstrun = true;
Log.w("OpenHelper", "set booFirstrun");
db.beginTransaction();
Log.w("OpenHelper", "db.beginTransaction");
try {
// Create tables and test data
db.execSQL(CREATE_TABLE_FEEDS);
Log.w("OpenHelper", "execSQL");
db.setTransactionSuccessful();
Log.w("OpenHelper", "setTransactionSuccessful");
} catch (SQLException e) {
Log.e("Error creating tables and debug data", e.toString());
throw e;
} finally {
db.endTransaction();
}
} catch (Exception e) {
Log.e("OpenHelper", e.toString() );
} finally {
Log.w("OpenHelper", "out of onCreate");
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("OpenHelper", "Upgrading database, this will drop tables and recreate.");
onCreate(db);
}
}
}
Now every time “database = helper.getWritableDatabase();” is called the app crashes with a NullPointerException. I’ve managed to trace the error to the onCreate method of OpenHelper and the “db.beginTransaction();” line.
What am I missing?
Actually you do not need to start transaction at onCreate method of the helper. Try removing everything from the method except
db.execSQL(CREATE_TABLE_FEEDS);Update: I was able to repeat the problem.
Move fishDb field initialization to the
onCreate()method of activity after that error disappears. It looks like it is not good idea to start db initialization before the onCreate is invoked.So instead of
do