Android - adding validation to input fields - android

I am making an Android app that uses a sqlite database to store the app data, an activity class to edit / insert data, a DbHelper to manage the database creation and version, and a content provider which manages access to the database.
I have managed to get data to be queried, inserted, deleted and edited from the database. However, I'm not too sure on how to add visual feedback to the user. I've tried adding a Toast in place where I have put an IllegalArgumentException but the app will simply add the content to the database.
If I omit the Name, the app will trigger the defined IllegalArgumentException and then crash the application.
This is a snippet for the insert method in the content provider
#Override
public Uri insert(Uri uri, ContentValues contentValues) {
final int match = sUriMatcher.match(uri);
switch (match) {
case PATIENT:
return insertPatient(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
/**
* Insert a patient into the database with the given content values.
*/
private Uri insertPatient(Uri uri, ContentValues values) {
String name = values.getAsString(PatientEntry.COLUMN_PATIENT_NAME);
if (name == null || name.length()==0) {
//Toast.makeText(getContext(), "Patient requires a name", Toast.LENGTH_SHORT).show();
throw new IllegalArgumentException("Patient requires a name");
}
Integer weight = values.getAsInteger(PatientEntry.COLUMN_PATIENT_WEIGHT);
if (weight != null && weight < 0) {
throw new IllegalArgumentException("Patient requires valid weight");
}
SQLiteDatabase database = mDbHelper.getWritableDatabase();
long id = database.insert(PatientEntry.TABLE_NAME, null, values);
if (id == -1) {
Log.e(LOG_TAG, "Failed to insert row for " + uri);
return null;
}
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);
}
This is a snippet from the activity file
private void savePatient() {
String nameString = mNameEditText.getText().toString().trim();
String weightString = mWeightEditText.getText().toString().trim();
if (mCurrentPatientUri == null &&
TextUtils.isEmpty(nameString) && TextUtils.isEmpty(weightString) {
Toast.makeText(this, "Data was not saved", Toast.LENGTH_SHORT).show();
return;
}
ContentValues values = new ContentValues();
values.put(PatientEntry.COLUMN_PATIENT_NAME, nameString);
int weight = 0;
if (!TextUtils.isEmpty(weightString)) {
weight = Integer.parseInt(weightString);
}
values.put(PatientEntry.COLUMN_PATIENT_WEIGHT, weight);
// Determine if this is a new or existing Patient by checking if mCurrentPatientUri is null or not
if (mCurrentPatientUri == null) {
// This is a NEW patient
Uri newUri = getContentResolver().insert(PatientEntry.CONTENT_URI, values);
if (newUri == null) {
Toast.makeText(this, getString(R.string.editor_insert_patient_failed),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, getString(R.string.editor_insert_patient_successful),
Toast.LENGTH_SHORT).show();
}
} else {
// Otherwise this is an EXISTING patient
int rowsAffected = getContentResolver().update(mCurrentPatientUri, values, null, null);
if (rowsAffected == 0) {
Toast.makeText(this, getString(R.string.editor_update_patient_failed),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, getString(R.string.editor_update_patient_successful),
Toast.LENGTH_SHORT).show();
}
}
}
Could someone kindly lend a hand?
.................................................................
EDIT 1:
This is the menu in the activity which calls savePatient:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
case R.id.action_save:
savePatient();
finish();
return true;
case R.id.action_delete:
showDeleteConfirmationDialog();
return true;
case android.R.id.home:
if (!mPatientHasChanged) {
NavUtils.navigateUpFromSameTask(EditorActivity.this);
return true;
}
// Otherwise if there are unsaved changes, setup a dialog to warn the user.
DialogInterface.OnClickListener discardButtonClickListener =
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
NavUtils.navigateUpFromSameTask(EditorActivity.this);
}
};
showUnsavedChangesDialog(discardButtonClickListener);
return true;
}
return super.onOptionsItemSelected(item);
}

For visual feedback validations are to be done as early as possible.
For example before you call save patient on some user action just call validatePatient() which if fails save will not be called.
For Visual feedback you can have error texts below your fields that will become visible only if validation related to that field fails.

Related

Only one column of data inserted in the sqlite database

So I'm using multiple radiogroup and an EditText to insert the data into the database. The problem is that only one column of data is inserted and it is always the the collection_time column.
This is the coding to insert the data:
BtnNext1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(SelectPrintingDetails.this, Summary.class);
int selectedId = rgCP.getCheckedRadioButtonId();
if(selectedId != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId);
String rbCP = selectedRadioButton.getText().toString();
Boolean insertPD = db.insertcolor(rbCP);
if(insertPD == true)
{
intent.putExtra("Color", rbCP);
}
else
{
Toast.makeText(getApplicationContext(), "Data is not inserted",Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(getApplicationContext(), "Radiobutton is not selected",Toast.LENGTH_SHORT).show();
}
int selectedId1 = rgFP.getCheckedRadioButtonId();
if(selectedId1 != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId1);
String rbFP = selectedRadioButton.getText().toString();
Boolean insertPD1 = db.insertflip(rbFP);
if(insertPD1 == true)
{
intent.putExtra("Flip", rbFP);
}
else
{
Toast.makeText(getApplicationContext(), "Data is not inserted",Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(getApplicationContext(), "Radiobutton is not selected",Toast.LENGTH_SHORT).show();
}
int selectedId2 = rgPC.getCheckedRadioButtonId();
if(selectedId1 != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId2);
String rbPC = selectedRadioButton.getText().toString();
Boolean insertPD2 = db.insertpc(rbPC);
if(insertPD2 == true)
{
intent.putExtra("Plastic", rbPC);
}
else
{
Toast.makeText(getApplicationContext(), "Data is not inserted",Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(getApplicationContext(), "Radiobutton is not selected",Toast.LENGTH_SHORT).show();
}
int selectedId3 = rgBind.getCheckedRadioButtonId();
if(selectedId1 != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId3);
String rbBind = selectedRadioButton.getText().toString();
Boolean insertPD3 = db.insertbind(rbBind);
if(insertPD3 == true)
{
intent.putExtra("Bind", rbBind);
}
else
{
Toast.makeText(getApplicationContext(), "Data is not inserted",Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(getApplicationContext(), "Radiobutton is not selected",Toast.LENGTH_SHORT).show();
}
String timecollect = etCT.getText().toString();
Boolean insertPD4 = db.insertct(timecollect);
if(insertPD4 == true)
{
intent.putExtra("Collect", timecollect);
}
else
{
Toast.makeText(getApplicationContext(), "Data is not inserted",Toast.LENGTH_SHORT).show();
}
startActivity(intent);
}
});
This is the databasehelper :
public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, "hdatabase1.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("Create table printingdetails (color text, binding text, collection_time text, flipped_page text, plastic_cover text)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("drop table if exists printingdetails");
}
public boolean insertcolor(String color)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("color", color);
long ins = db.insert("printingdetails", null, contentValues);
if(ins==-1) return false;
else return true;
}
public boolean insertflip(String flipped_page)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("flipped_page", flipped_page);
long ins = db.insert("printingdetails", null, contentValues);
if(ins==-1) return false;
else return true;
}
public boolean insertpc(String plastic_cover)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("plastic_cover", plastic_cover);
long ins = db.insert("printingdetails", null, contentValues);
if(ins==-1) return false;
else return true;
}
public boolean insertbind(String binding)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("binding", binding);
long ins = db.insert("printingdetails", null, contentValues);
if(ins==-1) return false;
else return true;
}
public boolean insertct (String collection_time)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("collection_time", collection_time);
long ins = db.insert("printingdetails", null, contentValues);
if(ins==-1) return false;
else return true;
}
I hope you guys guide me how to insert all the data in every column. I'm still new and I had already refer to several related post here and none of it really helping
Currently you seem to be inserting the value of each column separately. This means instead of a single row, you end up with multiple rows where only one column has a value and the rest are empty.
In order to fix this, you need a single method which is something like this:
public boolean insertRow(String color, String binding, String time, String flipped_page, String plastic_cover) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("color", color);
contentValues.put("binding", binding);
contentValues.put("collection_time", time);
contentValues.put("flipped_page", flipped_page);
contentValues.put("plastic_cover", plastic_cover);
long ins = db.insert("printingdetails", null, contentValues);
if(ins==-1) return false;
else return true;
}
Each individual insert command should be removed. Now, your onClick method will have to retrieve all the selected items and then call this insert method. Handling of unselected radio groups will depend on your application. In the sample below, I am simply interrupting the method, thus cancelling the submission. If some radio groups are optional, then you can set the corresponding strings to empty ("") and proceed with the method rather than cancelling the submission by returning.
public void onClick(View v) {
Intent intent = new Intent(SelectPrintingDetails.this, Summary.class);
String color, binding, time, page, cover;
int selectedId = rgCP.getCheckedRadioButtonId();
if(selectedId != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId);
color = selectedRadioButton.getText().toString();
}
else
{
Toast.makeText(getApplicationContext(), "Color is not selected",Toast.LENGTH_SHORT).show();
return; // this prevents the rest of the code from executing
}
int selectedId1 = rgFP.getCheckedRadioButtonId();
if(selectedId1 != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId1);
page = selectedRadioButton.getText().toString();
}
else
{
Toast.makeText(getApplicationContext(), "FlipPage is not selected",Toast.LENGTH_SHORT).show();
return;
}
int selectedId2 = rgPC.getCheckedRadioButtonId();
if(selectedId2 != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId2);
cover = selectedRadioButton.getText().toString();
}
else
{
Toast.makeText(getApplicationContext(), "Plastic Cover is not selected",Toast.LENGTH_SHORT).show();
return;
}
int selectedId3 = rgBind.getCheckedRadioButtonId();
if(selectedId3 != -1)
{
RadioButton selectedRadioButton = (RadioButton) findViewById(selectedId3);
binding = selectedRadioButton.getText().toString();
}
else
{
Toast.makeText(getApplicationContext(), "Binding is not selected",Toast.LENGTH_SHORT).show();
return;
}
time = etCT.getText().toString();
// since all attributed have been read, now we call insert
// you can read the returned boolean to determine if the insertion was successful
db.insertRow(color, binding, time, page, cover);
// Also add all of them as intent extras
intent.putExtra("Color", color);
intent.putExtra("Bind", binding);
intent.putExtra("Collect", time);
intent.putExtra("Flip", page);
intent.putExtra("Plastic", cover);
startActivity(intent);
}
I hope this helps you understand where you were going wrong, and how you can take this forward.

How do I use one button to swap between adding and deleting data from an sqlite database?

I have an sqlite database that collects data from the user and can delete it as well.
Here is it being created:
db.execSQL("CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, DATA TEXT UNIQUE) ");
Here's the code for the adding data and removing data
public boolean insertData(String data) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cValues = new ContentValues();
cValues.put(Col_2, data);
long result = db.insert(TABLE_NAME, null, cValues);
if (result == -1)
return false;
else
return true;
}
public boolean deleteData(String data){
SQLiteDatabase db = this.getWritableDatabase();
long result = db.delete(TABLE_NAME, "DATA = ?", new String[]{data});
ContentValues cValues = new ContentValues();
if (result == 0)
return false;
else
return true;
}
Here is the java button im trying to use
public void changeData(){
favBtn.setOnClickListener(
new View.OnClickListener(){
#Override
public void onClick(View v){
boolean isInserted = myDB.insertData(textView.getText().toString());
if(isInserted == true)
Toast.makeText(randomApp.this, "Added Data", Toast.LENGTH_LONG).show();
else
Toast.makeText(randomApp.this, "Data was deleted", Toast.LENGTH_LONG).show();
myDB.deleteData(textView.getText().toString());
}
}
);
}
The issue is that when this button is clicked it adds data but then will not remove said data. It will just continue playing the "added data" toast and add said data to the database- there is a unique constraint with the data
column but I'm not really sure what I'm doing wrong or missing as I understand it should not be added twice. It should remove the data if that is already added and vice versa.
According to your code the delete data code will always execute. And the data you are inserting will immediately deleted, hence the unique constraint won't break ever. You didn't put any {} in your else case and it contains two statements; first one considered as the statement inside else and second one will be considered as a statement outside the if and else case. So for fixing this issue you need to put {} properly. (Personal opinion : Try to put {} in if and else cases even if there is only one statement)
You should change that to:
if(isInserted == true)
{
Toast.makeText(randomApp.this, "Added Data", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(randomApp.this, "Data was deleted", Toast.LENGTH_LONG).show();
myDB.deleteData(textView.getText().toString());
}
You are calling myDB.insertData on every click first, for every insert it will return true, so isInserted will be true always, thats why do you add multiple times the same data. Try this:
private isInserted = false;
public void changeData(){
favBtn.setOnClickListener(
new View.OnClickListener(){
#Override
public void onClick(View v){
if(!isInserted){
Toast.makeText(randomApp.this, "Added Data", Toast.LENGTH_LONG).show();
myDB.insertData(textView.getText().toString());
}
else{
Toast.makeText(randomApp.this, "Data was deleted", Toast.LENGTH_LONG).show();
myDB.deleteData(textView.getText().toString());
}
isInserted = !isInserted;
}
}
);
}

Android sqlite check if table is empty

i'm working sqlite.i want to check if table is empty.i wrote some code but my code does not working perfect
this is a my DatabaseHelper code (function)
public boolean CheckGenderTableEmpty() {
boolean isEmpty = false;
String count = "SELECT * FROM Gender";
Cursor mcursor = db.rawQuery(count, null);
mcursor.moveToFirst();
if (mcursor.getCount() != 0) {
if (!mcursor.isClosed())
{
mcursor.close();
Log.e("is not empty", "is not empty");
isEmpty=true;
}
} else {
if (!mcursor.isClosed())
{
mcursor.close();
Log.e(" empty", "empty");
isEmpty=false;
}
}
return isEmpty;
}
as i said my code does not working perfect.first time my table is empty and i can't show log message about empty
and i call my function activity like this..
if(db_helper.CheckGenderTableEmpty()==true)
{
Toast.makeText(getApplicationContext(), "is not empty", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "empty", Toast.LENGTH_SHORT).show();
}
how i can check if database is empty in activity?
if anyone knows solution please help me
Use getCount() method of Cursor:
public boolean IsTableEmpty(Cursor cursor) {
return !(cursor.getCount() > 0);
}
The Android framework has a helper function for this in the DatabaseUtils class:
public boolean CheckGenderTableEmpty() {
return DatabaseUtils.queryNumEntries(db, "Gender") == 0;
}
you can go with something like
SQLiteDatabase db = table.getWritableDatabase();
String count = "SELECT count(*) FROM Gender";
Cursor mcursor = db.rawQuery(count, null);
mcursor.moveToFirst();
int icount = mcursor.getInt(0);
if(icount>0)
//do accordingly
else
//do accordingly
cursor.moveToFirst(); // Always one row returned.
Then check cursor.getInt (0) == 0
if(cursor.getInt (0) == 0) // Zero count means empty table.
Try this.

setting switch view state to checked based on database value android

i have just started learning android today, and so far i am going good, but getting an issue while changing the state of switch view dynamically. i have given a option in setting to check updates, so that user can on or off it as per their choice..
i am trying to set the state of switch view to checked or unchecked based on the last selected option of user which is stored in a database, the code is:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
sw = (Switch) findViewById(R.id.switchupdates);
taskkeeperdb = new DbHelper(this, "taskkeeper", null, 1);
db = taskkeeperdb.getReadableDatabase();
Cursor result = db.rawQuery("select * from tblsettings", null);
System.out.println("Cursore Created");
if (result != null) {
System.out.println("While Block");
while (result.moveToNext()) {
System.out.println("inside while block");
String name = result.getString(result.getColumnIndex("title"));
String value = result.getString(result.getColumnIndex("value"));
System.out.println("values are in variable");
switch (name) {
case "check_updates":
System.out.println("check updae case");
if (value == "YES") {
//sw.setText("Check for Updates: On");
sw.setChecked(true);
System.out.println("YESYESYESYESYESYESYESYESY");
} else {
//sw.setText("Check for Updates: Off");
sw.setChecked(false);
System.out.println("NONONONONONONONONON");
}
break;
default:
break;
}
}
System.out.println("ending the if block.....");
}
if (!result.isClosed()) {
result.close();
}
sw.setOnCheckedChangeListener(this);
}
updating table when user interact with the switch view toggle.....
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
db = taskkeeperdb.getWritableDatabase();
ContentValues cv = new ContentValues();
if (isChecked) {
cv.put("value", "YES");
db.update("tblsettings", cv, "title='check_updates'", null);
sw.setText("Check for Updates: On");
cv.clear();
} else {
cv.put("value", "NO");
db.update("tblsettings", cv, "title='check_updates'", null);
sw.setText("Check for Updates: Off");
cv.clear();
}
}
now when i open the setting view it does not reflect the changes..
and in my console the system.out.println only shows:
12-12 13:11:59.810: I/System.out(23320): Cursore Created
12-12 13:11:59.810: I/System.out(23320): While Block
12-12 13:11:59.820: I/System.out(23320): ending the if block.....
my DbHelper code:
public DbHelper(Context context, String databaseName,
CursorFactory factory, int version) {
super(context, DATABASE_NAME, null, 1);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table if not exists tblsettings (id integer primary key autoincrement, title text, value text);");
Cursor result = db.rawQuery("select * from tblsettings", null);
//when no rows then insert fresh rows..
if (result.getCount() == 0) {
ContentValues contentValues = new ContentValues();
contentValues.put("title", "check_updates");
contentValues.put("value", "NO");
db.insert("tblsettings", null, contentValues);
}
if (!result.isClosed()) {
result.close();
}
}
as i am new i am not able to understand what may be the real reason..
please help thanks in advance
thanks everyone, well i have solved the issue, the solution is just a minor mistake..
by changing the value comparison from == to value.toString().equals("YES") in the check_updates switch case i got what i was looking for.. the updated switch case is now:
switch (name) {
case "check_updates":
if (value.toString().equals("YES")) {
sw.setText("Check for Updates: On");
sw.setChecked(true);
} else {
sw.setText("Check for Updates: Off");
sw.setChecked(false);
}
break;
default:
break;
}

Check Db column data

I want my Onclick method that is used used to insert data into a database to first check if data exist. If there is data, a toast message appears. how can I accomplish this. My OnClick is below. I just it to verify there is a username and password. If there is, the user receives a toast.
#Override
public void onClick (View v) {
rUsername = rName.getText().toString();
rPasscode = rCode.getText().toString();
RegDetails regDetails = new RegDetails();
regDetails.setrName(bundleRegName);
regDetails.setpCode(bundleRegCode);
if(v.getId()==R.id.rtn_button){
finish();
}else if(v.getId()==R.id.reg_button){
insertCredentials(regDetails);
}
}
private void insertCredentials(RegDetails regDetails){
LoginDB androidOpenDBHelper = new LoginDB(this);
SQLiteDatabase sqliteDB = androidOpenDBHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(LoginDB.COLUMN_NAME_USERNAME, rUsername);
contentValues.put(LoginDB.COLUMN_NAME_PASSWORD, rPasscode);
long affectedColumnid = sqliteDB.insert(LoginDB.TABLE_NAME_CREDENTIALS, null, contentValues);
Toast.makeText(getApplicationContext(), "Credentials Saved! Please login" + affectedColumnid, Toast.LENGTH_SHORT).show();
sqliteDB.close();
finish();
}
}
The sqliteDB.insert return long value on success and -1 on error. The long value indicates the row number for newly inserted row in db. You can check this return value and display toast accordingly.
Please look at the detailed explanation here, http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#insert(java.lang.String, java.lang.String, android.content.ContentValues)
In short, modify your code to be like this,
private void insertCredentials(RegDetails regDetails){
LoginDB androidOpenDBHelper = new LoginDB(this);
SQLiteDatabase sqliteDB = androidOpenDBHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(LoginDB.COLUMN_NAME_USERNAME, rUsername);
contentValues.put(LoginDB.COLUMN_NAME_PASSWORD, rPasscode);
long affectedColumnid = sqliteDB.insert(LoginDB.TABLE_NAME_CREDENTIALS, null, contentValues);
if(affectedColumnid != -1){
Toast.makeText(getApplicationContext(), "Credentials Saved! Please login" + affectedColumnid, Toast.LENGTH_SHORT).show();
}else{
// Display error dialog or smthg
}
sqliteDB.close();
finish();
}
Read your database . If cursor.getCount() >0 thats mean data exists.
Cursor cursor = getDbEntries();
if( cursor.getCount() > 0 ){
// data exists
}
else{
// data doesnt exist
}

Categories

Resources