I'm using Sqlite with android to develop and app which can be customizable (for the dev) in the future. I have created a database with the data which is then to be used to create the database for the application. So if any changes need to be made in the future or I write an app for somebody else in the future then all I have to do is change this original database. The idea behind this is the dev's database will set up all the UI and everything to do with the app.
I am stuck on what to do next I have the database I need in the app as the dev fully populated. My idea was to create another DBHelper class and within that reference the original DBHelper class and query within the new DB Class. So this is the second DBHelper class that i'm trying to create a database from a previous database:
public class appDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "library.db"; //database name
Cursor all, tables, options, ui_type;
SQLiteDatabase database;
public appDbHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
DBHandler databaseHelper = new DBHandler(context);
database = databaseHelper.getReadableDatabase();
all = database.rawQuery("SELECT * FROM config", null);
tables = database.rawQuery("SELECT * FROM table_names", null);
options = database.rawQuery("SELECT * FROM options", null);
ui_type = database.rawQuery("SELECT * FROM ui_type", null);
}
#Override
public void onCreate(SQLiteDatabase db) {
for(int i=0; i<tables.getCount(); i++){
tables.moveToPosition(i+1);
String sql = "";
for(int j = 0; i < all.getCount(); j++){
if (all.moveToFirst()) {
do{
sql = ", " + all.getString(2) + " " + all.getString(5).toUpperCase();
}
while (all.moveToNext());
}
}
Log.v("DatabaseSQL", sql);
database.execSQL( "CREATE TABLE " + tables.getString(1) + "(_id INTEGER PRIMARY KEY AUTOINCREMENT"+sql+");");
}
}
But I have a feeling this is not the way to go about what I need to do. Any help will be greatly appreciated.
I think you do it wrong and to complicated. You provide a database to read data from where you could easily just create some inserts and your configuration will be implemented.
Two solutions:
From my own project: DatabaseAdapter.onCreate()
There you should see the database setup and the filling of the database with data. The data itself are added with simple inserts which contains data based on constants. So a programmer can easily change the data by changing the constants.
With that you don't have to handle 2 databases, you don't need to provide another database and read them.
As android supports database locations you could also skip this all and just open an sqlite database file you provide in your res/raw or asset folder or anywhere on the sdcard.
I recommend to do one of the two ways mentioned above.
Related
I am so new and new in android , i have a big problem with it, i create an app that needs to connect to database .so i create a database using sqllite expert pro as you can see here :
CREATE TABLE [user](
[name] tEXT,
[id] INT PRIMARY KEY);
My database name is a .i want to read the value from the user table as you can see here in my code :
SQLiteDatabase mydatabase = openOrCreateDatabase("a",MODE_PRIVATE,null);
Cursor resultSet = mydatabase.rawQuery("Select * from user",null);
resultSet.moveToFirst();
String username = resultSet.getString(1);
String password = resultSet.getString(2);
TextView tv = (TextView) findViewById(R.id.editText1);
tv.setText("Text is: " + username + password);
but it doesn't work ,should i add connection string to my code ,or should i import the database into my project,because the database is in my workspace folder.
I use this code to create a test database inside android ,but it doesn't work again?
SQLiteDatabase mydatabase = openOrCreateDatabase("ali",MODE_PRIVATE,null);
mydatabase.execSQL("CREATE TABLE IF NOT EXISTS TutorialsPoint(Username VARCHAR,Password VARCHAR);");
mydatabase.execSQL("INSERT INTO TutorialsPoint VALUES('admin','admin');");
Cursor resultSet = mydatabase.rawQuery("Select * from TutorialsPoint",null);
resultSet.moveToFirst();
String username = resultSet.getString(1);
String password = resultSet.getString(2);
Your database needs to be copied to the phone's internal storage first. You can do it manually or with the help of this library Android SqliteAsset Helper
Follow the right method for creating database in android using codes:
Create a class that extends SqliteOpenHelper.
public class DbOpener extends SqliteOpenHelper {
DbOpener(Context c){
super(c, 1, "a", null, 1); //where "a" is the database name
}
public void onCreate (SqliteDatabase db){
db.execSQL("CREATE TABLE TutorialsPoint (Username VARCHAR, Password VARCHAR);");
}
}
Then in your activity use it as follows:
DbOpener opener = new DbOpener(this);
SqliteDatabase myDatabase = opener.getWritableDatabase();
//Now you can perform all your queries (including insertions) using the myDatabase object
First, you should change your database name to a readable one like "mydata.db"
Second, there is no need for connection string on using SQLite in Android like the usual ways we do with accessing database from Java code.
You need to access database by using SQLiteOpenHelper. Tutorial from Android SQLite database and content provider. Try to get the feel with Android and SQLite from the tutorial.
Then, after you've mastering the concept and know the how, you can use your predefined database by utilizing Android SQLiteAssetHelper
I want to search a column by using an id.
That function will return all the values in that particular row.
Here's my code and log.
LOG:
09-19 14:00:54.940 618-618/? **I/SqliteDatabaseCpp﹕ sqlite returned: error code = 1, msg = table IUBConnectivitydata already exists, db=/data/data/com.example.sivs.datacopy/databases/**
09-19 14:00:54.970 618-618/? E/SQLiteOpenHelper﹕ Couldn't open Database1 for writing (will try read-only):
Code:
public Cursor Rowdata(String a){
SQLiteDatabase db=this.getReadableDatabase();
Log.d("a4","aaa34");
Cursor cursor1=db.rawQuery("SELECT "+COL_3+", FROM" + TABLE_NAME + "where WBTSID==?",new String[] {a});
Log.d("a3","row");
return cursor1;
}
You added an extra comma before FROM, an extra = before ? and forgot 2 spaces around the table name.
Wrong:
db.rawQuery("SELECT "+COL_3+", FROM" + TABLE_NAME + "where WBTSID==?",new String[] {a});
Right:
db.rawQuery("SELECT "+COL_3+" FROM " + TABLE_NAME + " where WBTSID=?",new String[] {a});
try following,
if (c.moveToFirst()){
do{
id = c.getInt(c.getColumnIndex("_id"));
}while(cursor.moveToNext());
}
c is a cursor of all data.
I would recommend only one global database helper class instance, which can be located in the extended application class. The helper class itself must hold an instance of SQLiteDatabase, which is the actual database object.
It can look like this:
public MyClass extends Application {
private MyDBHelper db;
public MyDBHelper getDB() {
if (database == null) {
db = new MyDBHelper(this);
}
db.open(); // call getWritableDataBase internally
return db;
}
}
If you create the database in the SqlLiteHelpers onCreate() callback, then it should be only created the very first time you open the app after installation.
In the onOpen() callback of SqlLitehelper you can activate foreign key constraints with setForeignKeyConstrainsEnabled(true), which is an important safety feature. Of coure you have to declare foreign keys with REFERS() clauses.
EDIT: Creating a synchronized static instance is also possible (as stated in the comment below). Anyway you must ensure that there exists only one instance of your database helper class and only one instance of the database itself. (Which must be located in the database helper class)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm a windows phone developer and newly I started developing android apps using android studio.
I need to create a database and store in it values and retrieve the updated values on screen, so I need help in:
Creating the database.
How to show values from the database on screen?
to create database , you need to extend SQLiteOpenHelper and need a constructor that takes Context.
lets say you name this class DBOperator. The table creation process will look something like this ,
public class DbOperator extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "DB_NAME";
protected static final String FIRST_TABLE_NAME = "FIRST_TABLE";
protected static final String SECOND_TABLE_NAME = "SECOND_TABLE";
public static final String CREATE_FIRST_TABLE = "create table if not exists "
+ FIRST_TABLE_NAME
+ " ( _id integer primary key autoincrement, COL1 TEXT NOT NULL, COL2 TEXT NOT NULL,COL3 TEXT, COL4 int, COL5 TEXT,"
+ "COL6 TEXT,COL7 REAL, COL8 INTEGER,COL9 TEXT not null);";
public static final String CREATE_SECOND_TABLE = "create table if not exists "
+ SECOND_TABLE_NAME+.........
public DbOperator(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_SFIRST_TABLE);
db.execSQL(CREATE_SECOND_TABLE);
//db.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//THIS WILL BE EXECUTED WHEN YOU UPDATED VERSION OF DATABASE_VERSION
//YOUR DROP AND CREATE QUERIES
}
}
Now your data manipulation class ( add, delete , update ) will look something like this ,
public class FirstTableDML extends DbOperator {
public FirstTableDML(Context context) {
super(context);
}
private static final String COL_ID = "_id";
private static final String COL1 = "COL1";
private static final String COL2 = "COL2";
........
.......
public void deleteFirstTableDataList(List<FirstTableData> firstTableDataList) {
for (FirstTableData data : firstTableDataList)
deleteFirstTableDetailData(data);
}
public void deleteFirstTableDetailData(FirstTableData item) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(FIRST_TABLE_NAME, item.getId() + "=" + COL_ID, null);
db.close();
}
/**this method retrieves all the records from table and returns them as list of
FirstTableData types. Now you use this list to display detail on your screen as per your
requirements.
*/
public List< FirstTableData > getFirstTableDataList() {
List< FirstTableData > firstTableDataList = new ArrayList< FirstTableData >();
String refQuery = "Select * From " + FIRST_TABLE_NAME;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(refQuery, null);
try {
if (cursor.moveToFirst()) {
do {
FirstTableData itemData = new FirstTableData();
itemData.setId(cursor.getInt(0));
itemData.setCol1(cursor.getString(1));
itemData.setCol2(cursor.getInt(2));
.....
.....
firstTableDataList.add(itemData);
} while (cursor.moveToNext());
}
} finally {
db.close();
}
Collections.sort(itemDataList);
return itemDataList;
}
public int addFirstTableData(FirstTableData data) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL1, data.getCol1());
values.put(COL2, data.getCol2());
.....
.....
long x=db.insert(FIRST_TABLE_NAME, null, values);
db.close();
return (int)x;
}
public void updateItemDetailData(FirstTableData data) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL1, data.getCol1());
values.put(COL2, data.getCol2());
values.put(COL3, data.getCol3());
.....
.....
db.update(FIRST_TABLE_NAME, values, COL_ID + "=" + data.getId(), null);
db.close();
}
}
P.S : *Data class are POJO data class representing the corresponding table.
Since you said you are not totally new to these, I have not provided any helper comments as most of the method names are self explanatory.
Hope it helps you to get started.
To creating a database for Android application, there are 2 ways:
Create database and tables using Code
Use existing database
1) Create database and tables using Code
In this scenario, you have to write a class and code to create database and tables for it. You have to use different classes and interfaces like SQLiteOpenHelper, SQLiteDatabase, etc. Check answer posted by Jimmy above.
2) Use existing database
In this scenario, you can use your existing sqlite database inside your android application. You have to place database file inside assets folder and write a code to copy that existing database on to either internal or external storage.
Regarding best scenario, I would say it's depend on the application functionality and nature, if your database is small then you should go with 1st scenario and if your database is large with many tables then you should go with 2nd scenario because you would be creating database using any GUI based SQLite browser and which would help you to make less mistakes. (When I say less mistakes using GUI, believe me there are chances of creating tables by code).
How to show values from the database on screen?
For that you have to write a SQL query which gives you Cursor in return which is a set of resultant data, so you have to iterate through the cursor data and prepare a set of data in terms of ArrayList or Array or HashMap.
You can display this set of data in ListView or GridView.
P.S. I am not posting links to any tutorials or examples as there are plenty of information/examples available on web, so suggesting you to search around the given points.
A good way to start is to read about Storage Options on the official Android documentation website: http://developer.android.com/guide/topics/data/data-storage.html
In my application I have a content provider which uses a database for the content provided. When the database is created the first time it needs to be filled from the raw content of a Json file. My idea was that i trigger this filling of the database at onCreate of my SQLiteOpenHelper subclass. This works fine yet I am not sure how to handle the the communication between application and content provider when the app is running the first time. Basically i would like to show some sort of a splash screen while the database is filled. Yet how does the application get informed that
the content provider is busy filling the database when running the first time
the content provider is ready to go
Surely I could fill the database from the application by calling the content provider with each dataset yet I would prefer doing it within the sphere of the content provider so that the application does not have to handle the reading of the json file etc. Besides design preferences it would also enable the content provider to fill the database more efficiently because it would have the whole dataset at once. I have a feeling this is not possible yet I hope I miss some simple point.
Any suggestions how to achieve this would be highly appreciated.
Thanks
martin
When using a content Provider i would presume that your using a DBHelper class to manage the creation of the database. Below is the code from the android notes example project.
This shows how the DBHelper constructor is intelligent enough to determine if the database has been created before. In the createDatabase method i would subsequently call a method to pre-populate the database, from as you say a json file.
The problem is that this doesn't really allow you to communicate to the Activity that your database hasn't been initialised.
One thought could be that you use SharedPreferences to store the fact you've populated the database. You could then check the sharedPreference in the activity on startup, Call the content provider to populate the database and then store in the shared preference that you've done this task already.
Just be aware that i'm not sure if the sharedPreferences maintain the same state as the database if you for example erase the data from the android settings menu. You'd need to check that.
http://code.google.com/p/android-notes/source/browse/trunk/src/com/bitsetters/android/notes/DBHelper.java?r=10
public class DBHelper {
private static final String DATABASE_NAME = "notes";
private static final String TABLE_DBVERSION = "dbversion";
private static final String TABLE_NOTES = "notes";
private static final int DATABASE_VERSION = 1;
private static String TAG = "DBHelper";
Context myCtx;
private static final String DBVERSION_CREATE =
"create table " + TABLE_DBVERSION + " ("
+ "version integer not null);";
private static final String NOTES_CREATE =
"create table " + TABLE_NOTES + " ("
+ "id integer primary key autoincrement, "
+ "note text, "
+ "lastedit text);";
private static final String NOTES_DROP =
"drop table " + TABLE_NOTES + ";";
private SQLiteDatabase db;
/**
*
* #param ctx
*/
public DBHelper(Context ctx) {
myCtx = ctx;
try {
db = myCtx.openOrCreateDatabase(DATABASE_NAME, 0,null);
// Check for the existence of the DBVERSION table
// If it doesn't exist than create the overall data,
// otherwise double check the version
Cursor c =
db.query("sqlite_master", new String[] { "name" },
"type='table' and name='"+TABLE_DBVERSION+"'", null, null, null, null);
int numRows = c.getCount();
if (numRows < 1) {
CreateDatabase(db);
} else {
int version=0;
Cursor vc = db.query(true, TABLE_DBVERSION, new String[] {"version"},
null, null, null, null, null,null);
if(vc.getCount() > 0) {
vc.moveToFirst();
version=vc.getInt(0);
}
vc.close();
if (version!=DATABASE_VERSION) {
Log.e(TAG,"database version mismatch");
}
}
c.close();
} catch (SQLException e) {
Log.d(TAG,"SQLite exception: " + e.getLocalizedMessage());
} finally {
db.close();
}
}
private void CreateDatabase(SQLiteDatabase db)
{
try {
db.execSQL(DBVERSION_CREATE);
ContentValues args = new ContentValues();
args.put("version", DATABASE_VERSION);
db.insert(TABLE_DBVERSION, null, args);
db.execSQL(NOTES_CREATE);
// Populate with data
populateDataBaseFromFile();// There are probably better ways to do this.
setSharedPreferenceYouPopulatedDB();
} catch (SQLException e) {
Log.d(TAG,"SQLite exception: " + e.getLocalizedMessage());
}
}
Personally I wouldn't bother with the splash screen, unless you really needed to.
Another thought might be to:
Write in the db helper a method to determin if your tables exist. Return false if not.
In startup activity call ContentProvider with a request that calls the DBHelper test method.
If false then display splash screen and then call Content Provider to populate DB.
If true, then carry on as normal.
My app's got a database with three tables in it: one to store the names of the people it tracks, one to track an ongoing event, and one - for lack of a better term - for settings.
I load the first table when the app starts. I ask for a readable database to load in members to display, and later I write to the database when the list changes. I've had no problems here.
The other two tables, however, I can't get to work. The code in the helper classes is identical with the exception of class names and column names, and (at least until the point where I try to access the table) the code to use the table is nearly identical as well.
Here's the code for my helper class (I've got a separate helper for each table, and as I said, it's identical except for class names and columns):
public class db_MembersOpenHelper extends SQLiteOpenHelper
{
public static final String TABLE_NAME = "members_table";
public static final String[] COLUMN_NAMES = new String[] {
Constants.KEY_ID,
"name",
"score"
};
private static final String TABLE_CREATE = "CREATE TABLE " + TABLE_NAME + " ("
+ COLUMN_NAMES[0] + " INTEGER PRIMARY KEY autoincrement, "
+ COLUMN_NAMES[1] + " TEXT, "
+ COLUMN_NAMES[2] + " INTEGER);";
public db_MembersOpenHelper(Context context)
{
super(context, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) { db.execSQL(TABLE_CREATE); }
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w("TaskDBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion + ".");
// Do nothing. We do not have any updated DB version
}
}
Here's how I use it successfully:
db_MembersOpenHelper membersDbHelper = new db_MembersOpenHelper(this);
SQLiteDatabase membersDb = membersDbHelper.getReadableDatabase();
Cursor membersResult = membersDb.query(TABLE_NAME, null, null, null, null, null, null);
members = new HashMap<String, Integer>();
membersResult.moveToFirst();
for(int r = 0; r < membersResult.getCount(); r++)
{
members.put(membersResult.getString(1), membersResult.getInt(2));
membersResult.moveToNext();
}
membersDb.close();
And here's where it fails:
db_PlayersOpenHelper playersDbHelper = new db_PlayersOpenHelper(this);
final SQLiteDatabase playersDb = playersDbHelper.getWritableDatabase();
if(newGame)
{
for(String name : players)
{
ContentValues row = new ContentValues();
row.put(COLUMN_NAMES[1], name);
row.put(COLUMN_NAMES[2], (Integer)null);
playersDb.insert(TABLE_NAME, null, row);
}
}
The first one works like a charm. The second results in ERROR/Database(6739): Error inserting achievement_id=null name=c
android.database.sqlite.SQLiteException: no such table: players_table: , while compiling: INSERT INTO players_table(achievement_id, name) VALUES(?, ?);
...
I did do some testing, and the onCreate method is not being called at all for the tables that aren't working. Which would explain why my phone thinks the table doesn't exist, but I don't know why the method isn't getting called.
I can't figure this out; what am I doing so wrong with the one table that I accidentally did right with the other?
I think the problem is that you are managing three tables with with three helpers, but only using one database. SQLiteOpenHelper manages on database, not one table. For example, it checks to see whether the database, not table, exists when it starts. It already does, so onCreate() does not fire.
I would manage all tables with one helper.
Let me see if I get this right. You are trying to create one database with three tables. But when you create the database, you create just one table; you are somehow instantiating the same database at a different place and wonder why its onCreate method doesn't get called. Is this a correct interpretation?
My strategy would be to try and create all three tables in the single onCreate() method.
If you are working with multiple tables, then you have to create all of the tables at once. If you have run your application first and later you update your database, then it will not upgrade your DB.
Now delete your application, then run it again.
There is one more solution but it is not proper. You can declare onOpen method in which you can call onCreate. And add IF NOT EXISTS before table name in your create table string. – Sourabh just now edit