Android - How to populate Content Provider only once on App install? - android

I have a database in my application that is used as a ContentProvider.
It holds settings values for the application, and when I install the application I
want it to add a hardcoded set of values just once.
This is how I am trying to do it at the minute.
if(settings.size()<= 0){
Settings s = new Settings("voipusernameTa", "xxxxxxxxx", "xxxxx",
"displayNameTa", "sip.networks.com", "sip.networks.com", "siprealmTa", 120);
addNewSettings(s);
}
And this is the addNewSettings method:
private void addNewSettings(Settings _settings) {
ContentResolver cr = getContentResolver();
String w = CiceroSettings._ID + " = " + _settings.get_Id();
Log.d("ADDNEW SETTINGS", "new setting id =" + _settings.get_Id());
Cursor c = cr.query(CiceroSettings.CONTENT_URI, null, w, null, null);
Log.d("CURSOR", "cursor created");
int dbCount = c.getCount();
c.close();
if (dbCount == 0){
ContentValues values = new ContentValues();
values.put(Settings._ID, _settings.get_Id());
values.put(Settings.VOIPUSERNAME, _settings.getVoipUserName());
values.put(Settings.VOIPAUTHID, _settings.getVoipAuthId());
values.put(Settings.PASSWORD, _settings.getPassword());
values.put(Settings.VOIPDISPLAYNAME, _settings.getVoipDisplayName());
values.put(Settings.SIPPROXYSERVER, _settings.getSipProxyServer());
values.put(Settings.SIPREGISTRAR, _settings.getSipRegistrar());
values.put(Settings.SIPREALM, _settings.getSipRealm());
values.put(Settings.EXPIRESTIME, Integer.toString(_settings.getExpiresTime()));
Log.d("CURSOR", "Values assigned");
cr.insert(CiceroSettings.CONTENT_URI, values);
Log.d("CURSOR", "Values inserted");
}
}
}
This works however each time the app starts it adds a new settings object and I only want it to app ONE object at the install of the application and thats it no more.
Has anyone a better solution for this? Or a reason why my code is flawed?

If you want to add default values to your SQL table, I think the best way would be to set them right after creating your table.
So if you are using SQLiteOpenHelper, in the onCreate method, you can call db.insert() right after creating your table so that those values will be created just once

Related

sql always return the same data

In my project, I use SQL (SQLite since its android) to save my data.
I encountered some odd problem:
In my application, I have three tabs and in order to know which data belong to which tab I have in my chart a column for each tab. the number in the column (Integer) represent if and how many of that data suppose to be in this tab.
So, when the tab initialized, it reads from the chart, and using the relevant column, it can tell which data needs to be read and how many.
When I retrieve data from the server (the database of the server is not related to the problem at hand), I check if the data is new or that I already have a similar one in my SQL DB. If its new, I add it to the SQL chart and put 1 in the relevant column. If it already exists, it checks if the data in the SQL is updated (it update the data if necessary) and add 1 to the relevant column (the same column it puts 1 in it in case the data is not in the SQL DB).
now here's my problem:
when it reads from the SQL DB to see the number in the column, so it can add 1 to it and then update the chart, it always return 1 regardless the actual number that in the column in that moment (I know its not really 1 because when I read from the DB in the same column from other places in my app it does read the actual number).
Since in other places in my app it doesn't happen I tried to see what is the difference between the places but I did not find anything wrong (the only difference is that I used WritableDatabase instead of just ReadableDatabase in that time but that should not be an issue as far as I know, at least not in such case).
the code where the problem occurs (the problem is with COL_CART):
writable = db.getWritableDatabase();
Cursor cursor = writable.query(
ShopContract.ShopChart.TABLE_NAME,
new String[]{ShopContract.ShopChart.COL_NAME, ShopContract.ShopChart.COL_PRICE, ShopContract.ShopChart.COL_PIC, ShopContract.ShopChart.COL_CART},
ShopContract.ShopChart.COL_PROD_ID + " = '" + product.getProd_id() +"'",
null,
null,
null,
null
);
if(cursor.moveToFirst()){
//check if the data match, if not, replace.
if(!cursor.getString(cursor.getColumnIndex(ShopContract.ShopChart.COL_NAME)).equals(product.getName())){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_NAME,product.getName());
update(values);
}
if(cursor.getDouble(cursor.getColumnIndex(ShopContract.ShopChart.COL_PRICE)) != product.getPrice()){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_PRICE,product.getPrice());
update(values);
}
if(!cursor.getString(cursor.getColumnIndex(ShopContract.ShopChart.COL_PIC)).equals(product.getPicture())){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_PIC,product.getPicture());
update(values);
}
//check how many there are already in cart (already in the cursor) and update it to be ++
Log.d(TAG, "run: the number in col_cart is: " + cursor.getInt(cursor.getColumnIndex(ShopContract.ShopChart.COL_CART)));
int inCart = cursor.getInt(cursor.getColumnIndex(ShopContract.ShopChart.COL_CART)) + 1; // because of the new product we just added
Log.d(TAG, "run: inCart = " + inCart);
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_CART,inCart);
Log.d(TAG, "run: change cart");
update(values);
edit:
here is the update method code (the writable is being initialized in the code above):
private SQLiteDatabase writable;
private void update(ContentValues values){
writable.update(ShopContract.ShopChart.TABLE_NAME, values, ShopContract.ShopChart.COL_PROD_ID + " = '" + product.getProd_id() +"'",null);
}

Android SQLite Incrementing Integer Field Read from Query

Disclosure up front, this is a school project.
I have a method in a class that manages the database for a "quzzer" feature in my app, it is intended to increment (or decrement in one case) three integer fields in an SQLite database. It needs to do this independently from the "quizzing functions", so I need to pull the data first, change it, then update it into the database.
The fields are as follows in the database:
"prof_level" - Only acceptable values are 1 to 4 inclusive.
"times_correct" - Only positive numbers.
"times_incorrect" - Only positive numbers.
I can pull the numbers fine from the db then increment them by 1, but when I update, they increment the values in the db by 2 instead, and I've no idea why. Here is the full code of the method:
public void updateCharacterProf(String table, String charToUpdate, boolean isIncreased){
//get character from table
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(table);
String[] projection = {"prof_level", "times_correct", "times_incorrect"};
Cursor c = qb.query(db, projection, "character=='" + charToUpdate + "'", null, null, null,
null, null);
c.moveToFirst();
//check to see if the prof level is at max/min
int profLevel = c.getInt(0);
int correctTimes = c.getInt(1);
int incorrectTimes = c.getInt(2);
//mod prof levels
if (isIncreased){
profLevel++;
correctTimes++;
}
else{
profLevel--;
incorrectTimes++;
}
if (profLevel == 4 && isIncreased){
profLevel = 4;
}
else if (profLevel == 1 && !isIncreased){
profLevel = 1;
}
c.close();
ContentValues values = new ContentValues();
values.put("prof_level", profLevel);
values.put("times_correct", correctTimes);
values.put("times_incorrect", incorrectTimes);
//update db
db.update(table, values, "character=='" + charToUpdate + "'", null);
db.close();
}
I'm hoping that it's just something I don't get about how updating SQLite dbs, but I'm lost at the "var++ == +=2" thing that I'm getting now.
I discovered that the issue was o e of my own creation, I fired the callback that calls this database update twice accidently in the dialog fragment that calls it (once in an onClick method and once in a life cycle onDismiss override.).
Fixing this bug, which happened during another different dateabase related thing, fixed the problem for me.

I can't get data from database using cursor

I have make following function for getting data.
public List<Presentation> getSlideMaster() {
List<Presentation> pptList = new ArrayList<Presentation>();
String selectQuery = "SELECT * FROM "
+ Constants.SLIDE_MASTER.slideMaster_Table + " WHERE dm_Id=" + lastDeckID;
SQLiteDatabase db = dbhelper.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
Presentation presentation = new Presentation();
presentation.setSlideId(cursor.getString(0));
getSlideID = presentation.getSlideId();
Log.i("string slide id in database helper", "" + presentation.getSlideId());
pptList.add(presentation);
} while (cursor.moveToNext());
}
String selectQuery2 = "SELECT sl_Id FROM "
+ Constants.SLIDE_LAYOUT.slideLayout_Table + " WHERE sm_Id = "
+ getSlideID;
Cursor cursorSL = db.rawQuery(selectQuery2, null);
Log.i("query", ""+selectQuery2);
if(cursorSL.moveToFirst()){
Log.i("getslideLayout function", "");
do{
Log.i("query string 0 ", ""+cursorSL.getString(0));
Presentation presentation = new Presentation();
presentation.setSlideLayoutId(cursorSL.getString(0));
getSlideLayoutId = presentation.getSlideLayoutId();
Log.i("string slide layout id in slideMaster", "" + getSlideLayoutId);
}while(cursorSL.moveToNext());
}
else{
Log.i("No Data Found!!!!!", "");
}
cursor.close();
cursorSL.close();
db.close();
return pptList;
}
I getting data from slideMaster_Table very fine and easily but I can't get data from another query, which is not print any value in Logcat inside of if(cursorSL.moveToFirst()) condition
When I use code in another activity i can get sl_Id very easily.
may below solution solve your problem
use Cursor cursorSL = db.rawQuery(selectQuery2, new String[]{getSlideID});
for
selectQuery2="SELECT sl_Id FROM "+Constants.SLIDE_LAYOUT.slideLayout_Table + " WHERE sm_Id = ?";
My speculation is that you have troubles constructing the second query. Basically it is never a good idea to construct database queries like you do. The android database API is providing more accurate interface for that. Rewrite your second part of program to:
String [] selectArgs = {getSlideID};
String selectQuery2 = "sm_Id = ?";
Cursor cursorSL = db.query(Constants.SLIDE_LAYOUT.slideLayout_Table, null,
selectQuery2, selectArgs, null, null, null, null);
Note that the fourth parameter of query is meant for substitution of where arguments, it is String[] and all the array members are substituted in sequence in the places of ? in the query string.
I think you might be facing problem with constructing the query.
PS: You are also misusing the log tags:
Log.i("No Data Found!!!!!", "");
Should actually be Log.i("TAG", "No Data Found!!!!!");
The first parameter is log tag and is supposed to be used for grouping related log messages, in your case you print every message in its own group, which does not make much sense.
I know this note will not solve your immediate problem, but I am pointing it out, so that you will know it for the future (I also suffer from seeing colleagues of mine learning from SO wrong practises like that one).

How to update the table values

I have the table(shown in fig). I want to update the time column. I have the medicine_id(second column) how to update the different times depend upon the same medicine_id(second column).
Also, I have four rows in my DB when I updated time it should be two row means, I want to remove the other two rows with the particular medicine_id..
I have the following code for update:
if(mon) {
for (int i = 0; i < dosage_per_day; i++) {
mMedicineDbHelper.updateMedicines(new
MedicineTime(row_id, time_InMillies[i]));
}
}
My DB code:
public void updateMedicines(MedicineTime medicineTime) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ID, medicineTime.getId());
values.put(MEDICINEID, medicineTime.getMedicine_id());
values.put(TIME, medicineTime.getTime_in_millis());
db.update(TABLENAME, values, MEDICINEID + " = ?",
new String[]{String.valueOf(medicineTime.getMedicine_id())});
db.close();
}
It shows exception..
anybody help to solve this...
For the original question asked you're executing the following code:
db.update(TABLENAME, values, MEDICINEID + " = ?",
new String[]{String.valueOf(medicineTime.getMedicine_id())});
For some reason on Android, converting numeric values to Strings and using them for selection args never works properly. See: Android Sqlite selection args[] with int values. The best way to do this is the following:
db.update(TABLENAME, values, MEDICINEID + " = " + medicineTime.getMedicine_id(), null);

Updating a single column is creating sqlite syntax error

I'm not sure what I'm doing wrong, but I'm trying to update a single integer value in a column of a table to 1 from 0. When creating the database, I set all values of the column to zero using:
for (int i = 0; i < setups.length; i++) {
ContentValues values = new ContentValues();
values.put(JokeDbContract.TblJoke.COLUMN_NAME_SETUP, setups[i]);
values.put(JokeDbContract.TblJoke.COLUMN_NAME_PUNCHLINE, punchlines[i]);
values.put(JokeDbContract.TblJoke.COLUMN_NAME_USED, 0);
db.insert(JokeDbContract.TblJoke.TABLE_NAME, null, values);
}
Then, in the actual activity, I'm doing:
private void findNewJoke() {
JokeDb jokeDb = JokeDb.getInstance(this);
SQLiteDatabase theDb = jokeDb.getDB();
String selection = JokeDbContract.TblJoke.COLUMN_NAME_USED + "=" + 0;
// Query database for a joke that has not been used, update the fields
// theJoke and thePunchline appropriately
String[] columns = {JokeDbContract.TblJoke._ID,
JokeDbContract.TblJoke.COLUMN_NAME_PUNCHLINE,
JokeDbContract.TblJoke.COLUMN_NAME_SETUP,
JokeDbContract.TblJoke.COLUMN_NAME_USED};
Cursor c = theDb.query(JokeDbContract.TblJoke.TABLE_NAME, columns, selection,
null, null, null, null);
if (c.moveToFirst() == false) {
Toast.makeText(this, R.string.error_retrieving_joke, Toast.LENGTH_LONG).show();
Log.e(getString(R.string.app_name),"No jokes retreived from DB in JokeActivity.findNewJoke()!");
}
else {
ContentValues values = new ContentValues();
theSetup = c.getString(c.getColumnIndexOrThrow(JokeDbContract.TblJoke.COLUMN_NAME_SETUP));
thePunchline = c.getString(c.getColumnIndexOrThrow(JokeDbContract.TblJoke.COLUMN_NAME_PUNCHLINE));
String updateSelection = JokeDbContract.TblJoke.COLUMN_NAME_SETUP + "=" + theSetup;
values.put(JokeDbContract.TblJoke.COLUMN_NAME_USED, 1);
theDb.update(JokeDbContract.TblJoke.TABLE_NAME, values, updateSelection, null);
}
}
I'm getting an error on the update:
java.lang.RuntimeException: .... while compiling: UPDATE jokes SET used=?
WHERE setup=Why do programmers always mix up Halloween and Christmas?
It seems as though I'm not getting an actual value set for the used column. What the program ultimately does is cycle through jokes where used=0, then sets used to 1 when it has been viewed. So the query only pulls those jokes that aren't used yet. I have a feeling I'm missing something simple, one can hope.
I think you are having problems with quotation marks.
Example:
String updateSelection = JokeDbContract.TblJoke.COLUMN_NAME_SETUP + "=\"" + theSetup + "\"";
However, the recommended way to do this, would be:
theDb.update(JokeDbContract.TblJoke.TABLE_NAME, values, JokeDbContract.TblJoke.COLUMN_NAME_SETUP + " = ?", new String[] { theSetup });
It is better to use field = ?, because this helps sqlite cache queries (I believe).

Categories

Resources