oncreate not called after creating database ! - android

Am creating a new database using helper, but as per the document on create should be called once the data base is created, but its not called properly. could any plz help me to resolve this asap. Plz see the code below.
1) Is there any way to create database instead of using helper if so plz advise me !
2) What are the callbacks will be called in the database creation and also in kill of a database ?
OpenHelper(Context context)
{
super(context, "examplee.db", null, 1 );
SQLiteDatabase sqlite = null;
Log.w(TAG, "Openhelp database, ");
sqlite = context.openOrCreateDatabase("examplee.db", Context.MODE_PRIVATE, null );
Log.e ( TAG,"SQ lite database object "+sqlite );
}
public void onOpen(SQLiteDatabase db)
{
Log.e ( TAG,"On open called ");
}
#Override
public void onCreate(SQLiteDatabase db)
{
Log.w(TAG, " On create ");
//db.execSQL(sql);
//db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database, this will drop tables and recreate.");
//db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
//onCreate(db);
}
}
Thanks in advance,

Here's a very detailed description on how to delete a database file from your emulator (debugging on an actual android phone is very similar).
Run your emulator. If you're having problems with that, then you can ignore the rest of this help message!
Pull up a command-line interface, according to your operating system.
Execute the command: 'adb shell' (omit the quotes, of course). This will take you into the Android Debug Bridge; your prompt will change to something like a simple pound sign. Regardless of your original operating system, you are now in a simplified unix OS.
You are now in your emulator. Type the command 'ls -l' to verify that you're in the root directory (you'll see something that looks very much like a unix root directory system).
Change directories to where your database file is stored. Suppose that the program that your ran is in the package com.sillynames.myprogram5, and the database file is called 'myblackbook.db'. You will find the file at the directory:
/data/data/com.sillynames.myprogram5/databases/myblackbook.db
Once you're at that directory, simply delete the database via 'rm myblackbook.db'.
Hope this helps!
-scott

The SQLiteOpenHelper javadoc says that onCreate is "Called when the database is created for the first time. This is where the creation of tables and the initial population of the tables should happen.". It is not called everytime the application comes up. In your case Probably the db is already created.
To verify if the db exists login to the shell with adb and go to /data/data/<your application package name>/databases and see if the employees.db file exists there.
In the onCreate method typically you will create your tables and load any initial data. This is executed when the app is launched for the first time after installation.

Is there any way to create database instead of using helper if so plz advise me !
Yes you can create your databse manually on your system using the the tool SQLite Manager or other and bundle that sqlite db file in your assets folder of your project. And when your application run then you need to copy that database file to the path /data/data/your_app_package_name/databases/
Refer this : Using your own SQLite database in Android applications
What are the callbacks will be called in the database creation and also in kill of a database ?
When your database is created fist time the onCreate() method is called. And there is no way to kill/drop a database instead you can delete that db file.

Make sure you await to get the database reference. Check if you have the database reference that was my issue. Had declared Database _db on top of class but in my functions it was null
final Database db = await initDb();
print("insert to db $db");
initDB
Future<Database> initDb() async {
print("called db init");
try {
final dbFolder = await getDatabasesPath();
if (!await Directory(dbFolder).exists()) {
print("db path does not exist");
await Directory(dbFolder).create(recursive: true).then((value) {
print("db directory $value");
});
}
final dbPath = join(dbFolder, _kBdFileName);
print("db path $dbPath");
// open db
_db = await openDatabase(
dbPath,
version: 1,
onCreate: (db, version) async {
print("Call on create");
await _initDBtables(db).then((value) {
print("on created ");
});
},
);
print("Db initialized $_db");
// success init db
return _db;
} on DatabaseException catch (e) {
print(e);
return _db;
}
}

Related

Is it possible to use SQLiteOpenHelper to create DB in cache dir?

I would like to create a database in cache so it could be wiped out when user clicks Clear cache button.
In SQLiteOpenHelper constructor there is only argument to pass a name of database, not a directory (default is dadabases).
Is there any option to delete such DB when user wants to clear cache?
Here is an example of creating a database in your cache directory:
public class CachedDatabase extends SQLiteOpenHelper {
public CachedDatabase(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, new File(context.getCacheDir(), name).getAbsolutePath(), factory, version);
}
#Override public void onCreate(SQLiteDatabase db) {
// just for testing
db.execSQL("CREATE TABLE example (id INTEGER PRIMARY KEY AUTOINCREMENT, foo, bar, baz, qux)");
}
#Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
All you need to do is pass the absolute path as the name parameter in the constructor.
Tested just to make sure it was created in /data/data/[package_name]/cache:
CachedDatabase cachedDatabase = new CachedDatabase(this, "TEST", null, 1);
SQLiteDatabase database = cachedDatabase.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("foo", "foo");
values.put("bar", "bar");
values.put("baz", 123);
values.put("qux", true);
database.insert("example", null, values);
Checking for the database:
$ adb shell
$ run-as [YOUR_PACKAGE_NAME]
$ ls cache
TEST
TEST-journal
You can create and open a database in a specific location, but you need to use SQLiteDatabase class (choose one of the openOrCreateDatabase methods): as you mentioned you can't create a database in a different path using the provided SQLiteOpenHelper.
You can also modify the code of the SQLiteOpenHelper to match your needs. Take the source code from the link, copy in a new class of your project and modify the getDatabaseLocked method.
You can also take inspiration from SQLiteAssetHelper.
If you are looking to clear the data in tabledb.execSQL("delete * from "+ TABLE_NAME);
you can also delete the tables db.delete("TABLE_NAME", null, null);

How do I update a database I am testing with a new app?

I am building an Android app that includes a built in database, and I am regularly testing it on my Samsung Galaxy S3 device.
I am having an issue now however, since I noticed that the SQLite database on the app is not updating even after I make changes to it on my computer using SQLiteBrowser.
I have verified that I am indeed writing the changes to the database and then rerunning the app from scratch on the device, but still the query results when performed by the app are unchanged, despite the changed data.
I've tried updating the version of the database, but this gives me all sorts of errors because it wants me to write an update script which I don't think is necessary for what I need to do.
Does anyone know how to refresh the data in the database on the device?
The easiest way to fix this is to go into Application Manager, select your app and then tap "Clear Cache". This will delete all the original databases that the app created. Android devices maintain this cache to persist databases even after the original app was uninstalled (for a few reasons and when they are deleted depends on the manufacturer's firmware). It is because of this, that even though you see that you are creating your new database, android is still querying the old ones.
You can then do a fresh install of your app and this should fix the problem. Outside of this, your only option is to write an upgrade script within the onUpgrade() method which does the upgrade.
You might not be writing to the database that is on the device, but in the folder on your computer. You can try having the app itself do some test updates to the database so that you know it is updating the SQLite Database on the device:
public class SQLHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "name goes here";
private static final String[] KEYS = {"column","names","go","here"};
private static final String DICTIONARY_TABLE_NAME = "tablename";
private static final String DICTIONARY_TABLE_CREATE =
"CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
KEY[0] + " TEXT, " +
KEY[1] + " TEXT, " . . .;
public SQLHelper(Context context) {
super(context, DATABASE_NAME , null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// creates table if does not exist
db.execSQL(DICTIONARY_TABLE_CREATE);
// . . . update database with test info here...
db.execSQL("INSERT INTO . . .");
db.execSQL("UPDATE . . .");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
You can use ADB to start a shell and use sqlite to directly act on the database http://developer.android.com/tools/help/sqlite3.html
Once you started sqlite3 just execute regular SQL commands

Cant find database when app starts

Im trying to do a simple example using my own SQLite database, android and greenDAO generator to generate classes for my android app.
My database file is defined this way:
1) Create a database called "OneTableDB" (without extension, SQLite 3) with the following structure:
Entity: Professor
professorID: primarykey
name: text
age: int
Entity: android_metadata
locale: text
Then i populated android_metadata with the value 'en_US', and the entity with few rows.
2) placed on my Android app structure inside: proj_root/databases/
Full path to database file: proj_root/databases/OneTableDB
3)i have a method to check whether database exists or not (in my case, it has to exist, since i placed inside databases folder)
private boolean databaseExists() {
SQLiteDatabase sqliteDatabase = null;
try {
String databasePath = DB_PATH + DB_NAME;
File f = new File(DB_PATH + DB_NAME);
f.exists();
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (sqliteDatabase != null) {
sqliteDatabase.close();
}
return sqliteDatabase != null ? true : false;
}
//DB_PATH = /data/data/com.myapp.android_dao_tests/databases/
//DB_NAME = OneTableDB
debugging on f.exists(), it returns false value and then breaks on
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READONLY);
During the debugging i used adb shell to check if the path was right, and in fact i can navigate to /data/data/com.myapp.android_dao_tests/ and there is no databases folder!
Any idea how can i solve this problem?
Thanks in advance?
The DB "template" is saved in the assets/ folder, in order for it to be bundled in the apk. The code then copies the DB from assets/ to databases/ to make it accessible as a regular SQLite DB.
After further investigation, it seems like Android refuses to acknowledge the new DB as its own. Apparently, the built-in DB mechanism wasn't meant to be used this way.
The correct way to approach it is by keeping the data in textual format in assets/ so that if the app starts and finds there's no DB, it will create the schema itself, and populate it with the data in the text files from the assets/ folder.

Android not paying attention to file changes?

I'm running into a very frustrating bug.
I have a java class that reads in data from a file, and enters it into the database.
package edu.uci.ics.android;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DbAdapter extends SQLiteOpenHelper{
private static final String DATABASE_NAME = "mydb";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "fruits";
private static final String FRUIT_ID = "_id";
private static final String FRUIT_NAME = "name";
private static final String FILE_NAME = "fruits.txt";
private static final String CREATE_TABLE = "CREATE TABLE "+ TABLE_NAME + "("+FRUIT_ID+" integer primary key autoincrement, "+FRUIT_NAME+" text not null);";
private SQLiteDatabase mDb;
private Context mContext;
public DbAdapter(Context ctx){
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
mContext = ctx;
this.mDb = getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
// populate database
try {
BufferedReader in = new BufferedReader(new InputStreamReader(mContext.getAssets().open(FILE_NAME)));
String line;
while((line=in.readLine())!=null) {
ContentValues values = new ContentValues();
values.put(FRUIT_NAME, line);
db.insert(TABLE_NAME, null, values);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public Cursor fetchAll() {
return mDb.query(TABLE_NAME, new String[] {FRUIT_NAME}, null, null, null, null, null);
}
}
EDIT:
To be more clear, this is what fails:
When I change the database name variable, the table name variable, the program force closes, indicating that something went wrong. Why can't I change the name of the table I create?
When I make changes in the fruits.txt file, I don't see anything reflecting those changes at run-time. Why does this happen?
SQLiteOpenHelper.onCreate() will only get called automatically if the database does not exist, which will only happen once. After that, the database file exists on the device's internal storage so it is simply going to load up the version it has.
If you want to create a new database when the external file is changed, you need to either delete the current database file (manual process) or also change the current database version the helper is created with. When Android sees that the version SQLiteOpenHelper is created with varies from the current file in internal storage, it will call onUpgrade() to allow the existing database to be modified to match the new "version".
EDIT:
To clarify, when you create a database, a db file is created (and persisted) on the device's internal storage, separate from your application's assets. When you re-run your application, persisted data storage does not clear out (or else it wouldn't be "persisted" anymore) so that database file from the last run of your application still exists...with all the settings from when it was created.
When you make changes to the variables in this class, it doesn't somehow magically modify the database file that already exists on the device, so now you are looking for tables and databases that don't exist (probably where your crashes are coming from).
If you simply need to clear out the database so it will reflect changes you've made during development, just clear the database manually on the device by going into Settings -> Manage Applications -> {Application Name} -> Clear Data. This deletes persisted files so they can be re-created by your application the next time you launch it.
If, however, you need this to somehow be a feature where your application automatically recognizes changes you've made to a file in /assets and modifies or re-creates the database as a result, then look at my previous suggestions about using the upgrade mechanism built into SQLiteOpenHelper
HTH
When you change the database name or table name in your code, they no longer reflect the names in the database on the device, so you get a force close. During development, the easy thing is to just uninstall your application and then reinstall whenever you make incompatible changes like that. When changing your database schema from one released version to another, you need to increase the database version number and do the right thing in onUpgrade().
For example, right now, you have
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
So when you change the table name in code from, say "fruits" to "veggies", onUpgrade() gets run, but table veggies doesn't exist, so it isn't dropped, and then you call onCreate(db) whith a conflicting shchema on top of the existing database. So you need to check oldVeresion and newVersion and do something more like
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion == 2 && oldVersion == 1) {
db.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME_V1);
db.execSQL("CREATE TABLE "+ TABLE_NAME ...);
}
}
If you're trying to change fruits.txt on the device, it won't work. That's how Android is designed: your assets never change, they're a read-only part of your APK. You need to write the fruit.txt file to the SD card if you want it to be able to change it.

Best practices for creating a SQLite database on Android

I have read through a lot of the posts on copying the database file over from the assets or raw folders to the /data/data/APP/databases folder, but that would leave two copies of the DB on the device taking up valuable space. I am thinking of building a solution with a slightly smaller footprint and allowing for more flexible schema management by storing the database SQL creation text file in the raw folder and using the standard on_create / on_update process in the DBhelper class. However I am a little confused because the examples that copy the database over bypass the on_create and on_update methods.
Is this the recommended way if you are not building the db from strings in the code?
My solution would simulate the running scripts from code method by having the scripts all in one file. The reason I am looking at building the db this way is that my DB will have close to 100 tables when the application is complete, so I need the schema to be manageable.
Any guidance is welcome as I am still learning the best practices and patterns for Android.
Here is an example of my code:
public class DatabaseHelper extends SQLiteOpenHelper {
private final String DATABASE_NAME = "mydb";
private final int DATABASE_VERSION = 1;
private final Context myCtx;
private String DATABASE_CREATE_SCRIPT = null;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
DATABASE_CREATE_SCRIPT = getLoadFile();
// Create all tables and populate the lookup tables
db.execSQL(DATABASE_CREATE_SCRIPT);
db.execSQL(VIEW_CREATE_V_PERSON);
}
private String getLoadFile(){
InputStream inputStream = myCtx.getResources().openRawResource(resIdofmyfile);
InputStreamReader inputreader = new InputStreamReader(inputStream);
BufferedReader buffreader = new BufferedReader(inputreader);
String line;
StringBuilder text = new StringBuilder();
try {
while (( line = buffreader.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch (IOException e) {
// We have an error to look up
return null;
}
return text.toString();
}
/**
* onUpgrade will check the version of the database and update the database
* if a newer version is available.
*/
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Will set conditional upgrade checks
//Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which may destroy all old data");
db.execSQL("DROP TABLE IF EXISTS CONTEXT_LOAD");
db.execSQL("DROP TABLE IF EXISTS ISSUES");
db.execSQL("DROP TABLE IF EXISTS GOALS");
db.execSQL("DROP TABLE IF EXISTS PERSON");
db.execSQL("DROP VIEW IF EXISTS V_PERSON");
onCreate(db);
}
}
I guess it looks like a good practice. It's not very bad even if you create your database with code completely. Check out google's app for IO schedules it has a fairly big database creation part. It may lead you a way.
Here is the project home page, here is the database part
I use this application as a reference all the time it's like a work of art =)
Edit: Google updated the app so the old database link doesn't work.
I'm not really sure what your question is.
If you are asking if it's OK to create your DB from scratch using a text file containing a load of SQL CREATE statements then the answer is "yes".
Not only that but it's more flexible than distributing a pre-built DB within your APK as you could even download the 'schema' file or files from a network location. This allows you to update the schema dynamically at a central point.

Categories

Resources