Using SharedPreferences with SQLiteOpenHelper before initialising the database - android

I would like to have a database for each user of my app. Usernames are stored in SharedPreferences. So I'm looking for something like this:
public class DatabaseHelper extends SQLiteOpenHelper {
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
String LoggedInUser = sp.getString("user","");
public static final String DATABASE_NAME = LoggedInUser + ".db";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
public void onCreate(SQLiteDatabase db) {
...
}
...
}
But this doesn't work, because SharedPreferences need context (using getApplicationContext() instead of this doesn't work either. This can be solved by something like this:
private Context appContext;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
this.appContext = context;
}
And then accessing SharedPreferences afterwards.
But I need to access SharedPreferences before this method ("DATABASE_NAME" is used in the above method and I want to define "DATABASE_NAME" using SharedPreferences).
Is there any way for doing this?

Since call to super() must be first statement, the only solution to achieve it would be to pass the DATABASE_NAME as constructor parameter:
public DatabaseHelper(final Context context, final string dbName) {
super(context, dbName, null, 1);
}
You can then either implement factory or Facade pattern to construct or pass the value to DatabaseHelper or simply pass the dbName value from Activity/Fragment.
An example of Factory could be:
public final class DatabaseFactory {
public static DatabaseHelper getDataBaseHelper(final Context context){
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
final String loggedInUser = sp.getString("user","");
return new DatabaseHelper(context,loggedInUser);
}
}
In Activity you can access the Helper as follows:
public class MainActivity extends Activity{
...
#Override
public void onCreate(Bundle savedInstanceState) {
...
final DatabaseHelper myDB = DatabaseFactory.getDataBaseHelper(this);
...
}
}

Must you use SharedPreference in you SQLiteOpenHelper?
I think you maybe use SQLite in your Activity, then how about declare SharedPreference in your Activity first, and get that in your SQLite through database's constructor.

Related

How to use multiple databases like multiple languages in android

I have two database to support two languages for my application.
I want to change database when I change language from settings.
Is it possible?? How can i do this?
It should be possible quite easily when you provide a string resource with the name of the database:
In /res/values/strings.xml put a line like this:
<string name="db_name">database</string>
In /res/values-de/strings.xml put that line:
<string name="db_name">database_de</string>
And in your DBHelper class use the database name of the strings file currently active according to language settings:
public class DBHelper extends SQLiteOpenHelper {
private final static int DB_VERSION = 1;
private static DBHelper sInstance;
/**
* Provides access to DBHelper singleton.
* #param context
* #return
*/
public static DBHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
// See this article for more information: http://bit.ly/6LRzfx
if (sInstance == null) {
sInstance = new DBHelper(context.getApplicationContext());
}
return sInstance;
}
/**
* Constructor should be private to prevent direct instantiation.
* make call to static factory method "getInstance()" instead.
*/
private DBHelper(Context context) {
// here comes the magic:
String dbName = context.getString(R.string.db_name);
super(context, db_name, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
// ...
}
// ...
}
using Ridcully solution, you will need to add only the database name part,
all you need to add is the class you extend.
this example from the library you mentioned:
public class MyDatabase extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 1;
public MyDatabase(Context context) {
// here comes the magic:
String dbName = context.getString(R.string.db_name);
super(context, dbName , null, DATABASE_VERSION);
}
}
The other database class can be:
public class MyDatabase2 extends SQLiteAssetHelper {
private static final int DATABASE_VERSION = 1;
public MyDatabase(Context context) {
// here comes the magic:
String dbName = context.getString(R.string.db_name_2);
super(context, dbName , null, DATABASE_VERSION);
}
}
NOTE: to use SQLiteAssetHelper, u need to create the database yourself, and put in the assets/databases folder.
you can create sqlite database with this app Sqlitebrowser

Ormlite - Access Two Databases from the same activity

I have an Android app where I need to access two different databases from the same activity.
I am using Ormlite to read from/write to database.
public class MyActivity extends OrmLiteBaseActivity<MyDatabaseHelper>
I need to use another database helper for the other database.
Can anyone direct me on how to achieve this?
Should I use the same DatabaseHelper and make modifications there to support both databases? Or is there a way to use different databaseHelpers in the same activity?
In your case I think that the better solution is to use separate helpers and not to extend OrmLiteBaseActivity.
public class DatabaseHelperA extends OrmLiteSqliteOpenHelper {
public static DatabaseHelper getInst(){
return inst;
}
public static void init(Context c){
if (inst == null) inst = OpenHelperManager.getHelper(c, DatabaseHelperA.class);
}
public DatabaseHelper(Context context) {
super(context, "a.db", null, 1);
}
}
public class DatabaseHelperB extends OrmLiteSqliteOpenHelper {
public static DatabaseHelper getInst(){
return inst;
}
public static void init(Context c){
if (inst == null) inst = OpenHelperManager.getHelper(c, DatabaseHelperB.class);
}
public DatabaseHelper(Context context) {
super(context, "a.db", null, 1);
}
}

Database initialization error in static method

I have database class. The class and its constructor are shown below.
public class LatLogDBAdapter {
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
I want to use the database in the static method. So that I declare as private static LatLogDBAdapter dbHelper;. Then when i initialize, i have problem. dbHelper = new LatLogDBAdapter(this); dbHelper = new LatLogDBAdapter(DetailMapView.this); make compile error. How can I use this in static method?
If you want to create static method that returns your dbhelper i suggest you to create normal subclass of SQLiteOpenHelper and in this class create public static method that will return new instance. This also is sounds like good reason to use design pattern Singleton
Update:
I mean I want to use this database class inside another java class.
That class has static method and use the database.
Here i create for you basic snippet of code:
public class AdapterWrapper {
private static SQLiteOpenHelper instance;
public static SQLiteOpenHelper getInstance(Context c) {
if (instance == null) {
instance = new DatabaseHelper(c);
}
return instance;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "Example";
private static final int DB_START_VERSION = 1;
public DatabaseHelper(Context cntx) {
super(cntx, DB_NAME, null, DB_START_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// creating tables
}
#Override
public void onUpgrade(SQLiteDatabase db, int old, int new) {
/// drop an upgrading db
}
}
}

passing context from non-activity

i yet really grasp this whole context thing we found a lot in android programming. so i tried creating a function to drop all my tables, and here's a my partial code:
public class DBAdapter {
private static class DbHelper extends SQLiteOpenHelper {
private boolean databaseCreated = false;
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void deleteTables(){
Log.d("DBAdapter","dlm drop tables pre");
this.sqlDatabase.execSQL("DROP TABLE IF EXISTS ["+TABLE_TV+"];");
this.sqlDatabase.execSQL("DROP TABLE IF EXISTS ["+TABLE_CAMERA+"];");
this.sqlDatabase.execSQL("DROP TABLE IF EXISTS ["+TABLE_GPS+"];");
}
}
}
and the part where i'm going to call the function deleteTables
public class UpdateDatabase {
public void updateTable(String table,JSONObject jsonObject){
DBAdapter db = new DBAdapter(this);
db.deleteTables();
}
}
but of course it will return an error, since DBAdapter expects a context. public class UpdateDatabase is not an activity class. Calling DbAdapter db = new DBAdapter(this) from activity class will work just find. So how do I find any fix for this problem?
thanks
You can add a constructor to UpdateDatabase that takes a Context and stores it so that it is available to be used by updateTable. Something like this:
public class UpdateDatabase {
private final Context mContext;
public UpdateDatabase(Context context){
mContext = context;
}
public void updateTable(String table,JSONObject jsonObject){
DBAdapter db = new DBAdapter(mContext);
db.deleteTables();
}
}
Now, whenever you do new UpdateDatabase() you will need to do new UpdateDatabase(..context..) instead. If you are doing this from an Activity, then you can do new UpdateDatabase(this).
hi look this code..
public class DbManager
{
// the Activity or Application that is creating an object from this class.
Context context;
CustomSQLiteOpenHelper helper;
// a reference to the database used by this application/object
protected SQLiteDatabase db;
private static DbManager INSTANCE;
// These constants are specific to the database.
protected final String DB_NAME = "yourDB";
protected final int DB_VERSION = 1;
public DbManager(Context context)
{
this.context = context;
// create or open the database
helper = new CustomSQLiteOpenHelper(context);
this.db = helper.getWritableDatabase();
}
public static DbManager getInstance(Context context){
if(INSTANCE == null)INSTANCE = new DbManager(context);
return INSTANCE;
}
public void db_Close()
{
if(helper!=null){
helper.close();
}
this.db.close();
}
private class CustomSQLiteOpenHelper extends SQLiteOpenHelper
{
public CustomSQLiteOpenHelper(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
// This string is used to create the database.
// execute the query string to the database.
//db.execSQL(newTableQueryString);
Log.i("DataBaseManager", "Create Table");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// NOTHING TO DO HERE. THIS IS THE ORIGINAL DATABASE VERSION.
// OTHERWISE, YOU WOULD SPECIFIY HOW TO UPGRADE THE DATABASE.
}
}
}
// Inherit the DbManager Class
public class DataCollection extends DbManager {
public DataCollection(Context context){
super(context);
}
public void deleteTable(String TABLE_NAME){
try {db.execSQL("DROP TABLE "+TABLE_NAME);}//.delete(TABLE_NAME, null, null);}
catch (Exception e){
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
}

SQLiteOpenHelp execution sequence

I have code like this:
public class DatabaseHelper extends SQLiteOpenHelper
{
private static final String DATABASE_NAME = "IDATT.data.db";
private static final int DATABASE_VERSION = 201;
private Context mContext;
public DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
}
I wonder if onCreate/onUpgrade going to be called in super or after creation? Reason I ask - I need Context inside my onUpgrade/onCreate methods and don't know how to test this class
The onCreate() is always called when you instantiate you class, just like those ones that extends Activity.
The onUpgrade() just gonna to be called if you pass a different DATABASE_VERSION to the super call.
Hope it helps

Categories

Resources