Android sqlite creating database error - java

i am newbie with android sqlite database. now i just try to create my custom database manager and i got the error at oncreate() function. I already spent 3 days to figure it out but unfortunately i am still stuck in it. Any brilliant idea would be appreciate.
public class DBManager extends SQLiteOpenHelper {
private SQLiteDatabase db;
private static Context myContext;
public static final String DB_NAME = "goldenland.db";
public static final String TB_CAT = "tbl_categories";
public static final String TB_ARTICLE = "tbl_articles";
public static final String TB_SUBCAT = "tbl_subcategories";
public static final String TB_SCHEDULE = "tbl_schedule";
public static final String TB_CONTENT = "tbl_contents";
public static final String TB_CITY = "tbl_cities";
public static final String name = "name";
public static String DB_PATH = "/data/data/com.gokiri.goldenland/databases/";
public DBManager(Context context) {
super(context, DB_NAME, null, 1);
DBManager.myContext = context;
}
public void createDataBase() throws IOException {
boolean dbExit = checkDataBase();
if (dbExit) {
System.out.println("Testing");
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDb = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLException e) {
}
if (checkDb != null) {
checkDb.close();
}
return checkDb != null ? true : false;
}
public void copyDataBase() throws IOException {
InputStream myInput = myContext.getAssets().open("goldenland_2.sqlite");
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDatabase() throws SQLiteException {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}

A few things might be wrong. Does your database really exist in res/assets? Are you writing to the correct directory? Stepping through with the debugger would go a long way toward diagnosing the problem.
You might get a sanity check by having copyDatabase take a String argument, which would be this.getReadableDatabase().getPath(). You might even try writing that out to the log to see if you're writing to the correct database directory.

Few things to check.
1. in method checkDataBase open the database in OPEN_READONLY mode.
2. this is very important check that the size of the database is less than 1 mb. Android version previous to 3.0 don't allow file copy of more than 1 mb.
Update:
You will need to split the database file into parts of 1Mb each, copy all parts one by one and join them together again. refer to following link

unless you didnt put up all your code, it seems to me that you are missing somethings. I used this tutorial and had no problems
http://www.devx.com/wireless/Article/40842/1954
hope that helps

Related

SQLite helper classes for each table issues

I am using an SQLite db in my android application and I setup helper classes for each table in the db. There are many tables and these classes just handle all the crud methods for each table. I followed example #6 here
I'm having an issue when there are multiple instances of the helper classes instantiated. The database is only available when one helper class is instantiated at a time.
public class ProjectsHelper {
SQLiteDatabase db;
DataBaseHelper dbHelper;
private String TABLE_NAME = "Projects";
public ProjectsHelper(Context context){
if(dbHelper == null){
dbHelper = new DataBaseHelper(context);
}
}
public void open() throws SQLException {
try {
if(!isOpen()){
db = dbHelper.getWritableDatabase();
}
} catch (Exception e){
e.printStackTrace();
}
}
private boolean isOpen(){
return db != null && db.isOpen();
}
public void close() {
if(isOpen()){
dbHelper.close();
db.close();
dbHelper = null;
db = null;
}
}
public long insert(Project obj){
ContentValues values = new ContentValues();
values.put("ProjName", obj.getProjName().trim());
if(!Utilities.empty(obj.getProjDesc())){
values.put("ProjDesc", obj.getProjDesc().trim());
}
if(!Utilities.empty(obj.getProjNumber())){
values.put("ProjNum", obj.getProjNumber().trim());
}
values.put("ServerID", obj.getServerID());
values.put("GUID", obj.getGUID());
values.put("ModDate", obj.getModDate());
long id = db.insert(TABLE_NAME, null, values);
return id;
}
}
public class DataBaseHelper extends SQLiteOpenHelper {
//The Android's default system path of your application database.
public static String DB_PATH = "/data/data/com.siscoders.arscompnentinspector/databases/";
public static String DB_NAME = "ARSInspection.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* #param context
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
try {
createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
//openDataBase();
}catch(SQLException sqle){
throw sqle;
}
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

How can I use my custom sqlite database with android app? [duplicate]

This question already has answers here:
Ship an application with a database
(15 answers)
Closed 7 years ago.
I have a static sqlite db. How could I include it into the app? Where should i put it in my project folder? How should I access it from DatabaseHandler?
Everything I found on the web was using sqlite only for creating a new db and storing user or temp data in it, but not using existing db with predefined data.
Official Google docs does not tell how to do that.
Handling this case is basically just doing a file copy.
The tricky part is
To create the database when needed only (otherwise just open it)
To implement the upgrade logic
I wrote a sample Helper class that demonstrate how to load a database from your assets.
public abstract class SQLiteAssetHelper extends SQLiteOpenHelper {
// ----------------------------------
// CONSTANTS
// ----------------------------------
private static final String DATABASE_DIR_NAME = "databases";
// ----------------------------------
// ATTRIBUTES
// ----------------------------------
private final Context mContext;
private final CursorFactory mFactory;
private SQLiteDatabase mDatabase;
private String mDatabaseName;
private String mDatabaseAssetPath;
private String mDatabaseDiskPath;
private boolean mIsProcessingDatabaseCreation; // Database creation may take some time
// ----------------------------------
// CONSTRUCTORS
// ----------------------------------
public SQLiteAssetHelper(Context context, String name, CursorFactory factory, String destinationPath, int version) {
super(context, name, factory, version);
mContext = context;
mFactory = factory;
mDatabaseName = name;
mDatabaseAssetPath = DATABASE_DIR_NAME + "/" + name;
if (destinationPath == null) {
mDatabaseDiskPath = context.getApplicationInfo().dataDir + "/" + DATABASE_DIR_NAME;
} else {
mDatabaseDiskPath = destinationPath;
}
}
// ----------------------------------
// OVERRIDEN METHODS
// ----------------------------------
#Override
public synchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
// the database is already open and writable
return mDatabase;
}
if (mIsProcessingDatabaseCreation) {
throw new IllegalStateException("getWritableDatabase is still processing");
}
SQLiteDatabase db = null;
boolean isDatabaseLoaded = false;
try {
mIsProcessingDatabaseCreation = true;
db = createOrOpenDatabase();
// you should probably check for database new version and process upgrade if necessary
onOpen(db);
isDatabaseLoaded = true;
return db;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
mIsProcessingDatabaseCreation = false;
if (isDatabaseLoaded) {
if (mDatabase != null) {
try {
mDatabase.close();
} catch (Exception e) {
e.printStackTrace();
}
}
mDatabase = db;
} else {
if (db != null) db.close();
}
}
}
#Override
public final void onCreate(SQLiteDatabase db) {
// getWritableDatabase() actually handles database creation so nothing to code here
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO implement your upgrade logic here
}
// ----------------------------------
// PRIVATE METHODS
// ----------------------------------
private void copyDatabaseFromAssets() throws IOException {
String dest = mDatabaseDiskPath + "/" + mDatabaseName;
String path = mDatabaseAssetPath;
InputStream is = mContext.getAssets().open(path);
File databaseDestinationDir = new File(mDatabaseDiskPath + "/");
if (!databaseDestinationDir.exists()) {
databaseDestinationDir.mkdir();
}
IOUtils.copy(is, new FileOutputStream(dest));
}
private SQLiteDatabase createOrOpenDatabase() throws IOException {
SQLiteDatabase db = null;
File file = new File (mDatabaseDiskPath + "/" + mDatabaseName);
if (file.exists()) {
db = openDatabase();
}
if (db != null) {
return db;
} else {
copyDatabaseFromAssets();
db = openDatabase();
return db;
}
}
private SQLiteDatabase openDatabase() {
try {
SQLiteDatabase db = SQLiteDatabase.openDatabase(
mDatabaseDiskPath + "/" + mDatabaseName, mFactory, SQLiteDatabase.OPEN_READWRITE);
return db;
} catch (SQLiteException e) {
e.printStackTrace();
return null;
}
}
// ----------------------------------
// NESTED CLASSES
// ----------------------------------
private static class IOUtils {
private static final int BUFFER_SIZE = 1024;
public static void copy(InputStream in, OutputStream outs) throws IOException {
int length;
byte[] buffer = new byte[BUFFER_SIZE];
while ((length = in.read(buffer)) > 0) {
outs.write(buffer, 0, length);
}
outs.flush();
outs.close();
in.close();
}
}; // IOUtils
}
Then you only have to create a class that extends from the one above like this :
public class MyDbHelper extends SQLiteAssetHelper {
// ----------------------------------
// CONSTANTS
// ----------------------------------
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_FILE_NAME = "test.db";
// ----------------------------------
// CONSTRUCTORS
// ----------------------------------
public MyDbHelper(Context context) {
super(context, DATABASE_FILE_NAME, null, context.getFilesDir().getAbsolutePath(), DATABASE_VERSION);
}
}
Each time you will call getWritableDatabase() from your MyDbHelper instance, it will do all the copy/open stuff for you and return the writable database.
As I said before, I did not implement the upgrade() method in this sample, you'll have to.
I also didn't implement getReadableDatabase() since I usually only use getWritableDatabase(). You may need to do it.
If you want to test it, just do the following:
Copy the code above
Create a folder in your assets called "databases" and insert your sqlite database file in it
In MyDatabaseHelper, change the value of the DATABASE_FILE_NAME constants with the name of the database in the asset folder
Don't forget to instantiate the MyDatabaseHelper and call for getWritableDatabse()
Hope this helped.

android onUpgrade moving some records from old db to new db

What I'm trying to achieve is that my application will ship with an existing sqlite database exported from my web panel with some records(news, products, categories etc.) and later on it will insert some records of its own into it(lets say it'll insert notifications it receives) and it will be copied to the databases folder, up to here there is no problem but my concern is when a user upgrades their application through market I want to replace the new database with the old one but keep those application generated records(notifications it has received) and insert them into the new one. Here's my code so far: (please enhance if necessary)
public class Helper_Db extends SQLiteOpenHelper{
public static final String DB_NAME = "Test.sqlite";
public static final int DB_VERSION = 3;
private static String DB_PATH = "";
private SQLiteDatabase _db;
private final Context _ctx;
public Helper_Db(Context context) {
super(context, null, null, 1);
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
_ctx = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
try
{
copyDatabase();
Log.e("DATABASE", "Database created");
}
catch(IOException io)
{
Log.e("DATABASE", io.toString());
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//take out the notifications from old db
//insert them into the new db
//delete the old db
//copy the new db
}
private void copyDatabase() throws IOException
{
InputStream input = _ctx.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream output = new FileOutputStream(outFileName);
byte [] buffer = new byte [1024];
int length;
while((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
}
public boolean openDatabase() throws SQLException
{
String path = DB_PATH + DB_NAME;
_db = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.CREATE_IF_NECESSARY);
return _db != null;
}
#Override
public void close()
{
if(_db != null)
{
_db.close();
}
super.close();
}
}
Thanks in advance.
I do something similar. I have default content in a database that I ship with the app that changes sometimes. However, I have a routine for synchronizing databases for syncing between users and with backups, and each time I upgrade the DB, I just take the included DB and sync it with the existing user's DB.
That may be too much for your needs, but this brings me to how I know whether data is user data or not which seems like is the real problem here. You need to determine what data is user data. Then all you need to do is copy that data.
So, my recommendation is to create an integer column in each database table called something like "IncludedContent" and set that to 1 on all data that you include in your shipped database and set the default value to 0 which is what all user content will have. Then all you have to so is attach the databases using the Attach command something like this:
db.execSQL("ATTACH DATABASE ? AS Old_DB", new String[]{fullPathToOldDB});
and then do an insert like this to copy only user content:
db.execSQL("INSERT INTO New_DB.TABLE SELECT * FROM Old_DB.TABLE WHERE IncludedContent = 0");

working with external data base in android programing with eclipse

i'm a beginner in java and android. now i want to work with external database (cancer.db).
i created "DataBaseHelper" class.
public class DataBaseHelper extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";
private static String DB_NAME = "myDBName";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* #param context
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.}
then i use codes below in "on create" method to create or open database:
private static String DB_PATH = "/data/data/info.myprogram/databases/";
private static String DB_NAME = "cancer.db";
DataBaseHelper myDbHelper = new DataBaseHelper();
myDbHelper = new DataBaseHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
i use these codes to get query. my table name is "shb":
SQLiteDatabase db;
Cursor cc= db.rawQuery("SELECT Name FROM shb WHERE _id=1",null);
cc.moveToFirst();
String sss=cc.getString(1);
now when i start debugging i get errors. what's the wrong code? whats my mistake? how should i get query?
and excuse me for my weak English, because it's not my mother tongue .
First create a sqlite database and create table inside it, put it in assets folder of your app.use that database by using following code. please make changes in code for your datbaseName, tableName, fieldsName and path of database etc. i have also write the code of getting list of data by passing paerticuler value.
public class MySQLiteHelper extends SQLiteOpenHelper {
public static final String TABLE_CARS = "Cars";
public static final String COL_ENAME = "ename";
public static final String COL_MODAL = "modal";
public static final String COL_ANAME = "aname";
public static final String COL_TYPES = "types";
private static final String TAG = "MSSS : DatabaseHelper";
// Your Database Name
private static final String DATABASE_NAME = "4saleCars.sqlite";
// Your Your Database Version
private static final int DATABASE_VERSION = 1;
private final Context myContext;
private SQLiteDatabase myDataBase;
// The Android's default system path of your application database. DB_PATH =
// "/data/data/YOUR_PACKAGE/databases/"
private String DB_PATH = "/data/data/net.forsalemall.android/databases/";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
try {
createDataBase();
} catch (Exception e) {
Log.e(TAG,
"DatabaseHelper_constuctor createDataBase :"
+ e.fillInStackTrace());
}
}
#Override
public void onCreate(SQLiteDatabase database) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// ***************************** My DB Handler Methods
// *****************************
/**
* Creates a empty database on the system and rewrites it with your own
* database.
**/
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
// Database already exist
openDataBase();
} else {
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
myDataBase = getWritableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error createDataBase().");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each
* time you open the application.
*
* #return true if it exists, false if it doesn't
**/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DATABASE_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/*
* public boolean isDataBaseExist() { File dbFile = new File(DB_PATH +
* DATABASE_NAME); return dbFile.exists(); }
*/
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transferring bytestream.
**/
private void copyDataBase() throws IOException {
try {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DATABASE_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DATABASE_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
} catch (IOException e) {
throw new Error("Error copyDataBase().");
}
}
public void openDataBase() throws SQLException, IOException {
try {
// Open the database
String myPath = DB_PATH + DATABASE_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
throw new Error("Error openDataBase().");
}
}
// ***************************** My DML Methods
// *****************************
public List<String> getModalList(String aname, Context context) {
List<String> list = new ArrayList<String>();
list.add(context.getResources().getString(R.string.all));
Cursor cursor;
String query;
query = "SELECT modal FROM Cars WHERE aname = '" + aname + "';";
try {
cursor = myDataBase.rawQuery(query, null);
if (cursor != null) {
while (cursor.moveToNext())
list.add(Utils.getDecodedString(cursor.getString(0)));
}
cursor.deactivate();
} catch (Exception e) {
Log.e(TAG, "getModalList Error : " + e.fillInStackTrace());
}
return list;
}
}
use this getModalList in your activity just like below
MySQLiteHelper dbHelper = new MySQLiteHelper(
AdvanceSearchActivity.this);
String aname = Utils.getEncodedString(catName);
car_modal = dbHelper.getModalList(aname,AdvanceSearchActivity.this);

How should my onUpgrade() method look like?

You can see my database helper class below. I use prepopulated sqlite database imported in assets folder. Whenever I add a table to my existing database, I get no such table error if my app is already installed on my phone. I guess my onUpgrade() method is now so good. It works, don't get me wrong, when I change some data to existing tables, I increase db version and it gets updated. But if I add a table I get error.
public class DataBaseHelper extends SQLiteOpenHelper
{
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
//destination path (location) of our database on device
private static String DB_PATH = "/data/data/rs.androidaplikacije.themostcompleteiqtest/databases/";
private static String DB_NAME ="pitanja.sqlite";// Database name
private static SQLiteDatabase mDataBase;
private final Context mContext;
private static final int DATABASE_VERSION = 3;
public DataBaseHelper(Context mojContext)
{
super(mojContext, DB_NAME, null, 3);// 1 it's Database Version
DB_PATH = mojContext.getApplicationInfo().dataDir + "/databases/";
this.mContext = mojContext;
}
public void createDataBase() throws IOException
{
//If database not exists copy it from the assets
this.getReadableDatabase();
this.close();
try
{
//Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
}
catch (IOException mIOException)
{
throw new Error("ErrorCopyingDataBase");
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
public boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/*Check that the database exists here: /data/data/your package/databases/Da Name
private boolean checkDataBase()
{
File dbFile = new File(DB_PATH + DB_NAME);
//Log.v("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
*/
//Copy the database from assets
private void copyDataBase() throws IOException
{
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer))>0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
//Open the database, so we can query it
public boolean openDataBase() throws SQLException
{
String mPath = DB_PATH + DB_NAME;
//Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
//mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public void close()
{
if(mDataBase != null)
mDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase arg0) {
}
#Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
try {
// delete existing?
// Copy the db from assests
copyDataBase();
Log.e(TAG, "database updated");
} catch (IOException mIOException) {
Log.e(TAG, mIOException.toString());
try {
throw mIOException;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
There's 2 ways to do onUpgrade, depending on your app.
1)Drop all your old tables, then run onCreate. THis basically wipes out all your old data and starts over. Its a good technique if you can regenerate the old data somehow, or just don't care about it.
2)Carefully maintain a diff of your schema between each released version, and write SQL statements to make the proper changes between them- add new tables, alter existing tables to add/remove columns, etc. This is time consuming and fragile, so use this only if you need to keep data between those versions.

Categories