I'm making a simple android app.
When first loaded, the app will show users a list of items (A)
The users will be able to add more items to this list
Each item can be clicked on which will show another list (B)
The users will be able to add more items to the second list as well.
I've gotten the first point done by storing few items in list and presenting them in ListView. I am wondering how can users add new items to the list and how would I persist?
I've seen several tutorials on internal storage and sql lite. Which one would be best for my needs in this scenario?
I would really benefit from a sample app on github that kind of shows how to accomplish this.
You also know :
Internal Storage
Store private data on the device memory.
By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.
People always use internal storage when they want to read/write the large file via InputStream/OutputStream.
SQLite Databases
Store structured data in a private database.
Please notice structured data, it will be good for you to access the Sqlite database via name, so it will be fast.
P/s: If you need inflate data to the list item. You should use Sqlite since it fast and easily to access the data via name.
It really depends on how you want to use the data. SQLite is easy to use on Android and runs fast. I'm using it for a fairly large database in my app.
I also suggest putting it in internal storage. That way, it is protected from other apps spying on the user's data (unless he "roots" his phone). One caveat on using internal storage is that it's hard to see your data. To get to the db you either need to run Android on an emulator (where you will have the privilege to see all files) or copy the db (by writing some code to copy a file) to external storage. Or simply temporarily put the db in external storage while you are debugging.
I don't have any github references for you, but can give you a quick outline. Subclass SQLiteOpenHelper and add methods for your CRUD actions.
public class DbHelper extends SQLiteOpenHelper
{
private static final int DB_VERSION = 1;
#Override
public void onCreate(SQLiteDatabase db)
{
String[] ddl = {"... all the tables you need to create..."};
db.beginTransaction();
try
{
for (int i = 0, limit = ddl.length; i < limit; i++)
db.execSQL (ddl [i]);
db.setTransactionSuccessful();
}
finally
{
db.endTransaction();
}
}
#Override
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion)
{
db.beginTransaction();
try
{
for ( ; oldVersion < newVersion; oldVersion++)
{
if (oldVersion == 1)
onUpgrade1to2 (db);
else if (oldVersion == 2)
...
}
db.setTransactionSuccessful();
}
finally
{
db.endTransaction();
}
}
public void insertItem (SQLiteDatabase db, Item item) // Item is one of your objects
{
ContentValues values = new ContentValues();
// id
values.put ("id", item.id);
values.put ("subject", item.subject);
...
db.insertOrThrow ("Items", null, values);
}
... and so on ...
}
Let me know if you need info on how to query, update, and delete...
Related
I have an android application which is using Sqlite as database.It has following tables:
Hotels
Locations
Favorites
I am keeping my raw database file in assests folder and when user installs my app i just copies this database to /data/data/package_name/databases directory.Initially Favorites table is empty and it gets populated after user start liking hotels.My problem is that I want to launch my updated version of app with some bug fixes and some new hotels added to the database, so I need to update database of existing users with new hotels and locations without affecting the favorites table.Now if I keep my old approach and update the Database Version Number then application will remove the old database and use the new database but all data in favorites table will be lost.I don't want it to happen.Now problem is how do I update Hotels and Locations table without loosing data in Favorites table.
I know this question was asked long ago, but I had a similar issue and wanted to share my solution, seems to do the trick for me. I'm a novice so feel free to give input-
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//code to keep table data
List<obj> objList = new ArrayList<obj>();
String selectQuery = "SELECT score,list_name,quiz_length FROM obj_table";
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
obj o = new obj();
o.final_score = cursor.getInt(0);
o.quiz_name = cursor.getString(1);
o.quiz_length = cursor.getInt(2);
objList.add(o);
} while (cursor.moveToNext());
}
//done storing data, now upgrade DB from asset file
try {
//my db file is upgraded here
copyDataBase();
} catch (IOException e) {
}
//now insert our saved table data
for (Score obj_rec: objList){
ContentValues values = new ContentValues();
values.put("score", obj_rec.final_score);
values.put("list_name", obj_rec.quiz_name);
values.put("quiz_length", obj_rec.quiz_length);
db.insert("obj_table", null, values);
}
}
Before updating write the contents of you previous table to a file and save it on the sdcard.
Then you may update your database with new version.
And after doing that copy back the data from the backup file(from sdcard) to the updated database. After the successful copying of the backup, delete the file from the sdcard.
Usualy upgrade a database has to be done with SQLiteOpenHelper class. I would advise You to do some tests at Your own device before publish it. You have to increment Your Database Version and call "ALTER TABLE" method from sqlite. This has been discussed in many threads here, the clearest one I think is this one:
Difficulty in upgrading SQlite table
and here is even a article with some solution:
http://joshhendo.blogspot.de/2012/03/android-sqlite-database-upgrade.html
However, a safe way would be to save the old database in a tempfolder, that the user can get back the old one if anything is running into chaos.
For my app, I need to have a database containing one table with 4 columns in it. This tables and its parameters will be static after creation, so that they will stay in the same place with the same data to be listed in a list view.
I have the DatabaseHandler for this purpose, but what I'm asking is how do I define this database in code? Does it build again every launch or is it only with the first launch? How does it work?
There are many ways of doing it. The one i follow is I will create database and tables in launch activity. Then i will insert data by counting the number of records in the table(Only for static table).So if(number of records == 0) then insert data into database. Otherwise do code for your app. It should work.
EDIT
This is the code to get total number of records in the database
In Database Class
YourDatabase
public class YourDatabase extends SQLiteOpenHelper{
//coding for table create and insert records goes here
//Your tables total number of records can be identified by following code
public long yourTableCount()
{
SQLiteDatabase db = getReadableDatabase();
return DatabaseUtils.queryNumEntries(db, YOURTABLE_NAME);
}
}
Your Activity
Calling Database class from your activity
YourDatabase db = new YourDatabase(this);
long numberofrecords = db.yourTableCount();
if(numberofrecords == 0)
{
//Insert your data in to database
//This will happen only in first launch because after that the numberofrecords == total number of records inserted in the database.
}
You can create the database manually using a database manager. Once you have the database defined in your assets folder it will remain there and be compressed within the apk file on build. Try SQLiteManager which has a free trial version that will let you design you database. Or use a firefox addon here: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/
I am experiencing some trouble with an SQLIte database in my Android application.
The issue is that the database is never updated, not even on multiple restarts of the emulator, of Eclipse or after deletion from DDMS.
This is my onCreate method, located in a class that extends SQLiteOpenHelper:
public void onCreate(SQLiteDatabase database) {
try {
database.execSQL(ESSENCE_TABLE_CREATE);
database.execSQL(PACCO_TABLE_CREATE);
database.execSQL(TAVOLE_TABLE_CREATE);
database.rawQuery("insert into essenza values(1, 'Rovere')",
null); // added later
} catch (SQLException e) {
Log.e("DB", e.getMessage());
}
}
After instantiating the helper, I request a reference to the database:
helper = new DBHelper(context, dbpath + "/" + DATABASE_NAME);
database = helper.getWritableDatabase();
It seems that the rawQuery statement (which was added at a later time) is not executed and that the database in use is instead cached from a previous version. I also tried to change the version of the database, but it did not work. Am I missing something? Thanks in advance.
You have two options:
Use DDMs to delete the database file from your device (look in /data/data/). This will force Android to run onCreate again.
In your constructor, increment the database version you pass to SQLiteOpenHelper. Add your raw query to onUpgrade.
You probably want option 1. Option 2 is better if you have users of your app whose databases you want to update.
I have an app that uses a database with 3 tables in it. Those 3 tables have data read from and written to them by activities and services.
Having gotten a few "android.database.sqlite.SQLiteException: database is locked" crashes, I went in to the database adapter class and wrapped every write, update, or delete function with a synchronized statement, so like:
public int deleteExpiredAlarms() {
String whereClause = FIELD_EXPIRED + " = 1";
int val = 0;
synchronized(dbWriteLock) {
val = db.delete(ALARM_DATABASE_TABLE, whereClause, null);
}
return val;
}
That seemed to make it better. But lately it's gotten bad again as I've added more services that read and write to different tables.
Do I need to synchronize ALL db access statements, including queries?
The exception is occurring on the attempt to open the writable database via the open helper...should I synchronize that act also?
I've heard that I should only be using one db helper so that there won't be issues with multiple threads accessing the db. How do I use only one db helper? Every example I've seen so far has the db helper as an instantiated value inside the db adapter....so wouldn't that be a separate db helper per db adapter instantiated (one in an activity, one in a service running,etc)
I've looked at using a content provider instead, as it's been claimed to solve problems like this, but it's really more work than I want to do if I should be able to have direct db access without locking issues. And I do not plan to make this db accessible to other apps.
Thanks for the help.
I have basically finished developing an android app that makes use of SQLite databases that I copy to the user data area on the device eg /data/data/com.company.app/databases/users.db
I am unsure how the marketplace app update procedure takes place and am also unsure as to how I could test it.
I currently check whether the database exists on the device and copy it if it doesn't (generally only occurs on first ever launch). What happens if I have a new version of the database in my updated app? Will an marketplace update wipe user data so that it will copy my new database in on next launch?
What happens in the future if I make database changes/add records/etc and package this with the new app? Will this database not overwrite the old database?
Otherwise, to avoid copying and overriding the databases from the app bundle on every launch is there a way to check the size and date of the database files and only copy if the database in the bundle is newer?
If anyone needs clarification please ask.
I am doing something similar. What I did is set the database version, and then when I check if the database exists, I also to make sure it's the correct version. If it's not, I save user favorites from the database, wipe and recopy my db, and then put back user favorites.
This is my on upgrade
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 2) {
System.out.println("Performing upgrade!");
openDataBase();
// save the old favorites
Cursor mCursor = getFavorites();
ArrayList<Stop> favs = allCursorToStops(mCursor);
mCursor.close();
deleteRecreate(db);
openDataBase();
for (int i = 0; i < favs.size(); i++)
setFavorite(favs.get(i));
close();
} else {
deleteRecreate(db);
}
}
Here is where I check existence/if need to upgrade etc
boolean dbExist = checkDataBase();
if(dbExist){
// check if we need to upgrade
openDataBase();
int cVersion = myDataBase.getVersion();
close();
if(cVersion != VERSION)
onUpgrade(myDataBase, myDataBase.getVersion(), VERSION);