Android SQLite: entry validating/checking - android

Hoping someone might be able to shine a little light on this for me to help out. I have a EditText field where a user will input a serial number and or reference number, then hit the load Button.
http://i.stack.imgur.com/95iWI.png
I made a method to check and see if that number has already been added to the Database. If it hasn't then i have a Yes/No dialog that pops up asking if they want to add to the database. Then if it is in the DB it will load that number's data into the four TextViews.
http://i.stack.imgur.com/dHbCQ.png
If they select yes then it runs the new intent, switching to the form screen(haven't yet looked into passing the user input to another class yet). but to get back on to my little issue, when testing this in the emulator everything runs fine. Then when i enter a number that i already entered in it still opens the dialog, (i have it in a if statement).
Load button code
String s = input.getText().toString();
int l = Integer.parseInt(s);
Db load = new Db(this);
load.open();
y = load.dbCheck(l);
if (y != 0) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
Intent i = new Intent("android.intent.action.FORM");
startActivity(i);
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Would you like to add to Database?")
.setTitle("Not in Database:")
.setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener)
.show();
}
else
{
final Dialog dbentery = new Dialog(this);
dbentery.setTitle("Entry Exists!");
TextView tv = new TextView(this);
tv.setText("The serial number you have entered is already in database");
dbentery.setContentView(tv);
dbentery.show();
final Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
dbentery.dismiss();
t.cancel();
}
}, 2000);
}
load.close();
Now with the method i created I thought I had it right, but something just isn't working. I have it returning a integer back to the load button code where the if statement uses wither 0 or 1 to validate if it is in the DB and what it should do. I figured since it is running the Dialog that it is returning 0, that it might be with the cursor. I looked at a few other posts on here that were similar but didn't seem to help me and or i wasn't comprehending what was being done. So here's the checking method in my DBHelper class
/* this is to check to see if entry is in db or not */
public int dbCheck(int l) throws SQLException {
String[] cols = new String[] { KEY_ROWID, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR };
Cursor c = ourDB.query(KEY_TABLE, cols, KEY_ONE + "=" + l, null,
null, null, null);
if (c == null) {
return 0;
}else {
return 1;
}
}
this might be a simple fix, but I'm not seeing it... thanks for any help or insight to what i might be doing wrong

c == null if the query throws an error, otherwise c != null, but c.getCount == 0
public int dbCheck(int l) throws SQLException {
String[] cols = new String[] { KEY_ROWID, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR };
Cursor c = ourDB.query(KEY_TABLE, cols, KEY_ONE + "=" + l, null,
null, null, null);
if (c == null) {
return 0;
}else {
return c.getCount() == 0 ? 0:1;
}
}

First, rewrite dbCheck() to return boolean, not int. No point in having an int if you only return two values, waste of space.
Second, rewrite your query. There is no point in selecting all those columns if you only filter on one of them, and then throw the result away. Rewrite it into this:
String s = String.format("SELECT count(*) FROM %s WHERE %s = %d",
KEY_TABLE, KEY_ONE, l);
Cursor c = ourDB.rawQuery(s, null);
c.moveToFirst();
return (c.getInt(0) > 0); // returns a boolean
This will cut down the number of quirks you have in your code, and it will help you debug it easier.
EDIT: corrected query() into rawQuery().

Related

Hashmap values not appended to Alertdialog

I have a callog(displayed in an alert dialog) in an arraylist that has been sorted using an hashmap, any time I try to view this callog it shows just the result of the calllog query but in my logcat it shows the numbers properly sorted. Please how can I append this result in the logcat to the alert dialog? I have been battling with it for days and I can't seem to figure it out.
final List<String> allNumbers = new ArrayList<String>();
public void onClick(View v) {
String[] strFields = { android.provider.CallLog.Calls._ID,
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.CACHED_NAME, };
String strOrder = android.provider.CallLog.Calls.DATE + " DESC LIMIT 10 ";
final Cursor cursorCall = EmergencyButtonActivity.this.getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, strFields,
null, null, strOrder);
this.sortNumber();
while (cursorCall.moveToNext()){
String names = cursorCall.getString(cursorCall.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
allNumbers.add(names)
}
AlertDialog.Builder builder = new AlertDialog.Builder(EmergencyButtonActivity.this);
builder.setTitle("Frequent Contacts");
android.content.DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int item) {
cursorCall.moveToPosition(item);
EditText phoneInput = (EditText) findViewById(R.id.txtPhoneNo);
String selectedNumber =cursorCall.getString(cursorCall.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
selectedNumber = selectedNumber.replace("-", "");
phoneInput.setText(selectedNumber);
Toast.makeText(EmergencyButtonActivity.this, cursorCall.getString(cursorCall.getColumnIndex(android.provider.CallLog.Calls.NUMBER)),
Toast.LENGTH_LONG).show();
cursorCall.close();
}
};
builder.setCursor(cursorCall, listener, android.provider.CallLog.Calls.CACHED_NAME);
builder.create().show();
}
public void sortNumber() {
Map<String, Integer> map = new HashMap<String, Integer>();
for (String temp : allNumbers) {
Integer count = map.get(temp);
map.put(temp, (count == null) ? 1 : count + 1);
}
printMap(map);
}
public static void printMap(Map<String, Integer> map){
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println( entry.getKey() + entry.getValue());
}
}
There is so much wrong with this it is hard to know where to begin :-(
First of all, you cannot "sort" anything using a HashMap. These 2 concepts are mutually exclusive.
Secondly, you have a while loop where you are creating and showing an AlertDialog for each row in your cursor. That can't be right.
Next, you are calling setCursor() on the AlertDialog.Builder and passing the Cursor. The dialog builder is using the data in this Cursor to build the content to be shown in the dialog. The fact that you have "sorted" the data is irrelevant, as you have given the dialog builder the data from your raw query.
Next, your method sortNumber() creates a HashMap and fills it, but this HashMap is a local variable to this method, so after the method returns, the HashMap is gone. You don't return the HashMap from the method, or store it anywhere.
If you really want the data "sorted", you should just add an "ordered by" clause to your query.
You might want to consider returning your HashMap from the sortNumber() method and then building an array of Strings out of that and then calling setItems() on the dialog builder instead of using setCursor().

Receiving unknown count of results from SQLite db

Basically this is not a problem in itself, my code works so far.
What I have is a App, that lets a user log in and depending on his ID in the db, he gets displayed his saved notes. For this view I have this part of code:
title = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
MyDbHandler dbh = new MyDbHandler(this);
for(int i = 0; i < 999; i++) {
content = dbh.getNoteTitle(id, i); //getNoteTitle(int, int) returns String
if(content != null && content != "0")
title.add(content);
else
break;
}
list.setAdapter(title);
As I said, this works so far.
Thing is - I am very unhappy with the use of ' break; ' here, as I learned during education, this shouldn't be used.
Is there a smoother way to approach this issue?
Also ' content != "0" ' should be ' ! content.equals("0") ' normally, right? But that one doesn't work then... Why is this?
I am not sure what are you trying to do. First of all you should use "equal" method for Strings. The condition "content != "0" will always be true, because you are comparing 2 different objects. The condition "! content.equals("0")" should return true most of the time (when the value is not "0") and probably you should use the debugger to see exactly what is the value of content.
Second if you want to take all the notes from the database and show them to the user you should have first a method in the SQLiteOpenHelper similar to (it is not efficient to interrogate the database for each item, plus the separation of concerns):
public ArrayList<String> getNotesList (int userID){
SQLiteDatabase db = getWritableDatabase();
Cursor c = db.query(TABLE_NAME, new String[] {MyDbHandler.COLUMN_NOTE_TITLE}, MyDbHandler.userID + "=" + userID,null, null, null, null);
ArrayList<String> list = null;
String noteTitle;
if (c != null && c.moveToFirst())
{
list = new ArrayList<String>(c.getCount());
for (int i = 0; i < c.getCount(); i++)
{
noteTitle = c.getString(c.getColumnIndex(MyDbHandler.COLUMN_SESSION_PATH));
list.add(noteTitle);
c.moveToNext();
}
}
c.close();
db.close();
return list;
I think you should not save notes that you don't want to use (e.g. null or "0"), so instead of checking here, I would check in the addNote method.
For the list initialization you have:
MyDbHandler dbh = new MyDbHandler(this);
ArrayList listData = dbh.getNotesList(id)
if (listData != null && listData.length != 0){
title = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
listData.setAdapter(title);
}
I didn't test the code, but I hope it helps you. Good luck!

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

android sqlite next record incorrect

This is the getContact method which takes the rowID in this case the counter
public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
question, possibleAnsOne,possibleAnsTwo, possibleAnsThree,realQuestion,userR}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
// moves to the the first record
mCursor.moveToFirst();
}
return mCursor;
}
Here is my problem. I start at record one. So the counter is set to one.
in the public oncreate method. When I click next for some reason it is not setting the value of the first record with db.updateUserResult(counter,8); I think it is missing the first record. The reason I know this is that if I chose the answer which is one ahead. Lets say that Question 1 right answer is option 2 and Question 2's right answer is option 3. If you choose option 3 for question 1 then you get the right answer. If i keep choosing the right answer one record ahead I get all the right results.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
boolean TimerStarted = b.getBoolean("timerlogic");
System.out.println("what is the logic of the timer" + TimerStarted);
Log.e(LOGS, "Whatis the first value for the timer inside the timer_btn" + TimerStarted);
setContentView(R.layout.basic);
// this method is better then a try and catch block as it actually prevents the occurence occuring instead of just patching it.
// the purpose of t
db.open();
Cursor c = db.getContact(1);
if(c.isFirst())
{
TextView question = (TextView)findViewById(R.id.question);
RadioButton radio1 = (RadioButton)findViewById(R.id.radio1);
RadioButton radio2 = (RadioButton)findViewById(R.id.radio2);
RadioButton radio3 = (RadioButton)findViewById(R.id.radio3);
answerCounterText = (TextView)findViewById(R.id.answerCounterText);
answerCounterText.setText(String.valueOf("0"));
// for the first record set the counter to zero
// question.setText(String.valueOf("0"));
TextView QuestionNumber = (TextView)findViewById(R.id.QuestionNumber);
Complete = (Button)findViewById(R.id.Continue);
Complete.setBackgroundResource(R.drawable.complete);
Complete.setVisibility(View.INVISIBLE);
QuestionNumber.setText(String.valueOf("Question Number :" + counter));
System.out.println("what is the setup counter after loop" + counter);
//DisplayContact(c,radio1);
DisplayRadioButton(c,radio1,radio2,radio3,question);
}
// }
// }
// Previous = (Button)findViewById(R.id.Previous);
Next = (Button)findViewById(R.id.Next);
Next.setBackgroundResource(R.drawable.next);
// get the results from the checked box
Next.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
// Cursor c = db.getContact(1);
/*
if (firstrecordchosen)
{
Cursor c = db.getContact(1);
System.out.println("what is the current value of the counter 0" + counter);
firstrecordchosen = false;
}
counter++;
*/
counter++;
Cursor c = db.getContact(counter);
if (c.moveToFirst() && !c.isNull(0))
{
TextView question = (TextView)findViewById(R.id.question);
RadioButton radio1 = (RadioButton)findViewById(R.id.radio1);
RadioButton radio2 = (RadioButton)findViewById(R.id.radio2);
RadioButton radio3 = (RadioButton)findViewById(R.id.radio3);
TextView answerCounterText = (TextView)findViewById(R.id.answerCounterText);
TextView QuestionNumber = (TextView)findViewById(R.id.QuestionNumber);
RadioGroup radioGroup1 = (RadioGroup)findViewById(R.id.radioGroup1);
QuestionNumber.setText(String.valueOf("Question Number :" + counter));
Log.e(LOGS, "default user set variable " + c.getString(5));
Log.e(LOGS, "real value" + c.getString(6));
System.out.println("what is the current value of the counter" + counter);
// DisplayContact(c,radio1);
DisplayRadioButton(c,radio1,radio2,radio3,question);
final String questionOneDb = c.getString(5);
String radioOneIndex = "1";
String radioTwoIndex = "2";
String radioThreeIndex = "3";
// set the first question to have the right value
if(radio1.isChecked() )
{
db.updateUserResult(counter,8);
if (questionOneDb.equals(radioOneIndex))
{
Log.e(LOGS, "correct" );
rightAnswer(c,radio1,answerCounterText);
// DisplayContact(c,radio1);
}
else
{
Log.e(LOGS, "wrong" );
}
}
if(radio2.isChecked() )
{
db.updateUserResult(counter,9);
if (questionOneDb.equals(radioTwoIndex))
{
System.out.println("is this counter being reached");
// db.updateUserResult(1, 2);
// db.updateUserResult(counter, 2);
// db.updateUserResult(recordval, 6);
Log.e(LOGS, "correct" );
rightAnswer(c,radio1,answerCounterText);
}
else
{
Log.e(LOGS, "wrong" );
}
}
if(radio3.isChecked() )
{
db.updateUserResult(counter,10);
if (questionOneDb.equals(radioThreeIndex))
{
Log.e(LOGS, "correct" );
System.out.println("you have the right answer");
rightAnswer(c,radio1,answerCounterText);
}
else
{
Log.e(LOGS, "wrong" );
}
}
}
/* when you get ot the last record you want to be able to close the db */
if (c.isAfterLast())
{
// this halts the timer when there are no questiosn left
Next.setVisibility(View.GONE);
// Previous.setVisibility(View.GONE);
Toast.makeText(getBaseContext(), "More questions available in the full version PHPExpert " , Toast.LENGTH_LONG).show();
Complete.setVisibility(View.VISIBLE);
handler.removeCallbacks(timedTask);
db.close();
intentcalls();
}
}
});
Home = (Button)findViewById(R.id.home_btn);
Home.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(Basic_database_questionsActivity.this,AndroidGUIActivity.class);
startActivity(i);
}
});
}
If I am not totally wrong, you have a timing issue.
First you get your first question and you show the UI (your radio buttons and stuff).
You check with the click on the Next button, if the chosen answer is right, correct?
If so, you make the mistake that you first increase the counter and then query for the question based on counter (which will be the next). After that you check if the chosen radio button is the correct one. As you already read the next question from the database, you check the chosen answer to your first question with the stored answer of the second one.
Hope that was clear.
Short tip: try to clean up some code. Don't put anything inside the onCreate() make smaller chunks so you can see and follow the code flow easier...
Try this
Cursor c1 = mDbHelper.fetAll(); \\ or whatever your method is to get data from database.
if(c1.moveToFirst()){
do{
\\ Do what you want to do with it.
}while(c1.moveToNext()); \\ this will move the cursor to next line.
}
c1.close(); \\ make sure you close it, else errors will pop up in LOGCAT.

Error in AutoCompleteText when the inputed text isnt on the autocomplete list for android

I'm using an AutoCompleteText for searching a location which would be connected to the database and the result would be shown. everything works fine when the inputed text is what is on the autocomplete list. But when i tried to input with a different text, which isnt available on the database, the application will get a force close.
here is my code
DataSPBU helper = new DataSPBU(this);
database = helper.getWritableDatabase();
Cursor dbCursor = database.query(TABLE_NAME, new String[] {SPBU, Alamat, JenisBensin, FasilitasUmum}, Alamat + "=?",new String[] {lokasi}, null, null, null);
if(dbCursor.moveToPosition(0)) {
String namaSpbu = dbCursor.getString(0);
String alamatSpbu = dbCursor.getString(1);
String jenisSpbu = dbCursor.getString(2);
String fasilitasSpbu = dbCursor.getString(3);
namaSpbuEdit.setText(namaSpbu);
alamatEdit.setText(alamatSpbu);
jenisBensinEdit.setText(jenisSpbu);
fasilitasEdit.setText(fasilitasSpbu);
}
else {
notFoundDialog = new AlertDialog.Builder(this)
.setTitle("RESULT NOT FOUND")
.setMessage("Hasil Tidak Ditemukan")
.setNegativeButton("close", new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create();
notFoundDialog.show();
}
//
any help would be highly appreciated.
Hey man when ever you enter a new text first enter into database after fetch the data,
then the application does not force close .and the data also shown in autocomplete text view
code::
String s=Edittext.getText().toString();
db.insert(s);
after bind the data with your resource

Categories

Resources