SQLite Update Not Applying Android - android

When I click on a ListItem, it opens up a custom dialog with 4 EditText fields. The fields are set with current data depending on the row that is clicked. The purpose of the dialog is to allow the user to update the data (it is a financial app). I am having trouble actually applying the update when the user clicks "submit" in the dialog. There are no errors in the app when I run. Here is the onclick method:
protected void onListItemClick(ListView l, View v, int position, long id) {
List<Debt> values = datasource.getAllDebt();
Debt item = values.get(position);
final long boxId = item.getId();
// final String BoxId = String.valueOf(boxId);
final String BoxName = item.getName();
final String BoxBalance = item.getBalance();
final String BoxApr = item.getApr();
final String BoxPayment = item.getPayment();
// set up dialog
final Dialog dialog = new Dialog(manageDebts.this);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Edit Debt Details");
dialog.setCancelable(true);
// set up text
EditText et1 = (EditText) dialog.findViewById(R.id.editText1);
EditText et2 = (EditText) dialog.findViewById(R.id.editText2);
EditText et3 = (EditText) dialog.findViewById(R.id.editText3);
EditText et4 = (EditText) dialog.findViewById(R.id.editText4);
et1.setText(BoxName);
et2.setText(BoxBalance);
et3.setText(BoxApr);
et4.setText(BoxPayment);
// set up button
Button button = (Button) dialog.findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
datasource.updateDebt(boxId, BoxName, BoxBalance, BoxApr,
BoxPayment);
dialog.dismiss();
}
});
dialog.show();
}
The Update Method in my Database helper class is shown here:
public boolean updateDebt(long updateId, String debt_name, String debt_total, String apr, String payment)
{
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_ID, updateId);
values.put(MySQLiteHelper.COLUMN_DEBT_NAME, debt_name);
values.put(MySQLiteHelper.COLUMN_DEBT_TOTAL, debt_total);
values.put(MySQLiteHelper.COLUMN_APR, apr);
values.put(MySQLiteHelper.COLUMN_PAYMENT, payment);
return database.update(MySQLiteHelper.TABLE_DEBT, values, MySQLiteHelper.COLUMN_ID + " = " + updateId, null) > 0;
}
I have verified that the COLUMN_ID and the updateId are pointing to the correct rows in the ListView and the SQL database.
Does someone see something I am not?

Perhaps you are violating a constraint with your update? Just a guess without seeing the DB code.
EDIT
Lose the single quotes around the row id variable, that is making the DB treat it as a string, and a string compared to a number is a fail.

This will work better:
String whereClause = MySQLiteHelper.COLUMN_ID + " = ?";
String[] whereArgs = new String[]{ String.valueOf(updateId) };
return database.update(MySQLiteHelper.TABLE_DEBT,
values, whereClause, whereArgs) > 0;
The String.valueOf() call simply converts the ID to a String value.

I test your code in my computer.
The update method works fine.
So I think you should post more code .
or You should check your logic.

I was missing a step between 2 and 3.
Setting the variable again, inside the onClick method. Once the user pressed the update button, the variable had to be RE-SET to the new value of the EditText field. Like this (simplified version):
String name = null;
EditText et;
name = debt.getName();
et.setText(name);
onclick {
***name = et.getText().toString();***
datasource.updateDebt(name);
}

Related

Do calculations on numbers in 1 multiline textView and return result replacing numbers

I am very new to android programming and am trying to complete my first app. It is a recipe converter.
I have stored my recipe details in a SQLite DB and the text for ingredients is just one multiline string separated by carriage returns. I have used a cursor to get the ingredient data into a textview which returns text like (could be numerous variants):
100ml Water
500 g Mince
2 x 400g can crushed tomatoes
etc.
I originally had each Qty, Unit and Ingredient Description stored separately in the database which made life easy when converting but I chose to store it in a multiline string to allow copying and pasting of ingredients from the internet or another source.
I am attempting to extract the numbers and then multiply them by a percentage, then return the new converted numbers, and the corresponding unit and description to get something like this:
(multiplied by 200%)
200ml Water
1000g Mince
4 x 400g can crushed tomatoes
I just don't know how to do it though. Can anyone help please?
Thanks
UPDATE:
I have tried to do something like this to get the numbers.
public void Split() {
TextView tvSplit = (TextView) findViewById(R.id.tvSplit);
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
String s = tvTest.getText().toString();
for (int i =0;i <= tvTest.getLineCount();i++){
tvSplit.setText("");
String text = s.replaceAll("\\D+", ",");
tvSplit.append(text);
tvSplit.append("\n");
}
That shows me all of the numbers with a "," between them but it also includes all numbers in the string like in the above example prior to conversion it would show 100,500,2,400 when I only need 100,500,2. Then from that point I'm not sure how I would convert them all. My "fresh to programming mind" thought that I could store these in a temp SQL table by INSERT INTO tablename (id, originalvalues) VALUES (my string ie 100,500,2).
I could then pull them back out, do the calculation, update the table, then add them back into my textview with the remaining string. I haven't got that far yet, so I'm just wondering what the correct way to do it is.
UPDATE 2:
As per my comments, this is the code I used to show an alert dialog with each item listed on a separate line, I then used the selected line to find the number before any " " to then display the text on the screen.
public void PopUpSpinnerDialogue() {
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
final TextView tv2 = (TextView) findViewById(R.id.tvTest2);
String s = tvTest.getText().toString();
final ArrayAdapter myAdapter = new ArrayAdapter<String>(this,
R.layout.my_dropdown_style, s.split("\n"));
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setTitle("Please choose the key ingredient you need to scale your recipe by.")
.setCancelable(false)
.setAdapter(myAdapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
String itemName = myAdapter.getItem(which).toString();
String[] parts = itemName.split(" ");
String itemNumStr = parts[0];
TextView tvLineName = (TextView) findViewById(R.id.tvIngredientSelect);
EditText et1 = (EditText) findViewById(R.id.etRecipeQtyConvert);
EditText et2 = (EditText) findViewById(R.id.etQtyHave);
tvLineName.setText(itemName);
String b4Space = itemNumStr.replaceAll("\\D+", "");
tv2.setText(b4Space);
et1.setText(b4Space);
et2.setText(b4Space);
calculateKeyIngredientPercent();
} catch (Exception e) {
Toast.makeText(SelectConvertMethod.this, "Your ingredient must have a QTY. eg. 100ml.", Toast.LENGTH_SHORT).show();
}
}
});
android.app.AlertDialog alert = builder.create();
alert.show();
}
It is this idea that I think I can use but I don't know how to code it and then display the results.
UPDATE 3:
The code or at least the idea of the code I am trying to use is this.
TextView tvSplit = (TextView) findViewById(R.id.tvSplit);
final TextView tvTest = (TextView) findViewById(R.id.tvTest);
String s = tvTest.getText().toString();
for (int i =0;i <= tvTest.getLineCount();i++){
String[] ingreds = s.split("\n");
tvSplit.setText("");
String[] parts = ingreds.split(" ");
String Qty = parts[0];
String Units = parts[1];
String Ingredients = parts[2];
Integer QtyInt = Integer.parseInt(Qty);}
ingreds.split doesn't work and also, I don't know how to specify splitting the parts for each i.
I ended up using regex. It allowed the data to be entered with or without a space. So I ended up using this code to pull out the Qty of each line, multiply it by a percentage, append the text (units,ingredient description) to the line, then add it to a string array, to add to my alert dialog.
Code is here.
public void Split() {
final TextView tv2 = (TextView) findViewById(R.id.tvTest2);
TextView tvTest = (TextView) findViewById(R.id.tvTest);
TextView tvPercent = (TextView) findViewById(R.id.tvPercent);
String tvP = tvPercent.getText().toString();
String tvNumOnly = tvP.replaceAll("\\D+", "");
Integer PercentVal = Integer.parseInt(tvNumOnly);
String s = tvTest.getText().toString();
StringBuilder sb = new StringBuilder();
Pattern p = Pattern.compile("((\\d*) ?(.*)(?:\\n*))");
Matcher m = p.matcher(s);
while (m.find()) {
String Qty = m.group(2) + ".00";
String Ingred = m.group(3);
Float QtyFloat = Float.parseFloat(Qty);
Float newQTY = (QtyFloat * PercentVal) / 100;
String newQTYstr = newQTY.toString();
sb.append(newQTYstr + " " + Ingred + "\n");
}
String[] lines = sb.toString().split("\n");
String[] IngredArray = Arrays.copyOfRange(lines, 0, lines.length - 1);
final ArrayAdapter myAdapter = new ArrayAdapter<String>(this,
R.layout.my_dropdown_style, IngredArray);
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setTitle("Please choose the key ingredient you need to scale your recipe by.")
.setCancelable(false)
.setAdapter(myAdapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
String itemName = myAdapter.getItem(which).toString();
String[] parts = itemName.split(" ");
String itemNumStr = parts[0];
TextView tvLineName = (TextView) findViewById(R.id.tvIngredientSelect);
EditText et1 = (EditText) findViewById(R.id.etRecipeQtyConvert);
EditText et2 = (EditText) findViewById(R.id.etQtyHave);
tvLineName.setText(itemName);
String b4Space = itemNumStr.replaceAll("\\D.\\D+", "");
tv2.setText(b4Space);
et1.setText(b4Space);
et2.setText(b4Space);
calculateKeyIngredientPercent();
} catch (Exception e) {
Toast.makeText(SelectConvertMethod.this, "Your ingredient must have a QTY. eg. 100ml.", Toast.LENGTH_SHORT).show();
}
}
});
android.app.AlertDialog alert = builder.create();
alert.show();
// Toast.makeText(SelectConvertMethod.this, sb, Toast.LENGTH_LONG).show();
}

How to prompt user for text input in a loop?

I am writing an android app in that main activity starts and populates a list of contacts, and needs to prompt the user for today's rating of all the contacts(promptUserForInput) and immediately process received rating of all the contacts. I thought i can use a dialogue box that prompt for every contact and gets the rating from the user. But below code fails as the main thread is not waiting for the user to finish enter rating of all the users.
Here is my function which I am calling in the main activity in a do while loop for all the contact names. rating is a global variable.
double rating=0;
private synchronized void promptUserForInput(String firstName, String lastName) {
final String fname = firstName;
final String lName = lastName;
AlertDialog.Builder alert = new AlertDialog.Builder(this);
String custName = firstName + " " + lastName;
final EditText input = new EditText(this);
alert.setTitle(custName);
alert.setView(input);
Log.v("Diva: in promptUserForInput", "setting positive buton");
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
Editable res = input.getText();
if(res == null) {
Log.v("Diva..", "In positivebutton..befoer getting rating res is null");
}
rating = Double.valueOf(input.getText().toString());
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
rating=0;
}
});
alert.show();
}
My caller of this promptUserForInput() looks like below.
// get list of contacts in a cursor
Cursor cursor = ManageDataBaseActivity.queryDataBase(this,
ManageDataBaseActivity.CONTACT_INFO_TABLE);
if(cursor.getCount()>0) {
double totalRatingForStats=0;
cursor.moveToFirst();
do {
String[] colNames = cursor.getColumnNames();
Log.v("Diva Colum names = ", colNames[0] + " " + colNames[1] + " " + colNames[2] + " " + colNames[3]);
String firstName = cursor.getString(cursor.getColumnIndex("FirstName"));
Log.v("Diva ..:", firstName);
String lastName = cursor.getString(cursor.getColumnIndex("LastName"));
String key = ManageDataBaseActivity.getDbKey(firstName, lastName,
date, ManageDataBaseActivity.CUSTOMER_DATA_TABLE);
promptUserForInput(firstName, lastName);
double ratingReceived = rating;
totalRatingForStats = totalRatingForStats+ratingReceived;
// some more processing
ManageDataBaseActivity.insertValueToDB(ManageDataBaseActivity.
CONTACT_DATA_TABLE+" ", .....);
} while(cursor.moveToNext());
The short answer: Don't.
The long answer: You should never block the main thread of a GUI program while waiting for user input.
Instead you should provide a continue button, which fires a event which causes the program to continue. There are several ways to accomplish this, the one that comes to mind first is signals and semaphores.
I'm not that well versed in Android programming - but there should be something similar in the API, perhaps dependent on Intents.
Looping in the main thread of an Activity is generally not a very good idea. But you could implement something like a pollNext() method that gets the next dataset from the cursor and change your click-methods to this:
#Override
public void onClick(DialogInterface dialog, int which) {
// do your rating stuff
// reads the next dataset
pollNext();
// shows the next dialog
// of course, firstName and lastName must be membervariables to make this work
promptUserForInput(firstName, lastName);
}
The idea behind that is very common and also used in the MVC-pattern

Editing the content of database in android

I have a edit tab in my app where the user can edit his details given during the time of registration .Inside the edit activity i have a save button which when clicked it saves the
data or update the datas into the database.
CODE
public void onSave(View btn)
{
EditText edtName = (EditText) findViewById(R.id.edtNameED);
EditText edtPass = (EditText) findViewById(R.id.edtPassED);
EditText edtEmail = (EditText) findViewById(R.id.edtEmailED);
EditText edtPh = (EditText) findViewById(R.id.edtPhED);
int id=0;
String where = DataBase_Server.C_ID+"=?";
String[] whereArgs = {id+""};
DataBase_Server database=new DataBase_Server(Edit.this);
SQLiteDatabase db=database.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(DataBase_Server.MOBILE_NO, edtPh.getText().toString());
values.put(DataBase_Server.PASS, edtPass.getText().toString());
values.put(DataBase_Server.EMAIL, edtEmail.getText().toString());
for(int i=0;i<edtName.length();i++)
{
id+=(int)edtName.getText().toString().charAt(i);
}
Toast.makeText(this,id+" hello", Toast.LENGTH_LONG).show();
try
{
db.update(DataBase_Server.TABLE, values,where,whereArgs);
}catch(Exception e){}
Toast.makeText(this,"UPDATE SUCESSFULL !!", Toast.LENGTH_LONG).show();
db.close();
database.close();
}
The code is giving not a single error but it is not even updating anything in the database. The database is not changed at all even after the user edit his details.
You are adding up the values of all the characters in the name:
for(int i=0;i<edtName.length();i++)
id+=(int)edtName.getText().toString().charAt(i);
This is unlikely to be your real ID value. With no record matching the WHERE condition, the update will do nothing, silently.
You must remember the ID value from when you loaded the data, because the name may have changed.

Looping code through database records

I have a database with some records in and i have the code i wish to execute on each row but I'm having trouble creating a suitable loop, ive been trying while(movetonext) but it hasnt been working.
cursor = getAppts();
cursor.moveToNext();
String titlefromdb = cursor.getString(3);
if (strTitle.equals(titlefromdb) && cursor.getString(1).equals(dateselforap))
{
// matching code update box
final Dialog matchdiag = new Dialog(CW2Organisor.this);
matchdiag.setContentView(R.layout.apptmatch);
matchdiag.setTitle("View/Edit Appointment");
matchdiag.setCancelable(true);
TextView matchtxt = (TextView) matchdiag.findViewById(R.id.matchtxt);
matchtxt.setText("Appointment \"" + titlefromdb + "\" already exists, please choose a different event title");
Button btnmatchok = (Button) matchdiag.findViewById(R.id.btnmatch);
btnmatchok.setOnClickListener(new OnClickListener() {
// on click for cancel button
#Override
public void onClick(View v) {
matchdiag.dismiss();
}
});
matchdiag.show();
}
else
{
addAppt(strTime, strTitle, strDet);
dialog.dismiss();
}
What I would need is for each row of my database i would need the titlefromdb to hold the title field of the current row and the for the if statement to run and then move to the next row.
You could try
cursor.moveToFirst();
loop with some sort of check
cursor.moveToNext();
end loop
... and I would also try to qualify your "it's not working" statement. What's not working?

Passing correct Info to Dialog

I am looking at creating a Dialog with a bundle of data. This all work correctly.
I have a number of buttons when clicked opens the dialog with the data and can then be updated.
Trouble I am having is it does not matter which button I press the bundle is only the data for the last row. Any ideas on getting the correct data passed to the Dialog for each button.
I was thinking down the line of setting an id for each view as I pass through the loop but unsure how to call that back again
Code:
for (int i = 0; i < nameInfo.size(); i++) {
// creating the views
View viewItem = (View) inflater.inflate(R.layout.view_item, null);
nameView = (TextView) viewItem.findViewById(R.id.title);
nameView.setId(i);
value1View = (TextView) viewItem.findViewById(R.id.value1);
value1View.setId(i);
value2View = (TextView) viewItem.findViewById(R.id.value2);
value2View.setId(i);
updateButton = (Button) sightmarkView.findViewById(R.id.updatebutton);
updateButton.setId(i);
// Getting the values
nameValue = nameInfo.get(i).toString();
value1 = db.getvalue1('1', nameInfo.get(i).toString());
value2 = db.getvalue2('2', nameInfo.get(i).toString());
// update fields
nameView.setText(nameValue);
value1View.setText(String.valueOf(value1));
value2View.setText(String.valueOf(value2));
updateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int updateButtonId = updateButton.getId();
bundle = new Bundle();
bundle.putString("name", nameValue);
bundle.putFloat("value1", value1);
bundle.putFloat("value2", value2);
showDialog(SIGHTMARK_DIALOG_ID, bundle);
}
});
pMainlayout.addView(viewItem);
}
Thanks for your time
In each loop (from the for), you are redefining the values of nameValue, value1 and value2.
To fix the problem, just change your code to match this:
// Getting the values
final String nameValue = nameInfo.get(i).toString();
final String value1 = db.getvalue1('1', nameInfo.get(i).toString());
final String value2 = db.getvalue2('2', nameInfo.get(i).toString());

Categories

Resources