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.
Related
I have database(say x.db) stored in asset folder(path = "\app\src\main\assets"). I am trying to change its name before it is loaded in runtime but for some reason, I am unable to do so. My goal is to rename the database per user. So if there is 3 user I want to have 3 new databases plus the initial database.
My code snipped when it runs for the first time,
try {
File oldFile = new File("\\app\\src\\main\\assets");
File[] listOfFiles = oldFile.listFiles();//this is always empty.
for (File listOfFile : listOfFiles) {
if (listOfFile.isFile() && listOfFile.getName().equals("x.db")) {
return listOfFile.renameTo(new File("y" + ".db"));
}
}
return false;
} catch (Exception e) {
return false;
}
My goal is to rename the database per user.
Then you do not need to rename the asset file, which you cannot as it's part of the APK and thus protected. What you do is copy the asset into the the location where the database is to be stored using the database name that you require per user.
Example
The following example creates 3 databases copying them from the single asset (mydb in this case). The core code is what is termed as the DatabaseHelper (a subclass of SQLiteOpenHelper). Typically this is written to be constructed from just the Context. In this case the user name is passed thus allowing seperate database per user. The database name being the user name suffixed by the asset name.
The database helper MultiUserDBHelper.java :-
public class MultiUserDBHelper extends SQLiteOpenHelper {
public static final String ASSET_NAME = "mydb";
public String DB_PATH;
Context mContext;
SQLiteDatabase mDataBase;
public MultiUserDBHelper(Context context, String User) {
super(context, User+ASSET_NAME, null, 1);
DB_PATH = context.getDatabasePath(User+ASSET_NAME).getPath();
this.mContext = context;
if (!checkDataBase()) {
copyDataBase();
}
mDataBase = this.getWritableDatabase(); //Forces open and therefore creation if db doesn exist.
}
public void copyDataBase() {
try {
InputStream myInput = mContext.getAssets().open(ASSET_NAME);
String outputFileName = DB_PATH;
OutputStream myOutput = new FileOutputStream(outputFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0)
myOutput.write(buffer, 0, length);
myOutput.flush();
myOutput.close();
myInput.close();
;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error copying database from asset");
}
}
public boolean checkDataBase() {
File dbfile = new File(DB_PATH);
if (dbfile.exists()) return true;
if (!(dbfile.getParentFile()).exists()) dbfile.getParentFile().mkdirs();
return false;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
An Activity that demonstrates use of the above for 3 users :-
public class MainActivity extends AppCompatActivity {
MultiUserDBHelper dbuser1, dbuser2, dbuser3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbuser1 = new MultiUserDBHelper(this,"User1");
dbuser2 = new MultiUserDBHelper(this,"User2");
dbuser3 = new MultiUserDBHelper(this,"User3");
}
}
Obviously you would introduce a methodlogy for selecting/switching users. The abve is intended only to demonstrate the copying/access to each individual database.
After running the above Device Explorer has :-
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 localize the database for the project in other languages (for example en, ru, fr and others)
I have an already ready database in English, but I want to make the application multilingual and able to work with other databases depending on the device locale.
I've already seen a lot of forums on this issue, but in each of them it says that you need to get the current locale. But I can not understand where these codes should be attributed. My code is completely listed below.
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
{
private static final String DATABASE_NAME = MuseumConfig.DATABASE_NAME;
private static final String DATABASE_PATH = "/data/data/" + CookbookApplication.getContext().getPackageName() + "/databases/";
private static final int DATABASE_VERSION = CookbookConfig.DATABASE_VERSION;
private static final String PREFS_KEY_DATABASE_VERSION = "database_version";
private Dao<CategoryModel, Long> mCategoryDao = null;
private Dao<AboutModel, Long> mRecipeDao = null;
private Dao<InformationModel, Long> mIngredientDao = null;
// singleton
private static DatabaseHelper instance;
public static synchronized DatabaseHelper getInstance()
{
if(instance==null) instance = new DatabaseHelper();
return instance;
}
private DatabaseHelper()
{
super(CookbookApplication.getContext(), DATABASE_PATH + DATABASE_NAME, null, DATABASE_VERSION);
if(!databaseExists() || DATABASE_VERSION>getVersion())
{
synchronized(this)
{
boolean success = copyPrepopulatedDatabase();
if(success)
{
setVersion(DATABASE_VERSION);
}
}
}
}
#Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource)
{
try
{
Logcat.d("DatabaseHelper.onCreate()");
//TableUtils.createTable(connectionSource, CategoryModel.class);
//TableUtils.createTable(connectionSource, RecipeModel.class);
//TableUtils.createTable(connectionSource, IngredientModel.class);
}
catch(android.database.SQLException e)
{
Logcat.e("DatabaseHelper.onCreate(): can't create database", e);
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion)
{
try
{
Logcat.d("DatabaseHelper.onUpgrade()");
}
catch(android.database.SQLException e)
{
Logcat.e("DatabaseHelper.onUpgrade(): can't upgrade database", e);
e.printStackTrace();
}
}
#Override
public void close()
{
super.close();
mCategoryDao = null;
mRecipeDao = null;
mIngredientDao = null;
}
public synchronized void clearDatabase()
{
try
{
Logcat.d("DatabaseHelper.clearDatabase()");
TableUtils.dropTable(getConnectionSource(), CategoryModel.class, true);
TableUtils.dropTable(getConnectionSource(), RecipeModel.class, true);
TableUtils.dropTable(getConnectionSource(), IngredientModel.class, true);
TableUtils.createTable(getConnectionSource(), CategoryModel.class);
TableUtils.createTable(getConnectionSource(), RecipeModel.class);
TableUtils.createTable(getConnectionSource(), IngredientModel.class);
}
catch(android.database.SQLException e)
{
Logcat.e("DatabaseHelper.clearDatabase(): can't clear database", e);
e.printStackTrace();
}
catch(java.sql.SQLException e)
{
Logcat.e("DatabaseHelper.clearDatabase(): can't clear database", e);
e.printStackTrace();
}
}
public synchronized Dao<CategoryModel, Long> getCategoryDao() throws java.sql.SQLException
{
if(mCategoryDao==null)
{
mCategoryDao = getDao(CategoryModel.class);
}
return mCategoryDao;
}
public synchronized Dao<RecipeModel, Long> getRecipeDao() throws java.sql.SQLException
{
if(mRecipeDao==null)
{
mRecipeDao = getDao(RecipeModel.class);
}
return mRecipeDao;
}
public synchronized Dao<IngredientModel, Long> getIngredientDao() throws java.sql.SQLException
{
if(mIngredientDao==null)
{
mIngredientDao = getDao(IngredientModel.class);
}
return mIngredientDao;
}
private boolean databaseExists()
{
File file = new File(DATABASE_PATH + DATABASE_NAME);
boolean exists = file.exists();
Logcat.d("DatabaseHelper.databaseExists(): " + exists);
return exists;
}
private boolean copyPrepopulatedDatabase()
{
String locale = java.util.Locale.getDefault().getDisplayName();
// copy database from assets
try
{
// create directories
File dir = new File(DATABASE_PATH);
dir.mkdirs();
// output file name
String outputFileName = DATABASE_PATH + DATABASE_NAME;
Logcat.d("DatabaseHelper.copyDatabase(): " + outputFileName);
// create streams
InputStream inputStream = CookbookApplication.getContext().getAssets().open(DATABASE_NAME);
OutputStream outputStream = new FileOutputStream(outputFileName);
// write input to output
byte[] buffer = new byte[1024];
int length;
while((length = inputStream.read(buffer))>0)
{
outputStream.write(buffer, 0, length);
}
// close streams
outputStream.flush();
outputStream.close();
inputStream.close();
return true;
}
catch(IOException e)
{
e.printStackTrace();
return false;
}
}
private int getVersion()
{
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(CookbookApplication.getContext());
return sharedPreferences.getInt(PREFS_KEY_DATABASE_VERSION, 0);
}
private void setVersion(int version)
{
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(CookbookApplication.getContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(PREFS_KEY_DATABASE_VERSION, version);
editor.commit();
}
}
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);
For my current project I decided to use ORMLite (4.46). Currently, I'm experiencing some issues when saving data of a foreign object. Below, a example of my code. The field called "field" is not saved properly (The old data is displayed). Anybody an idea, what's wrong with this code?
Thank you!
Regards
Andreas
Some class:
DatabaseHelper databaseHelper = OpenHelperManager.getHelper(context, DatabaseHelper.class)
branch.field = 123423;
Log.d("...", "field:" + branch.field); <-- new value of field is displayed
databaseHelper.getBranchDao().update(branch);
Other class:
DatabaseHelper databaseHelper = OpenHelperManager.getHelper(context, DatabaseHelper.class);
databaseHelper.getFloorDao().refresh(floor);
databaseHelper.getBranchDao().refresh(floor.branch);
Log.d("...", "branch field:" + floor.branch.field); <-- old value of field is displayed
DatabaseHelper:
...
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// name of the database file for your application -- change to something appropriate for your app
private static final String DATABASE_NAME = "xy.db";
// any time you make changes to your database objects, you may have to increase the database version
private static final int DATABASE_VERSION = 1;
// the DAO objects we use to access the tables
private Dao<Branch, Integer> branchDao = null;
private Dao<Floor, Integer> floorDao = null;
private Context appContext;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config);
appContext = context;
}
/**
* This is called when the database is first created. Usually you should call createTable statements here to create
* the tables that will store your data.
*/
#Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
try {
Log.i(DatabaseHelper.class.getName(), "onCreate");
// Create tables for each domain object here!
TableUtils.createTable(connectionSource, Branch.class);
TableUtils.createTable(connectionSource, Floor.class);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't create database", e);
throw new RuntimeException(e);
}
}
/**
* This is called when your application is upgraded and it has a higher version number. This allows you to adjust
* the various data to match the new version number.
*/
#Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
try {
Log.i(DatabaseHelper.class.getName(), "onUpgrade");
// Drop all tables of domain objects here!
TableUtils.dropTable(connectionSource, Branch.class, true);
TableUtils.dropTable(connectionSource, Floor.class, true);
// after we drop the old databases, we create the new ones
onCreate(db, connectionSource);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't drop databases", e);
throw new RuntimeException(e);
}
}
/**
* Delete and re-create database when user is changed
*/
public void reCreateDB(){
//delete the database (onCreate() will be called if database is needed again)
appContext.deleteDatabase(DATABASE_NAME);
}
/**
* Returns the Database Access Object (DAO) for our domain class. It will create it or just give the cached
* value.
*/
public Dao<Branch, Integer> getBranchDao() throws SQLException {
if (branchDao == null) {
branchDao = getDao(Branch.class);
}
return branchDao;
}
public Dao<Floor, Integer> getFloorDao() throws SQLException {
if (floorDao == null) {
floorDao = getDao(Floor.class);
}
return floorDao;
}
/**
* Close the database connections and clear any cached DAOs.
*/
#Override
public void close() {
super.close();
}
}
Floor:
...
public class Floor {
#DatabaseField(generatedId = true)
public int id;
#DatabaseField(foreign = true, canBeNull = true, foreignAutoRefresh = true, maxForeignAutoRefreshLevel=5)
public Branch branch;
public Floor(){}
}
Branch:
....
public class Branch {
#DatabaseField(generatedId = true)
public int id;
#DatabaseField(canBeNull = true)
public int field;
#ForeignCollectionField(eager = true, maxEagerLevel = 99)
private ForeignCollection<Floor> floors;
public Branch(){}
public ForeignCollection<Floor> getEmptyFloorCollection() {
try {
return MainActivity.getDatabaseHelper().getBranchDao().getEmptyForeignCollection("floors");
} catch (SQLException e) {
Log.e("DatabaseHelper", "SQL Exception: " + e.getLocalizedMessage());
return null;
}
}
public ForeignCollection<Floor> getFloors() {
if(floors == null) floors = getEmptyFloorCollection();
return floors;
}
public void setFloors(ForeignCollection<Floor> floors) {
this.floors = floors;
}
}