I am trying to add or update information in an SQLite database in Android.
The database takes a Lesson note id and a student id. If the lesson note id is 0, then a new entry is being made.
Here is what is in my Dbhelper class (for inserting, the update is fairly similar):
public boolean insertLessonNotes(LessonNotesData lData)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues lessonValues = new ContentValues();
//values.put(LESSON_ID, lData.getLessonID()); // Lesson ID
//values.put(ST_ID, lData.getStudentID()); // Student ID
//values.put(LESSON_IMAGE_ID, lData.getImageID()); // Lesson Image ID
//values.put(LESSON_IMAGE_NOTE, lData.getImageNote()); // Note attached to image
lessonValues.put(LESSON_ID, lData.getLessonID());
lessonValues.put(ST_ID, lData.getStudentID());
lessonValues.put(DATE, lData.getDate()); // Date note added
lessonValues.put(LESSON_READING, lData.getReadingNote()); // reading notes
lessonValues.put(LESSON_PHONICS, lData.getPhonicsNote()); // phoncis notes
lessonValues.put(LESSON_SPELLING, lData.getSpellingNote()); // spelling notes
lessonValues.put(LESSON_WRITING, lData.getWritingNote()); // writing notes
lessonValues.put(LESSON_COMMENTS, lData.getCommetns()); // comments notes
lessonValues.put(LESSON_HOMEWORK, lData.getHomework()); // homework notes
// Inserting Row
db.insert(TABLE_LESSON_NOTES, null, lessonValues);
db.close();
return true;
}
This is my lessonNotes class (where the information is entered and saved)
LessonNotesData lNote = new LessonNotesData(id_To_Update, student_id, lessonDate.getText().toString(), readNote.getText().toString(), phonNote.getText().toString(), spellNote.getText().toString(), writeNote.getText().toString(), commentNote.getText().toString(), homeworkNote.getText().toString());
Bundle extras = getIntent().getExtras();
int studentID = extras.getInt("studentId");
int lessonID = extras.getInt("lessonID");
Toast.makeText(getApplicationContext(), "LessonID is:(lessonNotes3) "+String.valueOf(lessonID), Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), "StudentID is: (lessonNotes3) "+String.valueOf(studentID), Toast.LENGTH_SHORT).show();
//Bundle studentId = getIntent().getExtras();
if (lessonID != 0) {
if (studentID > 0) {
if (mydb.updateLessonNotes(lNote)) {
//Update was successful
Toast.makeText(getApplicationContext(), "Updated successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), com.example.ltss.dyslexia.app.LessonNotesList.class);
intent.putExtra("studentId",studentID);
startActivity(intent);
} else {
//Update did not complete correctly
Toast.makeText(getApplicationContext(), "Update unsuccessful, Please try again", Toast.LENGTH_SHORT).show();
}
} else {
if (mydb.insertLessonNotes(lNote)) {
Toast.makeText(getApplicationContext(), "New Lesson note created", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Error creating lesson note! Please try again", Toast.LENGTH_SHORT).show();
}
//Return user to lessonNotesList where ListView should now show new lesson note
Intent intent = new Intent(getApplicationContext(), com.example.ltss.dyslexia.app.LessonNotesList.class);
intent.putExtra("studentId",studentID);
startActivity(intent);
}
}
Whenever I try to add or update anything in the system, I get this from the debug log:
04-02 20:02:33.925 26789-26789/com.example.ltssdyslexiaapp D/Items to add:﹕ com.example.ltss.dyslexia.app.LessonNotesData#42602bf8
Any ideas as to what this is or how I can fix it?
Thanks
Actually its not an error at all its just a Log output, its a DEBUG type of Log. You colud try to log the same adding line android.util.Log.d("hello","world"); to any method you want. And 'com.example.ltss.dyslexia.app.LessonNotesData#42602bf8' means that LessonNotesData has no toString() method and thats why you see #42602bf8 - its an instance address in memory or hash.
Related
Ok, I've got this Retrofit Call that receives a list of objects and insert the into a local SQLite database. I want to display a message saying that the operation was successful with a Ok button that when pressed opens a new activity.
How do I check if my Query has finished so I can show the message?
final ContactApi contactApi = retrofit.create(ContactApi.class);
Call<List<Contact>> callContact = contactApi.getContact(token);
callContact.enqueue(new Callback<List<Contact>>() {
#Override
public void onResponse(Response<List<Contact>> response, Retrofit retrofit) {
List<Contact> contactList = response.body();
if (contactList != null) {
try {
DBHelper dbHelper = new DBHelper(TokenActivity.this, token);
SQLiteDatabase conn = dbHelper.getWritableDatabase();
RepoContact repocontact = new RepoContact(conn);
// Inserts each contact into the database
for (Contatc c : contactList) {
repositorioCadastro.inserirCadastro(c);
Log.i("ACTTOKEN", "Contact insert ID: " + c.getId());
}
} catch (SQLiteException e) {
Log.i("ACTTOKEN", "Faillure on insert: " + e.getMessage());
}
}
wrap your code in try{...}finally{...} blocks with a listener ( beginTransactionWithListener(SQLiteTransactionListener transactionListener)), and use the transactionListner to check whether everything went well within the transaction, in addition to everything within the try/finally.
what you have is good, just try adding finally block..
something like this..
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
You can try a different loop, something like this:
for(int i = 0; i < contactList.size(); i++) {
Contact c = contactList.get(i);
repositorioCadastro.inserirCadastro(c);
Log.i("ACTTOKEN", "Contact insert ID: " + c.getId());
if(i == (contactList.size() - 1)) {
// DO SOMETHING HERE
}
}
You may check insert statement return a long when query successfully executed then long value.
db.insert()
returns the row ID of the newly inserted row, or -1 if an error occurred
I have a listView that is created in onCreate method.As below, and read data from a Stored Procedure.
I Used CallabeStatement.
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.type_of_dairy);
try
{
CallableStatement catCallable;
ConnectionHelper connectionHelper = new ConnectionHelper();
catCallable = connectionHelper.getConnection().prepareCall("{ CALL SpGetDairyCategory}");
catCallable.execute();
resultSet = catCallable.getResultSet();
setResultSet(resultSet);
if(getResultSet().next()) {
do {
String typeString = resultSet.getString("CategoryName");
int typeId = resultSet.getInt("CategoryId");
integerArraList.add(typeId);
typeArray.add(typeString);
typeAdapter.getItemViewType(R.id.listView); // adapter for first ListView
dairyType.setAdapter(typeAdapter);//dairyType is my first List View
}while(resultSet.next());
}
}
catch (SQLException e)
{
Toast.makeText(getApplicationContext(), "Something is wrong", Toast.LENGTH_LONG).show();
}
In the above code, I got Id of Category Id and name,and passed them into two ArrayLists named integerArrayList and typeArray.
I generate the second ListView with the Id of category that i got from the above Stored Procedure.
I do it in dairyType(first ListView)onClickListener.
here is the code
dairyType.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try {
flavorAapter.clear();
CallableStatement proCallable;
ConnectionHelper connectionHelper = new ConnectionHelper();
proCallable = connectionHelper.getConnection().prepareCall("{call SpGetCategoryProducts(?)}");
proCallable.setInt(1, integerArraList.get(dairyType.getCheckedItemPosition())); //integerArrayList contains the categoryId from the first Store Procedure
resultSet2 = proCallable.executeQuery();
//The second Stored Procedure get the Id and return some value as you see
if (resultSet2.next()) {
do {
int flavourId;
int weitgh;
int price;
weitgh = resultSet2.getInt("Weight");
price = resultSet2.getInt("Price");
String flavourString = resultSet2.getString("Name");
flavourId = resultSet2.getInt("Id");
dairyArray.add(flavourString);
idOfCategories.add(flavourId);
weightArray.add(weitgh);
priceArray.add(price);
flavorAapter.getItemViewType(R.id.listView2);
dairyFlavour.destroyDrawingCache();
dairyFlavour.setAdapter(flavorAapter);
} while (resultSet2.next());
connectionHelper.closeConnection();
} else {
flavorAapter.clear();
Toast.makeText(getApplicationContext(), "Nothing to show", Toast.LENGTH_LONG).show();
}
} catch (SQLException e) {
Toast.makeText(getApplicationContext(), "Something wrong", Toast.LENGTH_LONG).show();
dairyArray.clear();
}
}
});
Ok, so i generate the second Listview sucessfully as i wanted,
the problem is in the insert Buttom,
Now i have ArrayList of Name, Weight, Price and Id.( I use Id as an argument that passes to last Stored Procedure.
So I have to call another Stored Procedure to insert all these data into DB(Name,Weight,Price)
But it doesnt insert the changed items values.
It means, i select an item from the first ListView,The second Listview generate and i choose one of them, but when i change my select in the first ListView, it still insert the id of first ListView.
here is my insert code via buttom named apply.
apply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
dairyFlavour.invalidateViews();
dairyType.invalidateViews();
typeAdapter.notifyDataSetInvalidated();
flavorAapter.notifyDataSetChanged();
int weight = weightArray.get(dairyFlavour.getCheckedItemPosition()); //weitgh from previous SP
int price = priceArray.get(dairyFlavour.getCheckedItemPosition()); //price from previous SP
String count = "";
int c;
count = countOfProduct.getText().toString(); // insert the count of product via editText
c = Integer.parseInt(count); // cast the cound to Integer
we = idOfCategories.get(dairyFlavour.getCheckedItemPosition());//the id i got in previous SP
CallableStatement callableStatement = null;
ConnectionHelper connectionHelper = new ConnectionHelper();
callableStatement = connectionHelper.getConnection().prepareCall("{call SpInsertLoadCityProducts(?, ?, ? ,?)}");
callableStatement.setInt(1, we);
callableStatement.setInt(2, weight);
callableStatement.setInt(3, price);
callableStatement.setInt(4, c);
callableStatement.executeQuery();
}catch(SQLException e){
Toast.makeText(getApplicationContext(), "Something is wrong", Toast.LENGTH_LONG).show()
}
Intent i = new Intent(getApplicationContext(), FinishLoading.class);
startActivity(i);
}
});
In view it is ok and as i change the first ListView the second ListView generated as desired.
But in insert, i only insert the first chose values into DB, and when i change the selection in the first ListView and choose another product in second ListView and click apply buttom, the first data is inserted.
Any Suggestion?
If you are confused ask question to make myself more clear !
I found the solution.
I should clear every ArrayList befor storing data.
when first time get index and data, i should clear ArrayList and again fill out them as below.
dairyTypes.clear();
integerArraList.clear();
typeArray.clear();
and also
flavorAapter.clear();
I've been working with Xamarin for a few weeks now and i'm trying to find the best practices for using SQLite ORM queries.I have a log in page which is launched first before users can access the app.I have the database created before this first activity comes to the screen and administrator log in details inserted into the user's table as soon as the tables are created.The point is,the admin is meant to log in and import an xml file containing all of the other user's personal information.This information is read from the file and saved to sqlite as well.
Next,the other users can log in after their details have been imported and saved successfully.My challenge is,at the point of logging in,i would like to verify the details as follows:
1.Compare the entered username with a single username from the db
**2.Check the password entered to see if it matches the username entered **
I'm currently using a select query to pull up all the passwords from the database,before comparing the two strings(from the db and from the edit text field).If it's a large db however,reading all the data will be quite expensive.How do i go about this?
How do i also look up the password for that username?
Below is my code:
namespace sample.NameSpace
{
[Activity (MainLauncher = true)]
public class MainActivity : Activity
{
Button login = FindViewById<Button> (Resource.Id.login);
try{
login.Click += (object sender, EventArgs e) => {
if (TextUtils.IsEmpty(userName.Text.ToString())) {
makeToast();
} else if (TextUtils.IsEmpty(password.Text.ToString())) {
makeToast();
} else {
returningUser = userName.Text.ToString().Trim();
returningUserPassword = password.Text.ToString().Trim();
}
//Check to see if the name is in the db already
List<string> allUsers = GetAllUserNames();
//Loop through the list of names and compare the retrieved username with the name entered in the text field
string retrievedDbName ="";
foreach(string name in allUsers )
{
retrievedDbName = name .Trim();
}
//Verify name
if(retrievedDbName .Equals(returningUser))
{
Toast.MakeText(this,
"Login Successful !", ToastLength.Short).Show();
Intent intent = new Intent (this, typeof(HomeActivity));
StartActivity (intent);
}
else
{
Toast.MakeText(this, "User Name or Password does not match", ToastLength.Short).Show();
}
};
} catch(Exception e){
logger.Exception (this, e);
}
public List<string>GetAllUserNames()
{
List<UserInfoTable> allUserNames = new List<UserInfoTable> ();
allUserNames = dataManager.GetSingleUserName ();
string name = "";
foreach(var UserName in allUserNames)
{
Console.WriteLine ("Usernames from db :" + name.ToString());
}
return allUserNames;
}
Then the DataManager class:
public List<UserInfoTable> GetSingleUserName()
{
UserInfoTable user = new UserInfoTable ();
using (var db = dbHandler.getUserDatabaseConnection ()) {
var userName = db.Query<UserInfoTable> ("select * from UserInfoTable where user_name = ?", user.USER_NAME);
return userName;
}
}
public bool CheckLogin(string user, string password)
{
bool valid = false;
using (var db = dbHandler.getUserDatabaseConnection ()) {
var user = db.Query<UserInfoTable> ("select * from UserInfoTable where user_name = ? and password = ?", user, password);
if (user != null) valid = true;
}
return valid;
}
I am working on a button to email all users that have an email within the sqlite database. At the moment i have got the button working successfully, but can only call a single email address that is linked to the rows id.
Below is the code where i call upon the email and then send.
view.findViewById(R.id.btn_save).setOnClickListener(new OnClickListener() {
public void onClick(View view ) {
Mail m = new Mail("gmail#gmail.com", "password");
int arg = 0;
String[] toArr = {user_eMail.get(arg)};
m.setTo(toArr);
m.setFrom("gmail#gmail.com");
m.setSubject("This email is never going to work");
m.setBody("If you can read this email, please call me immediately because this never should have worked.");
try {
if(m.send()) {
Toast.makeText(getActivity(), "Email was sent successfully.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), "Email was not sent.", Toast.LENGTH_LONG).show();
}
} catch(Exception e) {
//Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show();
Log.e("MailApp", "Could not send email", e);
}
}
});
How do i go about changing the "int arg = 0" into calling all ids in the database? If you need any other code just let me know.
ok, since user_eMail is an ArrayList
private ArrayList<String> user_eMail = new ArrayList<String>();
.setTo() method must receive an array of emails separated by ","
create a method to extract an array from the database (for example getEmailsFromDB()) containing the emails: {"email1#gmail.com", "email2#gmail.com", "email3#gmail.com", "email4#gmail.com", "email5#gmail.com"};
and use:
m.setTo(getEmailsFromDB())
other option, the method returns from Database a String containing all the emails separated by "," , like "email1#gmail.com, email2#gmail.com, email3#gmail.com, email4#gmail.com, email5#gmail.com";
String[] user_eMail = getEmailsFromDB().split(",");
m.setTo(user_eMail);
i have created an app which insert data to sql server. i made column NAME as unique key.
i want that if i enter same name by edittext to insert...it should give a toast message.
but it's not happening. i cann't understand where i have made error.
in connection to server there is no problem. the only thing is i have to display Toast msg if i entered same name again.
my code is.......
public void onClick(View v) {
// TODO Auto-generated method stub
String myloc=loc.getText().toString();
String myname=name.getText().toString();
String myphone=phone.getText().toString();
initilize();
ResultSet rs;
try{
Statement statement=connect.createStatement();
rs=statement.executeQuery("SELECT * FROM FORM1");
List<Map<String,String>>data=null;
data=new ArrayList<Map<String,String>>();
while(rs.next()){
Map<String,String>datanum=new HashMap<String,String>();
datanum.put("a", rs.getString("NAME"));
data.add(datanum);
}
if(data.contains(myname)){
Toast.makeText(c, myname+" Already stored: please choose different one", Toast.LENGTH_LONG).show();
}
else{
insert(myname,myphone,myloc);
}
}catch(Exception e){
Log.e("ERROR", e.getMessage());
}
}
plzz guys...help me someone...
With data.contains(myname) you are trying to check if there is myname of type String in your data varible, but, in fact, your data have type List<Map<String,String>>, so when you are invoking contains(Object object) method passing a String, you are performing equals operation between Map<String,String> and String, which clearly would always result false. So I would suggest you either write something like this
List<String> data = new ArrayList<String>();
while(rs.next()) {
data.add(rs.getString("NAME"));
}
if(data.contains(myname)){
Toast.makeText(c, myname+" Already stored: please choose different one", Toast.LENGTH_LONG).show();
}
or there is a better way, just change your query to SELECT * FROM FORM1 WHERE NAME = myname and check if your result set is empty.