Responding to updates on SQLiteDatabase - android

I have an ImageButton that I want to use to set a boolean value for an item in an SQLiteDatabase.
The ImageButton will display one image for a value of "1", and another image for a value of "0". Pressing the image button should toggle the database field and therefore its image.
For some reason, when I press the button the value returned by the currentCursor.getInt() is still the same, despite the update method being called on the database. Do I have to update/refresh the cursor?
In my activity I have:
private void updateFavouriteButton(){
int favourite = currentCursor.getInt(currentCursor.getColumnIndex(Object.favourite));
if (favourite == 1)
{
favouriteButton.setImageDrawable(getResources().getDrawable(R.drawable.favourite_selected));
favouriteButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dbHelper.updateFavourite(selectedId, 0);
updateFavouriteButton();
}
});
}
else
{
favouriteButton.setImageDrawable(getResources().getDrawable(R.drawable.favourite));
favouriteButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dbHelper.updateFavourite(selectedId, 1);
updateFavouriteButton();
}
});
}
}
In my database helper I have:
public void updateFavourite(long rowId, int favourite)
{
db.beginTransaction();
try {
ContentValues args = new ContentValues();
args.put("ZFAVOURITE", favourite);
int rowsAffected = db.update("ZOBJECT", args,"_id" + "=" + rowId, null);
if (rowsAffected > 0)
db.setTransactionSuccessful();
} catch (Exception e) {
Log.e("Error in transaction", e.toString());
} finally {
db.endTransaction();
}
}

requery() is deprecated, the documentation says to just close the old cursor, remake it, and use the new one.
A cursor is a snapshot at the time its created. If the Database is changed, you must requery.

As #Pyrodante had said, it is needed to requery() the cursor in some ways since requery() is deprecated
Not sure how u guys solve it, here is how I solve this problem.
please let me know if there is a better way. thanks!
Cursor newCursor=CreateCursor(); //ChreateCursor() create a method which returns you a new cursor
mAdapter.changeCursor(newCursor); //Change to the new cursor so that the list will be updated

Related

I want to retrieve password from the database from the corresponding username but i am unable to do it

i basically want to use the query select password from Login_table where username ='this will be given by the user';
Cursor res =db.rawQuery("select password from Login_table where username ='"+x+"'",null);
i guess this is right but still getting a problem
android.database.CursorIndexOutOfBoundsException: Index -1 requested,
with a size of 2
public void checkData(){
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String user_name=usname.getText().toString();
Cursor res =mydb.getData(user_name);
if(res.getCount()==0){
Toast.makeText(MainActivity.this,"Login failed",Toast.LENGTH_SHORT);
}
String check=res.getString(2);
Toast.makeText(MainActivity.this,String.valueOf(check),Toast.LENGTH_SHORT).show();
String pass_Word=pass.getText().toString();
if(pass_Word.compareTo(check)==0){
Toast.makeText(MainActivity.this,"You are Loged IN",Toast.LENGTH_LONG).show();
}
else
Toast.makeTextenter code here(MainActivity.this,"You are Not Loged IN",Toast.LENGTH_SHORT).show();
}
});
}
i just want to retrieve the password and check with the users inputenter code here
The reason why you are getting the index out of bounds is that you are trying to read data from the position that is BEFORE THE FIRST ROW i.e. -1. You have to move to a row to read data from the row.
So before the line String check=res.getString(2); you need to move to a row, probably using the Cursor's moveToFirst method (although according to the message there are 2 rows returned, which is an issue you would probably want to address as it would appear that there are two rows for the same user and perhaps 2 different passwords).
As the moveToFirst method returns a boolean, true if the move could be made, else false, then there is no need to check to see if there are any rows as if there are not then moveToFirst will return false.
Although probably not currently an issue. You should also always close a Cursor when done with it.
As such you may wish to try using :-
public void checkData(){
final DBAssetHelper mydb;
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String user_name=usname.getText().toString();
Cursor res =mydb.getData(user_name);
if (res.moveToFirst()) { //<<<<<<<<<< try to move to a row
Toast.makeText(MainActivity.this,"Login failed", Toast.LENGTH_SHORT);
} else {
if (res.getString(2).equals(pass.getText().toString)) {
Toast.makeText(MainActivity.this,"You are Loged IN",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this,"You are Not Loged IN",Toast.LENGTH_SHORT).show();
}
}
res.close(); //<<<<<<<<<< Close the Cursor
}
});
}

Insert Method do not insert data neither throws an exception - Android SQLite

One of the methods of my app should set the data into its database.
The problem I'm facing is that the insert method (Provided by SQLite Android Class) does not insert any data at the end and it didn't throws an exception either.
Here is the method's code:
public void setGasto(int idRubrica, String estabelecimento, float valor){
SQLiteDatabase db2 = this.getWritableDatabase();
ContentValues values = new ContentValues(4);
values.put("DATA", System.currentTimeMillis());
values.put("VALOR",valor);
values.put("ESTABELECIMENTO", estabelecimento);
values.put("ID_RUBRICA",idRubrica);
db2.beginTransaction();
try{
db2.insertOrThrow("GASTOS",null,values);
} catch (Exception e){
System.out.println(e);
}
db2.endTransaction();
db2.close();
}
I got stuck with it.
Update.
I think that the problem resides in the way I'm calling it.
I call it from a Inner Method that is set to an Alert Dialog Builder.
public void dismiss(AlertDialog.Builder builder, final SQLiteDatabase db2){
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
db.setGasto(db2, idRubrica,estabelecimento,valor);
}
});
}
You need to call setTransactionSuccessful() before endTransaction() to commit the changes. Otherwise endTransaction() rolls back the changes.
The canonical pattern for transactions is as follows:
beginTransaction();
try {
db operations...
setTransactionSuccessful();
}
finally {
endTransaction();
}
This ensures the begin and end calls are always paired.

Usage CursorLoader without ContentProvider and avoiding database leaks

I have implemented the class found in this question:
CursorLoader usage without ContentProvider
It is a means of using the LoaderManager and CursorLoader without a content resolver. I am using it to load data from a SQLite database and display it in a ListFragment.
The problem I am seeing is that the database is leaking. Obviously this is because I am not closing the database when I am done.
I have now started to do this, but I am concerned as the database could be accessed at any time by background tasks scheduled with the AlarmManager. I am worried that I might close the database when another class needs it open.
My solution has been to count the opens/closes and only close the database when no one is using it. Like so:
public synchronized SQLiteDatabase openDataBase()
{
try
{
mDatabaseUsers++;
Log.d(TAG, "DatabaseUsers: " + mDatabaseUsers);
// If already open, return it.
if (mOpenDatabase != null && mOpenDatabase.isOpen())
return mOpenDatabase;
OpenHelper openHelper = new OpenHelper(mContext);
return openHelper.getWritableDatabase();
} catch (SQLException e)
{
Log.e("MessageDelay", "Error opening database: " + e.toString());
return null;
}
}
public synchronized void closeDatabase()
{
mDatabaseUsers--;
// If no one is using the database, close it.
if (mOpenDatabase != null && mDatabaseUsers == 0)
{
mOpenDatabase.close();
}
Log.d(TAG, "DatabaseUsers: " + mDatabaseUsers);
}
This appears to work, but it has meant adding an extra line of code all over my application. Furthermore I've had trouble with the LoaderManager not behaving as expected and it calls its reset function more than it does its load, so I've had to put this fix in:
return new SimpleCursorLoader(getActivity())
{
private int mDBOpens = 0;
#Override
public Cursor loadInBackground()
{
mDBOpens++;
return JSQLite.getSingleton(getActivity()).retrieveTextsSent(mMode == 1 ? true : false);
}
#Override
public void reset()
{
if (mDBOpens > 0)
{
JSQLite.getSingleton(getContext()).closeDatabase();
}
super.reset();
mDBOpens--;
}
};
It feels like this isn't the correct way of doing it. Is there another, cleaner means of closing/opening the database only when needed?
Thanks, Jason.

Check box refresh not working when Activity not reloaded - Android

I have created an activity that refresh quotes when the user clicks a button. Within the same activity there is a check box which the users can click if they like the quote.
Everything works perfectly apart from the check box. When the user clicks they like the quote, I want that check box checked. This only happens when the user moves away from the activity and returns at a later stage.
However when the user stays within the activity and returns to the quote, the old state is shown instead of the users preference.
The check box is configured from the values even in the database, if the value is 1, the check box should be ticked, if not, check box should be clear.
The code is shown below:
When the user clicks the next button, the following code is executed:
Button nextGenerateButton = (Button) findViewById(R.id.btn_next_quotes);
nextGenerateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String nextQuote = myDbHelper.getnextQuote();
setQuoteDisplay(nextQuote);
btn_favorite.setChecked(myDbHelper.getFavouriteCheckBoxValue());
}
});
The button retrieves the next quote and the getFavouriteCheckBoxValue() confirms whether the favourite column is marked in the database and either returns a true of false which sets the check box value.
public boolean getFavouriteCheckBoxValue()
{
int laballedFavourite = cursor.getInt(0);
if(laballedFavourite == 0)
{
return false;
}
else
{
return true;
}
}
if the user likes the quote, the code executes the addFavourite() which updates the table where the favourite column will be modified on one.
btn_favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked == true)
{
myDbHelper.addFavourite();
}
if(isChecked == false)
{
myDbHelper.removeFavourite();
}
}
});
public void addFavourite()
{
ContentValues vals = new ContentValues();
vals.put("favouriteQuote", 1);
db.update(TABLE_NAME, vals, "columnId = " + cursor.getInt(1), null);
}
Again this only works perfectly when I resume the quote activity and not when I am currently live in the quote activity.
Hope this makes sense.
Any help would be greatly appreciated.
You need to refresh your checkbox to see the changement because you made a changement in you db but not on the UI. You need to observe the db and refresh the checkbox after a modification.
Refreshing cursor solved the problem.

Cursor out of bounds exception

I am fetching data from cursor. Using this cursor i am populating the text for my radio button. While displaying the activity it works fine but when i try to select the radio button, i again try to access my cursor and at that time i get the cursor out of bounds exception. Please help me out.
Cursor cur=db.getForcemodLevelForMenuitem(mnuItmID);
cur.moveToFirst();
while (cur.isAfterLast() == false) {
cnt=1;
//Level 1
if(cur.getInt(0)==1)
{
LinearLayout level1Layout=(LinearLayout)findViewById(R.id.level1Layout);
level1Layout.setVisibility(View.VISIBLE);
//ArrayList menuitemForcemodMapsLevel1=db.GetBaseObjectListFromDBWhere("MenuitemForcemodMapping", "MenuitemID= "+mnuItmID+ " and Level="+1);
menuitemForcemodMapsLevel1=db.getForcemodDetailsForMenuitem(mnuItmID,1);
RadioGroup level1_rg=(RadioGroup) findViewById(R.id.level1_rg);
RadioButton[] rblevel1=new RadioButton[menuitemForcemodMapsLevel1.getCount()];
menuitemForcemodMapsLevel1.moveToFirst();
int i=0;
while (menuitemForcemodMapsLevel1.isAfterLast() == false) {
rblevel1[i] =new RadioButton(AddPopupMenuItem.this);
rblevel1[i].setText(menuitemForcemodMapsLevel1.getString(1).substring(0));
rblevel1[i].setTextColor(R.color.black);
level1_rg.addView(rblevel1[i]);
rblevel1[i].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
menuitemForcemodMapsLevel1.moveToPosition(i);
forceModNameList.add(menuitemForcemodMapsLevel1.getString(1).substring(0));
}
});
i++;
menuitemForcemodMapsLevel1.moveToNext();
}
menuitemForcemodMapsLevel1.close();
rblevel1=null;
}
}
cur.moveToNext();
}
cur.close();
db.close();
}
}
I am getting error at this line
:forceModNameList.add(menuitemForcemodMapsLevel1.getString(1).substring(0));
Thanks ,
Neha
You already retreive the 1st element at :
rblevel1[i].setText(menuitemForcemodMapsLevel1.getString(1).substring(0));
so the cursor is moved ahead. And then you are asking again the same thing to retrieve. Cursor can't move backwards, it moves only forward by default. So you are getting this error.
Why don't you save the value in a String and can thus use again without the need of retreiving it again.
I beleive this will simplify your code and also solve the problem. Try out.
please use this, i think it will solve your issue
Cursor c;
if(c.moveToFirst())
{
do
{
// perform operation in this blocks
}while(c.moveToNext());
}

Categories

Resources