SQLiteDatabase updates only when the application is reopened - android

I have an android app that successfully inserts data in my database when I click a marker in the map.
I have an activity that updates its info(column) in the database. It doesn't update on my first attempt but when I close, exit the app, run it again and update the info again, it successfully updates so I believe my code is right. What would the problem?
Process:
1st open
place marker
onInfoWindowClick starts new activityForResult
fill up fields
save (button)
return values to update a row
doesn't update
re-open
when an existing marker is clicked, fill up fields, it updates when saved
when a new marker is placed, fill up fields, doesn't update (means need to reopen again)
Call to update:
ContentValues cv = new ContentValues();
cv.put(LocationsDB.FIELD_TITLE, newReminder);
cv.put(LocationsDB.FIELD_MONTH, mm_final);
cv.put(LocationsDB.FIELD_DAY, dd_final);
cv.put(LocationsDB.FIELD_YEAR, yy_final);
getContentResolver().update(LocationsContentProvider.CONTENT_URI, cv, "lat=? AND lng=?", new String[] {location_lat, location_lng});
LocationContentProvider.java:
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs){
int count;
count = mLocationsDB.update(values, selection, selectionArgs);
return count;
}
LocationsDB.java:
public int update(ContentValues contentValues, String where, String[] whereArgs){
int cnt = mDB.update(DATABASE_TABLE, contentValues, where, whereArgs);
return cnt;
}

Most likely, your SQLite database has changed, but the ContentResolver does not know it. In your the update() method of your ContentProvider, add this line of code:
this.getContext().getContentResolver().notifyChange(uri, null);
This notifies the ContentResolver that a change has occurred. The resolver will then update an UI components that depend on the data.

Related

OnLoadFinished suddenly not called anymore after update

I have a fragment with a list of items, each item has an editable quantity. When I edit the quantity, the database is updated and I receive a new cursor in the fragment. This all works well, except when you update the quantity a number of times, the onLoadFinished method is not called anymore. This can happen after 5 updates or after 200 updates: I can't reproduce the bug on command. The update is executed in the database because when I close and open that screen, I can see the updated quantity. Nothing out of the ordinary happens in the code: onLoaderReset is not called, notifyChange gets called on the correct Uri in the contentprovider. Has anyone ever seen this issue?
When the quantity needs to get updated:
ContentValues cv = new ContentValues();
cv.put(CartTable.COLUMN_COUNT, quantity);
String selection = CartTable.COLUMN_ID + " = " + cartItemId;
contentResolver.update(CartContentProvider.CONTENT_URI, cv, selection, null);
The CartContentProvider:
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
{
int rowsUpdated;
switch (uriMatcher.match(uri))
{
case CART_ITEMS:
rowsUpdated = this.database.update(CartTable.TABLE_NAME, values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
if(rowsUpdated > 0)
{
this.getContext().getContentResolver().notifyChange(CONTENT_URI, null);
this.getContext().getContentResolver().notifyChange(CONTENT_URI_PRODUCTS, null);
this.getContext().getContentResolver().notifyChange(CONTENT_URI_PRODUCTS_PHOTOS, null);
this.getContext().getContentResolver().notifyChange(CONTENT_URI_PHOTOS, null);
}
return rowsUpdated;
}
When I create the CursorLoader:
return new CursorLoader(this.getView().getContext(), CartContentProvider.CONTENT_URI_PRODUCTS, projection, null, null, null);
So for example, I edit the quantity 20 times and 20 times onLoadFinished gets called with a new cursor. The 21st time and all times after that, the update happens but onLoadFinished is not called anymore.
When extra code is required, let me know!
Thanks in advance.
Try using the CursorLoader like this:
return new CursorLoader(this.getActivity(), CartContentProvider.CONTENT_URI_PRODUCTS, projection, null, null, null);
use the fragment's Activity context, Also check where are you implementing the LoaderCallbacks interface, in the activity or in the fragment?

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.

Unable to show updated values from Cursor when live updating SQLite database

I am fairly new to Android and trying to learn how things work module by module. Here's what I am trying to do:
Show a word with a favorite checkbox (image). If a user taps on it then the database is updated and a column in database table stores its value (1 for checked, 0 for unchecked). I am using a cursor to retrieve values of both the word and favorite checkbox. Tapping on the favorite image correctly updates the database without any problem.
The problem I am facing is:
Unless I exit the application and start it again, the cursor doesn't fetch the recent changes made to the database. To explain it further, when I navigate to the next/previous word (using a button at the bottom of screen) the values retrieved aren't the latest ones i.e it seems like the cursor still has the old database values and not the updated ones.
I did search through Google, StackOverflow to get a concrete solution but it seems like I am not using the right search terms. I know this has something to do with updating cursor and the fact that requery is depreciated but again I have lost direction.
[EDIT] Using the below mentioned method to get Cursor:
public Cursor getWords() {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String[] sqlSelect = {"_id", "word", "favourite"};
String sqlTables = "word_list";
qb.setTables(sqlTables);
Cursor c = qb.query(db, sqlSelect, null, null,
null, null, null);
c.moveToFirst();
return c;
}
This method is called when user taps on favorite image to update the database:
public void setFavWord(int markFav, int wordPos) {
SQLiteDatabase db = getWritableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
ContentValues values = new ContentValues();
values.put("favourite", markFav);
db.update("word_list", values, "_id = " + wordPos, null);
}
A cursor is not dynamic; it shows a snapshot of the database at the time the query was executed.
When the database changes, you must execute the query again.
As suggested by #Sreekanth in comments section, I am updating the cursor whenever favorite image is tapped. Although it is working just fine but I think it as a workaround rather than a solution. Maybe I am wrong in saying so.

Will leaving a Cursor open cause later commands to fail?

I have an app with a SQLite database in it; after opening a Cursor to get some data with a query like:
SELECT * FROM table_name WHERE id=42;
is it necessary to close the cursor before running a command like this:
UPDATE table_name SET column = datetime('now') WHERE id=42;
that affects the rows in the open Cursor?
This should be easy enough to test yourself.
The UPDATE statement will run, but the data in your existing Cursor will be out-dated. The general rule is to close the Cursor when you are done with it and if you use Loaders existing Cursors should refresh when the source data changes.
No, you can open a cursor, execute some updates on the selected rows and close the cursor afterwards (before db.close()). Sample:
Cursor cursor = db.rawQuery("SELECT id, ...");
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getLong ("id");
ContentValues values = new ContentValues();
values.put("id", id +1000);
values.put("name", name);
db.update(DATABASE_TABLE, args, "id=" + id, null);
}
cursor.close();
Note: updates on selected tables will have no effect on the (values of the) opened cursor.

Sqlite open helper insert else update?

I want to insert data successfully
Here is my code:
public void insertData(String strTableName,
ArrayList<HashMap<String, String>> arrListproductdatabase) {
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
for (int i = 0; i < arrListproductdatabase.size(); i++) {
// cv.put(columnName, arrListOfRecord.get(i).get("name"));
cv.put(columnproductname,
arrListproductdatabase.get(i).get("product"));
cv.put(columnproductprice,
arrListproductdatabase.get(i).get("price"));
cv.put(columnproductquantity,
arrListproductdatabase.get(i).get("quantity"));
cv.put(columnproductid,
arrListproductdatabase.get(i).get("productID"));
cv.put(columnresturantID,
arrListproductdatabase.get(i).get("resturantID"));
db.insert(strTableName, null, cv);
}
I want that when I have to press add button again, that time it should check if the product is already inserted, and in that condition it should update and all.
I don't want to create any duplicate value.
Any help would be appreciated!
you can check for the distinct values in the db. please follow the link to have more details
android check duplicate values before inserting data into database
Set 'Product' field as unique key. So when duplicate value arrives from standard insert, it will simply return -1 and the error message will be swallowed.
You can control the behavior by using insertWithOnConflict (String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm) where you also specify a conflict algorithm that can be of values:
CONFLICT_ABORT
CONFLICT_FAIL
CONFLICT_IGNORE
CONFLICT_REPLACE
CONFLICT_ROLLBACK
Check out the reference for descrption of the conflict resolution types.
There is also an updateWithOnConflict
You can do that like this :
public boolean checkProduct(String product){
// shold open database here
Cursor mCursor =
db.query(true, DATABASE_TABLE, null, "product='" + product+"'", null, null, null, null, null);
if(mCursor != null){
mCursor.close();
// shold close database here
return true;
}
// shold close database first here also
return false;
}
Hope this helped you.

Categories

Resources