I want to see if there is a way to assign different database names to different users that login to an app. I'm trying to write a small app that assigns a DB to a user based on their username/email.
I tried setting DATABASE_NAME that is passed into
public SQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
to the users' email addresses but it doesn't work. It loads the same data for all users.
On logout, I close the database and clean up and on startup, everytime I start a new database connection with the name already properly assigned...
Can someone help me understand what I'm missing?
You can just pass the name of the database to your SQLiteOpenHelper class constructor (along with required Context instance) instead of hardcoding it as did DATABASE_NAME:
public class DBOpenHelper extends SQLiteOpenHelper {
public DBOpenHelper(Context context, String dbName, int dbVersion) {
super(context, dbName, null, dbVersion);
}
...
}
Related
I'm getting the
'This class should provide a default constructor'
error when i'm trying to build the APK
this is my DBHelper class:
public class DBHelper extends SQLiteOpenHelper {
// create variables
public DBHelper(Context context)
{
super(context, DATABASE_NAME , null, 1);
}
// onCreate
I was under the impression that
public DBHelper(Context context)
was the default constructor? And have checked other answers with this and can't find anything to help...
Thanks in advance
A default constructor is a constructor without any arguments.
SQLiteOpenHelper needs at least a context so you won't be able to create a default constructor for your DBHelper. Are you sure this is the class causing this error ?
As the error suggest
Error: This class should provide a default constructor (a public constructor with no arguments)
try this way:
public class DBHelper extends SQLiteOpenHelper {
// create variables
public DBHelper(){
super();
}
public DBHelper(Context context)
{
super(context, DATABASE_NAME , null, 1);
}
// onCreate
I want to open the database once only from the main screen of my app , and I want to use this instance anywhere in any activity. Is that possible or should I make the context to be each actual opened activity so that I must create an instance of the database ( open ) in every activity ?
Is that possible or should I make the context to be each actual opened
activity so that I must create an instance of the database ( open ) in
every activity ?
it is possible, and you could use the application context. Your DBHelper could be a singleton. E.g
public class DBHelper extends SQLiteOpenHelper {
private static DBHelper sInstance;
public static synchronized DBHelper getInstance(Context context) {
if (sInstance == null) {
sInstance = new DBHelper(context.getApplicationContext());
}
return sInstance;
}
private DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
You do not need to close and re-open the SQL connection per each individual Activity.
Having said that - it is best to open the connection using an app context, to avoid Activity leaks.
You can get an app context refrence quite easily.
On my app I make use of two datatabases.
This is the class that handles the database management and all the query that are made to it.
public class Database {
private DbHelper DBHelper;
private final Context Context;
private SQLiteDatabase MyDBone, MyDBtwo;
static Context ctx;
private static class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context, String dbName, int dbVersion) {
super(context, dbName, null, dbVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
// This is where the two databases are created
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVesion) {
// database upgrades are handled here
}
}
}
// database constructor
public Database(Context c) {
Context = c;
ctx = c;
}
// database open
public Database open() throws SQLException {
DBHelper = new DbHelper(Context, BD_NAME, BD_VERSION);
// I have here some if code to decide witch one of the bellow is used
if{
MyDBone = DBHelper.getWritableDatabase();
} else{
MyDBtwo = DBHelper.getWritableDatabase();
}
return this;
}
// database close
public void close() {
DBHelper.close();
}
public Cursor getData(........) {
// My querys are made here
}
}
My problem is that the databases are too big. In the onCreate method I'm getting the error: The code of method onCreate(SQLiteDatabase) is exceeding the 65535bytes limit. On the other side, my app is getting very big on size.
I would like to know what's the best way to address this issue since I can't change my databases.
Since my app must be run offline I can't make query's on a webserver.
I beleive that the best aproach would be to, on the first run of the app, download the databases from somewhere on the internet (drive, dropbox or other side) but since my programming skils are a little green I must pospone this to a must do in the future.
Is it possible, maintaining my Database class, prepack the apk with the databases and install them on the sdcard? On the other side this will increase the apk size (the total of the databases is 15 mb).
Please advise on the best way to address this issue.
Regards,
favolas
I have created a database by extending SQLiteOpenHelper class. And its created also. This is code I am pasting
public Imagehelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
cntxt = context;
filename = Environment.getExternalStorageDirectory();
DATABASE_FILE_PATH_EXTERNAL = filename.getAbsolutePath()+File.separator+DATABASE_NAME;
Log.i("Log", ":"+DATABASE_FILE_PATH_EXTERNAL);
}
Here everything is working fine.
But if you focus on the parameters pass in super super(context, DATABASE_NAME, null, SCHEMA_VERSION); . I am not able to understand the null parameter. I know here we have to pass the SQLiteDatabase.CursorFactory object.
But how?? And what is the use of that??
The reason of passing null is you want the standard SQLiteCursor behaviour. If you want to implement a specialized Cursor you can get it by by extending the Cursor class( this is for doing additional operations on the query results). And in these cases, you can use the CursorFactory class to return an instance of your Cursor implementation. Here is the document for that
SQLiteDatabase.CursorFactory DOC
Used to allow returning sub-classes of Cursor when calling query.
I'm trying to get a better understanding of the SQLiteOpenHelper class and how and when onCreate and onUpgrade are called.
My problem is that each time I quit and start my application (technically it's actually each time I create a new instance of MyDB), onCreate is called, and all of the data from the previous usage is effectively wiped... WTF???
I got around this problem initially by creating a singleton MyDBFactory where I created a single instance of MyDB. This allowed the data to be persistent while the application is running at least.
What I would like is for my database schema and data to be persistent!
I basically have:
public class MyDB extends SQLiteOpenHelper{
private static int VERSION = 1;
...
public ContactControlDB(Context context) {
super(context, null, null, VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(DATABASE_CREATE);
db.execSQL(INSERT_DATA);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
and:
public class MyDBFactory{
private static MyDB db;
public static MyDB getInstance(Context context) {
if(db == null) {
db = new MyDB (context);
}
return db;
}
}
What I'd like to know is why onCreate is called every time I have 'new MyDB(context)', and where my database goes each time my app exits.
If you have some appropriate links, or some knowledge that would clue me up a bit, I'd greatly appreciate it!
the line:
super(context, null, null, VERSION);
the second parameter is null specifying that the database should be created in memory, you should give it a name.
Android reference