Retrieving data from SQLite and displaying in Listview - android

I am trying to display the contents of my mysqlite database into a listview,
I am able to get the contents and display them in a textview, but for some
reason I can't add the details to an arraylist ? I am not too sure what am doing
wrong. I have looked for multiple solutions but none of them seem to work, am getting an error
Android.database.CursorIndexOutOfBoundsExecption: Index requested -1
Here is what I currently have:
OnCreate:
ArrayAdapter<Contact> currentContactsAdapter = new ContactArrayAdapter();
ListView lvcontacts = (ListView) findViewById(R.id.lvContacts);
lvcontacts.setAdapter(currentContactsAdapter);
tdb = new TestDBOpenHelper(this, "contact.db", null, 1);
sdb = tdb.getWritableDatabase();
new MyContacts().execute();
ListView Adapter:
private class ContactArrayAdapter extends ArrayAdapter<Contact>{
public ContactArrayAdapter(){
super(MainActivity.this, R.layout.listviewitem, addedContacts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(itemView == null){
itemView = getLayoutInflater().inflate(R.layout.listviewitem, parent, false);
}
Contact currentContact = addedContacts.get(position);
TextView name = (TextView) itemView.findViewById(R.id.tvNameitem);
name.setText(currentContact.getName());
TextView phone = (TextView) itemView.findViewById(R.id.tvPhoneitem);
phone.setText(currentContact.getPhone());
TextView email = (TextView) itemView.findViewById(R.id.tvEmailitem);
email.setText(currentContact.getEmail());
return itemView;
}
}
GetContacts:
class MyContacts extends AsyncTask<String, String, String> {
List<Contact> retrievedContacts = new ArrayList<Contact>();
protected String doInBackground(String... args) {
String cname;
String cphone;
String cemail;
// name of the table to query
String table_name = "contact";
// the columns that we wish to retrieve from the tables
String[] columns = {"FIRST_NAME", "PHONE", "EMAIL"};
// where clause of the query. DO NOT WRITE WHERE IN THIS
String where = null;
// arguments to provide to the where clause
String where_args[] = null;
// group by clause of the query. DO NOT WRITE GROUP BY IN THIS
String group_by = null;
// having clause of the query. DO NOT WRITE HAVING IN THIS
String having = null;
// order by clause of the query. DO NOT WRITE ORDER BY IN THIS
String order_by = null;
// run the query. this will give us a cursor into the database
// that will enable us to change the table row that we are working with
Cursor c = sdb.query(table_name, columns, where, where_args, group_by,
having, order_by);
for(int i = 0; i < c.getCount(); i++) {
cname = c.getString(c.getColumnIndex("FIRST_NAME"));
cphone = c.getString(c.getColumnIndex("PHONE"));
cemail = c.getString(c.getColumnIndex("EMAIL"));
c.moveToNext();
retrievedContacts.add(new Contact(cname,cphone,cemail));
}
return null;
}
//Update Contact list when response from server is received
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
for(Contact contact: retrievedContacts)
addedContacts.add(contact);
}
}

It seems that your table "contact" doesn't have the exact structure you are trying to read.
Android.database.CursorIndexOutOfBoundsExecption: Index requested -1
This means that one of these column names is not part of it.
c.getColumnIndex("FIRST_NAME")
c.getColumnIndex("PHONE")
c.getColumnIndex("EMAIL")
So one of them return -1 instead of the index because they not exist in the table.
EDIT:
Then the for loop may be faulty. I suggest to use something like:
if (c != null ) {
if (c.moveToFirst()) { // Always move at the first item
do {
cname = c.getString(c.getColumnIndex("FIRST_NAME"));
cphone = c.getString(c.getColumnIndex("PHONE"));
cemail = c.getString(c.getColumnIndex("EMAIL"));
retrievedContacts.add(new Contact(cname, cphone, cemail));
} while (c.moveToNext());
}
}
c.close(); // always close when done!

Related

Adding Cart Items to the Database and retrieving

I have three tables in mySQL namely user, restaurants, cartlist.
here user table is for saving the user details.
restaurant table is for saving the meal details, price and quantity.
cartlist is to add the restaurant details.
Now when the specific user login to the app, I want the cartlist items of specific user added to the list. but Im getting the details of whole users who added items to the cart.
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String selectQuery = "SELECT * FROM restaurants";
SQLiteDatabase database = DatabaseManager.getInstance().openDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
ProductModel productModel = new ProductModel();
productModel.setID(Integer.parseInt(cursor.getString(0)));
productModel.setName(cursor.getString(1));
productModel.setMealname(cursor.getString(2));
productModel.setMealprice(cursor.getString(3));
productModel.setMealqty(cursor.getString(4));
products.add(productModel);
} while (cursor.moveToNext());
}
cursor.close();
DatabaseManager.getInstance().closeDatabase();
adapter = new ProductAdapter(ProductList.this, R.layout.activity_cartlistview, products);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
Carttable:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkout);
lv_checkout = findViewById(R.id.lv_checkout);
tv_totalamount = findViewById(R.id.tv_totalamount);
btn_checkouttopayment = findViewById(R.id.btn_checkouttopayment);
String selectQuery = "SELECT * FROM carttable";
SQLiteDatabase database = DatabaseManager.getInstance().openDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
ProductModel productModel = new ProductModel();
productModel.setID(Integer.parseInt(cursor.getString(0)));
productModel.setName(cursor.getString(1));
productModel.setMealname(cursor.getString(2));
productModel.setMealprice(cursor.getString(3));
productModel.setMealqty(cursor.getString(4));
productModel.setMealtotal((Double.parseDouble(cursor.getString(3)) * Double.parseDouble(cursor.getString(4)) + ""));
products.add(productModel);
} while (cursor.moveToNext());
}
double totalPrices = 0;
for (int i = 0; i < products.size(); i++) {
totalPrices += Double.parseDouble(products.get(i).getMealtotal());
}
tv_totalamount.setText("Total Amount to be Paid : " + totalPrices + "");
cursor.close();
DatabaseManager.getInstance().closeDatabase();
adapter = new ProductAdapter(this, R.layout.activity_cartlistview, products);
lv_checkout.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
what are the changed to be done to the query? Let me knw guys.TIA!
It's because The query you are running is going to the Restaurant table and getting all the Records from It. From what I can understand, Cartlist the name of table in which a user will input the details of a particular restaurant. So Right now, you are calling all the records from Restaurant table which will give you the list regardless of who added it.
You might want to change the query to something like
SELECT restaurant_name FROM cartlist WHERE userName = selected_User;
Now you have the restaurant name. Save these and use it on query.
SELECT * FROM restaurants WHERE restaurantsName = selected_restaurant_name;
do {
ProductModel productModel = new ProductModel();
productModel.setID(Integer.parseInt(cursor.getString(0)));
productModel.setName(cursor.getString(1));
productModel.setMealname(cursor.getString(2));
productModel.setMealprice(cursor.getString(3));
productModel.setMealqty(cursor.getString(4));
productModel.setMealtotal((Double.parseDouble(cursor.getString(3)) * Double.parseDouble(cursor.getString(4)) + ""));
products.add(productModel);
}
Add a constructor to your model class and inject in. Saves a few lines of code/readability.
do {
products.add( new ProductModel(
Integer.parseInt(cursor.getString(0)),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3),
cursor.getString(4),
}
The line: productModel.setMealtotal((Double.parseDouble(cursor.getString(3)) * Double.parseDouble(cursor.getString(4)) + ""));
seems to contain a simple relationship where the "Meal total = mean quantity * meal price" which could be done in the constructor as well...it is a constant algorithm and part of the model.
Here is the model (I have added #Data using lombok which makes all the getters and setters when being compiled)
import lombok.Data;
#Data
public class ProductModel {
private int id;
private String name;
private String mealName;
private int mealPrice;
private int mealQuantity;
private int mealTotal;
//Constructor...i.e. "new ProductModel(field1,field2...)"
public ProductModel(int id, String name, String mealName, int mealPrice, int mealQuantity) {
this.id = id;
this.name = name;
this.mealName = mealName;
this.mealPrice = mealPrice;
this.mealQuantity = mealQuantity;
this.mealTotal = mealPrice * mealQuantity;
}
}

ListView does not change elements at scrolling

I have several markers on a google map and in each marker a ListView with several entries.
Each entry can be liked by the user and if he has liked, there is stored an entry in the SQLite Database with the marker ID, the entry ID and if he has liked (1) or took the like back (0) and the activity is reloaded.
Now I want a filled heart to be shown below each List Item the user has liked. The problem is: Especially if there are many entries, there are randomly filled hearts, even if the user only liked one entry. These falsely filled hearts sometimes appear only at scrolling up so I assume, that the ListView does not update its elements at scrolling...
Here is my code:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ListCell cell;
if (convertView == null) {
convertView = inflater.inflate(R.layout.pinboard_list_view_cell, null);
cell = new ListCell();
cell.likes = (TextView) convertView.findViewById(R.id.listViewLikes);
cell.note = (TextView) convertView.findViewById(R.id.listViewNote);
cell.img = (ImageView) convertView.findViewById(R.id.listViewImg);
cell.likeImage = (ImageView) convertView.findViewById(R.id.heartImage);
convertView.setTag(cell);
}
else {
cell = (ListCell)convertView.getTag();
}
cell.position = position;
//Listen-Items mit entsprechenden Elementen aus dem heruntergeladenen Array befüllen
try {
JSONObject jsonObject = this.dataArray.getJSONObject(position);
cell.likes.setText(jsonObject.getString("likes"));
cell.note.setText(jsonObject.getString("note"));
cell.entryID = jsonObject.getString("id");
String img = jsonObject.getString("image");
String urlForImageInServer = baseUrlForImage + img;
Picasso.with(context)
.load(urlForImageInServer)
.placeholder(R.drawable.progress_animation)
.error(R.drawable.no_picture)
.into(cell.img);
objectID = ""+cell.entryID;
dbh = new DbHelper(context);
cursor = getLikes(dbh);
cursor.moveToFirst();
if (cursor.moveToFirst()) {
do {
if (Integer.parseInt(cursor.getString(2)) == 1) {
cell.likeImage.setImageResource(R.drawable.heart_filled);
}
else {
cell.likeImage.setImageResource(R.drawable.heart);
}
}
while(cursor.moveToNext());
}
else {
cursor.close();
}
cursor.close();
}
catch (JSONException e) {
e.printStackTrace();
}
return convertView;
}
public static class ListCell {
private TextView likes;
private TextView note;
private ImageView img;
public ImageView likeImage;
public int position;
public String entryID;
}
public Cursor getLikes(DbHelper dbh) {
dbase = dbh.getReadableDatabase();
String columns[] = {dbh.LIKES_MARKERID, dbh.LIKES_ENTRYID, dbh.LIKES_LIKE};
String selection = dbh.LIKES_MARKERID + " LIKE ? AND " + dbh.LIKES_ENTRYID + " LIKE ? ";
String args[] = {markerID.toString(), objectID};
Cursor cursor = dbase.query(dbh.TABLE_LIKES, columns, selection, args , null, null, null, null);
return cursor;
}
if there are no likes make sure you set disable heart image explictly. Right now it seems you are trying to set it inside do while loop, if flow doesn't goes inside this loop, recycled view will be used which may or may not have disabled heart.

How to add pagination in Expandable list view.How to add load more button code

Main Activity
Code for fetching data from Sqlite & adding it inside Expandable list view.
public void getExpandableListData() {
// Group data//
Cursor cursor = databaseHelper.getGroupData();
cursor.moveToFirst();
do {
String categoryDescription = cursor.getString(cursor .getColumnIndex("categorydesc"));
int categoryId = cursor.getInt(cursor.getColumnIndex("CategoryId"));
listDataHeader.add(categoryDescription);
// Child data//
Cursor cursorChild = databaseHelper.getChildData(categoryId);
List<ChildInfo> childList = new ArrayList<ChildInfo>();
cursorChild.moveToFirst();
while (cursorChild.moveToNext()) {
String businessName = cursorChild.getString(cursorChild.getColumnIndex("BusinessName"));
phoneNumber = cursorChild.getString(cursorChild.getColumnIndex("ph_Phone"));
String landMark = cursorChild.getString(cursorChild.getColumnIndex("LandMark"));
ChildInfo childInfo = new ChildInfo(businessName, phoneNumber, landMark);
childList.add(childInfo);
}
childDataHashMap.put(categoryDescription, childList);
} while (cursor.moveToNext());
cursor.close();
}
DataBaseHelper class
public Cursor getGroupData() {
String query = "SELECT * FROM Category GROUP BY categorydesc";
return db.rawQuery(query, null);
}
public Cursor getChildData(int CategoryId) {
String query = "SELECT * from Category WHERE CategoryId = '" + CategoryId + "' LIMIT 3" ;
return db.rawQuery(query, null);
}
On load more tab click I have to fetch data from Sqlite db and set it to Expandable list view.Can anyone please suggest me how to avoid repetition of data fetching from Sqlite and maintain count of data fetched.

Issue in Data filled in Spinner from Database

I have an External Database into assets folder. I have been successful into loading it on my Emulator and performing operations on it.
I also know how to fill data using queries in Spinner and ListView.
The main issue: I am running a query which gives me all data from the table. I store them in a Bean class. Now i have successfully filled one of the column data into a spinner.
BUT, when i open the spinner, i don't get Database values but object name into spinner
FOR e.g -- com.mypackageName.BeanPackage.BeanClass#411da123
I get the whole spinner full of this, not the Data which is in Database( e.g 13, 13/1) .
My Code :
Query in DBHelper Class :
public Cursor getBusNumbers() {
// date="21-10-2013";
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
return db.rawQuery("select * from table", null);
}
In My Main Activity :
Adapter code :
adapter = new Adapter(MainActivity.this,android.R.layout.simple_spinner_item, array);
route.setAdapter(adapter);
adapter.notifyDataSetChanged();
My GetView method:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = ((LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(layout, null);
}
final Bean item = items.get(position);
final TextView km = (TextView) convertView
.findViewById(android.R.id.text1);
km.setText(item.getRouteNumber());
km.setTextSize(22);
return convertView;
}
}
Method which fills the Array :
private void loadFieldDatabase() {
Cursor c = dbhelper.getBusNumbers();
if (c != null && c.getCount() > 0) {
c.moveToFirst();
for (int count = 0; count < c.getCount(); count++) {
Bean detail = new Bean();
detail.setRouteNumber(c.getString(c
.getColumnIndex("route_number")));
array.add(detail);
c.moveToNext();
}
c.close();
//dbhelper.close();
}
Here in your code your setting the Bean object into the Text view insted of which item you need to set that.
Try this code this may help you.
private void loadSpinnerCourse() {
// TODO Auto-generated method stub
List<String> lables = getAllCourse();
// Creating adapter for spinner
dataAdapterCourse = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
dataAdapterCourse
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
mLesson_course.setAdapter(dataAdapterCourse);
}
private List<String> getAllCourse() {
// TODO Auto-generated method stub
List<String> labels = new ArrayList<String>();
mCoureseIdList = new ArrayList<String>();
ExamDatabaseConnector dbConnector = new ExamDatabaseConnector(
getActivity());
dbConnector.open();
String selectQuery = "SELECT * FROM courses_stud";
Cursor cursor = dbConnector.database.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
mCoureseIdList.add(cursor.getString(0));
labels.add(cursor.getString(1));
} while (cursor.moveToNext());
}
// closing connection
cursor.close();
dbConnector.database.close();
// returning lables
return labels;
}
Cursor cursor = db.getAllBhashat();
SpinnerArr = new String[cursor.getCount()+1];
SpinnerArr[0] = "<-SELECT->";
if(cursor.moveToNext()){
int i = 1;
do {
SpinnerArr[i] = cursor.getString(cursor
.getColumnIndex("LocalityTitle_E"));
i++;
} while (cursor.moveToNext());
}if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
ArrayAdapter<String> adapter_sorCat = new ArrayAdapter<String>(
this, android.R.layout.simple_spinner_item, SpinnerArr);
Spinner.setAdapter(adapter_sorCat);
adapter_sorCat
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}

android: Query SMS Unique DisplayName(s) Efficiently

I'm trying to write an activity that shows the DisplayNames of contacts evolved in SMS conversations.
Unfortunately:
The SMS database doesn't contain the DisplayName
so I used a function that uses the address "phone number" to get the DisplayName
I don't know how to query unique addresses from the SMS database
so I used sorted query, used a loop to find unique DisplayNames, and then put them in an array
If not, is it better to run this process in the background? but how will the activity open if the list is not prepared yet?!
Finally, I used this array in an ArrayAdapter to populate my ListView (pretty much trying to mimic the native Messaging app)
The activity turned out to take a lot of time to open up (around 2-3 seconds, and I don't have much messages)
Is there a way to solve any or both of my problems efficiently?
Here's my code
public class MessagesPicker extends Activity {
Cursor myCursor;
ListView pickerListView;
public static final String MessageAddress = address;
public static final String MessageID = _id;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picker);
ContentResolver cr = getContentResolver();
myCursor = cr.query(Uri.parse(contentsms), null, null, null, MessageAddress + ASC); //getting sorted data to easy finding uniqueness
/**setting up unique DisplayNames array**/
int allCount = myCursor.getCount(), uniqueCount = 0;
String[] uniqueNames = new String[allCount];
String temp1,temp2;
myCursor.moveToFirst();
temp1 = getContactDiplayNameByAddr();
uniqueNames[uniqueCount++] = temp1;
do {
temp2 = getContactDiplayNameByAddr();
if (temp1.compareTo(temp2) != 0){
uniqueNames[uniqueCount++] = temp2;
temp1 = temp2;
}
}while(myCursor.moveToNext());
String [] valuesArray = new String[uniqueCount]; //filling the array
for (int i = 0 ; i uniqueCount ; i++)
valuesArray[i] = uniqueNames[i];
/**setting up the ListView**/
ArrayAdapterString adapter = new ArrayAdapterString(this, android.R.layout.simple_list_item_multiple_choice, valuesArray);
pickerListView = (ListView)findViewById(R.id.PickerLV); //linking the object to the interface
pickerListView.setAdapter(adapter); //setting the adapter
pickerListView.setItemsCanFocus(false); //allowing to check the checkbox
pickerListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); //allowing multiple choices
}
String getContactDiplayNameByAddr() { //this function returns DisplayName, or if not available, returns the address
String Address = myCursor.getString(myCursor.getColumnIndex(address));
Uri personUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Address);
Cursor cur = getContentResolver().query(personUri,
new String[] {PhoneLookup.DISPLAY_NAME},
null, null, null );
if( cur.moveToFirst() ) {
String DisplayName = cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME));
cur.close();
return DisplayName;
}
return Address;
}
}

Categories

Resources