I am trying to solve the following problem. I have an application which uses a pre-created database. I put this database in assets folder. Then i copy the database internaly.
I want to be able to check the version of my database so when there is a new version i delete the old database and copy the new one from assets folder. I store the database version as an shared preference data.
Runing the following code i got an error and the application stops running (has stopped unexpectendly).
Can you please help me and find where the problem is?
public class DatabaseConnector
{
// database name
private static final String DATABASE_NAME = "Recipes";
private SQLiteDatabase database; // database object
private DatabaseOpenHelper databaseOpenHelper; // database helper
String selection;
// public constructor for DatabaseConnector
public DatabaseConnector(Context context)
{
// create a new DatabaseOpenHelper
databaseOpenHelper =
new DatabaseOpenHelper(context, DATABASE_NAME, null, 1);
} // end DatabaseConnector constructor
// open the database connection
// attempts to establish a connection to the db
// and throws an exception if it fails
public void open() throws SQLException
{
// create or open a database for reading/writing
database = databaseOpenHelper.getWritableDatabase();
} // end method open
// close the database connection
public void close()
{
if (database != null)
database.close(); // close the database connection
} // end method close
// inserts a new esoda in the database
public void insertEsoda(String title, String category, String ingredients, String process,
String notes, String image, String time, String calories, String difficulty)
{
....
} // end method insertEsoda
// updates a esoda in the database
public void updateEsoda(long id, String title, String category, String ingredients,
String process, String notes, String image, String time, String calories, String difficulty)
{
....
} // end method updateEsoda
// updates favorites in the database
public Boolean updateFavorite(long id)
{
....
} // end method update favorites
// return a Cursor with all esoda information in the database
public Cursor getAllEsoda()
{
....
} // end method getAllEsoda
// return a Cursor with all esoda information in the database
public Cursor getRecipeCategory(int position)
{
....
} // end method getAllEsoda
// get a Cursor containing all information about the esoda specified
// by the given id
public Cursor getOneEsoda(long id)
{
....
} // end method getOneEsoda
// delete the contact specified by the given String name
public void deleteEsoda(long id)
{
....
} // end method deleteEsoda
private class DatabaseOpenHelper extends SQLiteOpenHelper {
public Context mContext;
private static final int DATABASE_VERSION = 1;
private static final String SP_KEY_DB_VER = "db_ver";
// public constructor
public DatabaseOpenHelper(Context context, String title,
CursorFactory factory, int version)
{
super(context, title, factory, version);
mContext=context;
initialize();
} // end DatabaseOpenHelper constructor
private void initialize() {
if (databaseExists()) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(mContext);
int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
if (DATABASE_VERSION != dbVersion) {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
if (!dbFile.delete()) {
Log.w("TAG", "Unable to update database");
}
}
}
if (!databaseExists()) {
createDatabase();
}
}
private boolean databaseExists() {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
return dbFile.exists();
}
private void createDatabase() {
String parentPath = mContext.getDatabasePath(DATABASE_NAME).getParent();
String path = mContext.getDatabasePath(DATABASE_NAME).getPath();
File file = new File(parentPath);
if (!file.exists()) {
if (!file.mkdir()) {
Log.w("TAG", "Unable to create database directory");
return;
}
}
InputStream is = null;
OutputStream os = null;
try {
is = mContext.getAssets().open(DATABASE_NAME);
os = new FileOutputStream(path);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.commit();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// creates the contacts table when the database is created
@Override
public void onCreate(SQLiteDatabase db)
{
// query to create a new table named contacts
String createQuery = "CREATE TABLE recipes" +
"(_id integer primary key autoincrement," +
"title TEXT, category TEXT, ingredients TEXT, process TEXT, notes TEXT, image TEXT, " +
"time TEXT, calories TEXT, difficulty TEXT);";
db.execSQL(createQuery); // execute the query
} // end method onCreate
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
} // end method onUpgrade
} // end class DatabaseOpenHelper
}
This is my LogCat text:
11-27 23:19:41.643: D/AndroidRuntime(297): Shutting down VM
11-27 23:19:41.643: W/dalvikvm(297): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
11-27 23:19:41.673: E/AndroidRuntime(297): FATAL EXCEPTION: main
11-27 23:19:41.673: E/AndroidRuntime(297): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{development.nk.cretanrecipes/development.nk.cretanrecipes.RecipesMainActivity}: java.lang.NullPointerException
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.os.Handler.dispatchMessage(Handler.java:99)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.os.Looper.loop(Looper.java:123)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-27 23:19:41.673: E/AndroidRuntime(297): at java.lang.reflect.Method.invokeNative(Native Method)
11-27 23:19:41.673: E/AndroidRuntime(297): at java.lang.reflect.Method.invoke(Method.java:521)
11-27 23:19:41.673: E/AndroidRuntime(297): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-27 23:19:41.673: E/AndroidRuntime(297): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-27 23:19:41.673: E/AndroidRuntime(297): at dalvik.system.NativeStart.main(Native Method)
11-27 23:19:41.673: E/AndroidRuntime(297): Caused by: java.lang.NullPointerException
11-27 23:19:41.673: E/AndroidRuntime(297): at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.widget.Toast.<init>(Toast.java:89)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.widget.Toast.makeText(Toast.java:231)
11-27 23:19:41.673: E/AndroidRuntime(297): at development.nk.cretanrecipes.DatabaseConnector$DatabaseOpenHelper.initialize(DatabaseConnector.java:191)
11-27 23:19:41.673: E/AndroidRuntime(297): at development.nk.cretanrecipes.DatabaseConnector$DatabaseOpenHelper.<init>(DatabaseConnector.java:186)
11-27 23:19:41.673: E/AndroidRuntime(297): at development.nk.cretanrecipes.DatabaseConnector.<init>(DatabaseConnector.java:35)
11-27 23:19:41.673: E/AndroidRuntime(297): at development.nk.cretanrecipes.RecipesMainActivity.<init>(RecipesMainActivity.java:32)
11-27 23:19:41.673: E/AndroidRuntime(297): at java.lang.Class.newInstanceImpl(Native Method)
11-27 23:19:41.673: E/AndroidRuntime(297): at java.lang.Class.newInstance(Class.java:1429)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
11-27 23:19:41.673: E/AndroidRuntime(297): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
11-27 23:19:41.673: E/AndroidRuntime(297): ... 11 more
The error in the stacktrace seems to be related to a toast, which is not appearing in the code you pasted.
However, this library sqllite asset helper seems to address the same exact problem you are trying to solve.
“An Android helper class to manage database creation and version management using an application’s raw asset files.”
Hope it helps