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.
Related
The find on the db does not complete, so the FindCallback.done() method is never called, no errors, nothing, just is not called. this is the code
ParseQuery<ParseObject> pq = ParseQuery.getQuery("Category").setLimit(1);
pq.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
throw new RuntimeException();
}
});
I can see the prints before and after this portion of code, but the exception is never thrown. Please, I do really need help.
Edit: I use the parse-login before this point and it works correctly, even the saveInBackground() works correctly, the only problems I find are about queries, (find, getfirst ecc).
Resolved, I found out that the background features offered by Parse do not work if in your activity there are fragments, so you have to implement them yourself. The only strange fact is that in the beginning some function (such saveInBackground as I mentioned above) worked.
Check the ACL column in the parse object row, maybe you don't have permission to read.Double click on the ACL column and check the "public Read".
Thy this:
ParseQuery<ParseObject> pq = ParseQuery.getQuery("Category").setLimit(1);
pq.findInBackground(new FindCallback< ParseObject >() {
#Override
public void done(List< ParseObject > parseObjects, ParseException e) {
// Success
} else {
e.printStackTrace();
}
The pq.getFirstInBackground(new GetCallback<ParseObject>() is meant to return only one object, so you need to help it zero in on that object, for example a particular name or item.
Try adding pq.whereEqualTo("item", biscuit);.
If you want to return a list of objects you need to use a different callback.
End product should look like this.
ParseQuery<ParseObject> pq = ParseQuery.getQuery("Category").setLimit(1);
pq.whereEqualTo("item_key_here", "item_value_here");
pq.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
if(object != null){
//do stuff here
}
});
I have an interesting problem that I've never run into in programming before. I have an onClickListener that does a lot of username and password checks (makes sure the username is proper length, not taken, etc). I'm using MobDB, and I was using a conditional statement that would return a row if the username already existed. The problem is that the Listener skips the DB and goes to the final check that, if everything works, posts a new username and password to my DB. How can I make it wait for a response from the DB before skipping to the last check?
Here is the relevant code:
usernamecheck3 = true;
MobDB.getInstance().execute(APP_KEY, null, rd, null, false, new MobDBResponseListener() {
#Override public void mobDBSuccessResponse() {
usernamecheck3 = false;
Log.e("mobdbSuccess:", "success");
}
#Override public void mobDBResponse(Vector<HashMap<String, Object[]>> row) {
}
#Override public void mobDBResponse(String jsonObj) {
/*Log.e("mobdbSuccess:", "jsonObj");
Log.e("mobdbSuccess:", jsonObj);
JSONObject mainObject;
try {
mainObject = new JSONObject(jsonObj);
// need to parse the json object.
} catch (JSONException e1) {
e1.printStackTrace();
} */
}
#Override public void mobDBFileResponse(String fileName, byte[] fileData) {
//get file name with extension and file byte array
}
#Override public void mobDBErrorResponse(Integer errValue, String errMsg) {
usernamecheck3 = false;
Log.e("doesnt", "work");
}
});
if(usernamecheck3 == false){
Toast.makeText(getApplicationContext(), "Username is taken, please choose another", Toast.LENGTH_SHORT).show();
}
Basically the check always returns true, and then logcat will say mobdbSuccess: success, which should have set the Bool to false.
Thanks.
MobDBResponseListener is executing on a different thread. What happens here is that the processing is split, while a thread is doing the query, the main thread on which you added the listener, skips right ahead to the validation. Your best bet is to place the validation inside the MobDBResponseListener, on the mobDBResponse method.
Try to debug your code and calls, the Listener may be using an async task. If so, you may do anything you please from the response method, as it will be executing in the main thread again. Otherwise, you should look at solutions that handle threaded execution like Handlers
I have a problem with synchronizing results from AsyncTask when needed to check if input is vaild.
My application asks user to type in some promotion code into EditText. I want to label promotion code as valid if promotion code is in database. If promotion code entered is not in database, it is labeled as invalid.
This is code for button listener
// Listens for Add button presses
addButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String promo_code = (String) PromotCodeEditText.getText().toString();
// Start AsyncTask that will store true or false in checkCodeInDatabase variable
// depending if PromoCode is in database. We use checkCodeInDatabase in else if check below.
new CheckCodeDatabase().execute(promo_code);
// Check if Promo Code that user typed is in database
// checkCodeInDatabase is false if course is not in database
if (!checkCodeInDatabase) {
// Display No code in database alert dialog
showMsgDialog(getString(R.string.noCodeDBTitle),
getString(R.string.noCodeDBMessage));
courseCodeEditText.setText("");
} else {
// Add promo code user typed in EditText
addCode(promo_code);
}
}
});
My idea is that when user presses ADD button, to add promo code, I start AsyncTask which performs a query on database. AsyncTask stores true or false in static variable checkCodeInDatabase.
Here's code for AsyncTask:
private class CheckCodeDatabase extends AsyncTask<String, Object, Boolean> {
DataBaseHelper myDbHelper = new DataBaseHelper(MainActivity.this);
#Override
protected Boolean doInBackground(String... params)
{
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
} catch (SQLException sqle) {
throw sqle;
}
// This returns true or false if params[0], which is a promo code,
// is in in PromoCodes table in database.
return myDbHelper.checkCourseInDatabase(params[0]);
}
#Override
protected void onPostExecute(Boolean result) {
// Store true or false in checkCodeInDatabase which is a static variable.
// This variable will be used to check if code is valid in add button listener.
checkCodeInDatabase = result;
myDbHelper.close();
}
Problem:
Problem is that AsyncTask does not store value into checkCodeInDatabase variable on time. Meaning, if statement which is performed in add button listener, value of checkCodeInDatabase is the old value because AsyncTask does not have enough time to perform database query and update checkCodeInDatabase variable before if statement is executed in add button listener.
So, how to make add button listener wait for AsyncTask to update checkCodeInDatabase and then perform if check.
Thanks in advance!
p.s. I'm new to android development. I read in some book on Android development that any queries on database should be performed in AsyncTasks, to avoid unresponsive app. Maybe it's impossible to achieve what I want with AsyncTasks. Any suggestions are welcome.
You should delegate the whole
if (!checkCodeInDatabase) {
// Display No code in database alert dialog
showMsgDialog(getString(R.string.noCodeDBTitle),
getString(R.string.noCodeDBMessage));
courseCodeEditText.setText("");
} else {
// Add promo code user typed in EditText
addCode(promo_code);
}
block into you AsyncTask's onPostExecute.
Doing that you are sure that you have fetched the result AND that you are running on the ui thread.
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.
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