I wanted to learn how to use sqlite in android so I used the following code from a tutorials website but when I ran it , If I delete the first entry in the listview the next entry would give
android.database.CursorIndexOutOfBoundsException: Index -1 requested,
with a size of 0 in the DisplayContact class.
So I wanted to know how to fix it, I don't know if the problem is in the listview or the arraylist.
Thanks in advance.
Here is the code which shows the error
Bundle extras = getIntent().getExtras();
if (extras != null)
{
int Value = extras.getInt("id");
if (Value > 0)
{
Cursor rs = mydb.getData(Value);
id_To_Update = Value;
if (rs != null && rs.getCount() > 0)
{
rs.moveToFirst();
}
String dat = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_DATE));
String emai = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_EMAIL));
String stree = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STREET));
String plac = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_CITY));
String nam = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_NAME));
if (!rs.isClosed())
{
rs.close();
}
And here is the code to delete an entry
case R.id.Delete_Contact: AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.deleteContact)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
mydb.deleteContact(id_To_Update);
Toast.makeText(getApplicationContext(), "Deleted Successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
} )
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{ }
}
);
AlertDialog d =builder.create();
d.setTitle("Are you sure?");
d.show();
return true;
default:
This is the logcat output 05-20
12:59:33.953 E/AndroidRuntime(25513): Process: com.myelse.sqlcontacts, PID: 25513
05-20 12:59:33.953 E/AndroidRuntime(25513): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myelse.sqlcontacts/com.myelse.sqlcontacts.DisplayContact}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
05-20 12:59:33.953 E/AndroidRuntime(25513): at com.myelse.sqlcontacts.DisplayContact.onCreate(DisplayContact.java:51)
Edit: This is the code for the arraylist and arrayadapter in the mainactivity
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mydb = new DBHelper(this);
ArrayList arraylist = mydb.getAllContacts();
arrayadapter= new ArrayAdapter (this, android.R.layout.simple_list_item_1 ,arraylist);
arrayadapter.notifyDataSetChanged();
obj = (ListView) findViewById(R.id.listView1);
obj.setAdapter(arrayadapter);
obj.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
int id_to_search=arg2+1;
Toast.makeText(getApplicationContext(), id_to_search + "" , Toast.LENGTH_SHORT).show();
Bundle dataBundle = new Bundle();
dataBundle.putInt("id", id_to_search);
Intent intent = new Intent(getApplicationContext(), DisplayContact.class);
intent.putExtras(dataBundle);
startActivity(intent);
arrayadapter.notifyDataSetChanged();
}
}
);
}
The problem is in the line:
Cursor rs = mydb.getData(Value);
mydb.getData(Value) will return only one row, where the "id" = Value
So, when you delete this single row, the cursor returns an IndexOutOfBoundsException.
One possible solution is to modify your getData function as follows:
public Cursor getData(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from contacts, null );
return res;
}
Thanks to #parth mehta for the responce , but the only solution that I found to preserve order after deleting an entry was to copy all records to a temporary table without the id column and then moving them back to the original table after each delete.
Using insert into table 1 () select from table2.
Thanks.
Please add Notifydatsetchange() after delete event
Related
I'm having some issues with an array adapter.
this is what is in my lessonNotesList class:
mydb = new DBHelper(this);
//Creating an ArrayList of contacts data
ArrayList array_list = mydb.getAllLessonNotes();
//Creating an Array Adapter to manipulate the contacts data into a ListView
ArrayAdapter arrayAdapter = new ArrayAdapter(this,R.layout.list_layout, array_list);
//Adding the contacts to the list view.
lessonNote = (ListView)findViewById(R.id.listView1);
lessonNote.setAdapter(arrayAdapter);
//Setting an onClickListener to process the user's actions
lessonNote.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
//Prepare the data from the ListView item to be passed to new activity
//arg2 is increased by one as its a zero based index but the contacts table in the database works of a base index of 1
int id_To_Search = VALUE;
//Bundle extras = getIntent().getExtras();
Bundle dataBundle = new Bundle();
dataBundle.putInt("id", id_To_Search);
Log.d("Id is ^&*: ", String.valueOf(id_To_Search));
//Create a new intent to open the DisplayContact activity
Intent intent = new Intent(getApplicationContext(), com.example.ltss.dyslexia.app.LessonNotes.class);
intent.putExtras(dataBundle);
startActivity(intent);
}
});
DBHelper class:
public ArrayList getAllLessonNotes()
{
ArrayList array_list = new ArrayList();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from "+TABLE_LESSON_NOTES, null);
res.moveToFirst();
while(res.isAfterLast() == false)
{
array_list.add(res.getString(res.getColumnIndex(DATE)));
res.moveToNext();
}
return array_list;
}
The code crashes with a NULL pointer exception here:
lessonNote.setAdapter(arrayAdapter);
Any ideas why this is happening?
I've tried debugging and the debugger is telling me that the arrayAdatper contains 1 entry as it should
I have nearly the same code for a different page and it's working 100% fine..
Any suggestions would be welcome!
Thanks
Are you sure about that line ?
lessonNote = (ListView)findViewById(R.id.listView1);
It seems that in your layout XML, no view have "listView1" id.
hope you could help me with this problem. i want to get the rowId of a selected item in a listview from sqlite so that i can pass the value to another activity.
i already fed the listview with info from my sqlite table and use onClickedItem in the listview and use pos + 1 to get the id, but i dont want this solution because whenever i delete an item from the listview i wont be able to get the correct rowId from the database itself... this is my code :
in my DBhelper:
public List<String> getSYAList() {
List<String> List = new ArrayList<String>();
try {
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SYA ;
Cursor c = ourDatabase.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (c.moveToFirst()) {
do {
List.add((c.getString(0)) + " " +(c.getString(1)) + " "+ (c.getString(2)));
} while (c.moveToNext());
}
} catch (Exception e) {
Toast.makeText(ourContext, "Error encountered.",
Toast.LENGTH_LONG).show();
}
return List;
}
in my activity:
private void loadSYA() {
// TODO Auto-generated method stub
final DBhelper entry = new DBhelper(this);
entry.open();
final List<String> sya = entry.getSYAList();
if(sya.size()>0) // check if list contains items.
{
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(SYA.this,android.R.layout.simple_dropdown_item_1line, sya);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
sqlSYA.setAdapter(arrayAdapter);
sqlSYA.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(SYA.this,SYAInfo.class);
Bundle b = new Bundle();
b.putInt("id", (int)position + 1);
i.putExtras(b);
startActivity(i);
}
}); }
else
{
Toast.makeText(SYA.this,"No items to display",1000).show();
}
entry.close();
}
i really hope you anyone could help me to find a solution for this one. thanks in advance guys !!!
Ive been trying to get my listview to update after removing an item. Here's what I have so far:
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
String str = null;
public void onItemClick(AdapterView<?> arg0, final View view, int arg2, long arg3) {
//TextView txtview = (TextView)view.findViewById(R.id.txtview);
final String item = ((TextView) view.findViewById(R.id.txtview)).getText().toString();
str = item;
final long arr = arg3;
final String arg22 = longToString(arg3);
//Creating an Alert Dialog
AlertDialog.Builder builder = new AlertDialog.Builder(Home.this);
builder.setMessage("Are you sure you want to delete the hike " + str + " ?");
builder.setCancelable(false);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SQLiteDatabase db1=openOrCreateDatabase("hikeManager", MODE_PRIVATE, null);
DatabaseHandler db = new DatabaseHandler(Home.this);
String table = "hikes";
Cursor c = db1.rawQuery("select id from "+ table + " where name='"+item+"'", null);
int dhike = c.getColumnIndex("name") + 1;
try {
Hike hike = db.getHike(arr + 1);
db.deleteHike(hike);
Log.d("DLT", "Deleted hike at index " + arr);
//db.updateList(adapter, myList, listItems);
adapter.remove(arg22);
adapter.notifyDataSetChanged();
//updateData();
db.close();
} catch (CursorIndexOutOfBoundsException e) {
Log.d("DLT", "Failed to delete: " + e.getMessage());
db.close();
}
//db.updateList(adapter, myList, listItems);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
I Have quite a bit of unused code in there, as I have tried a few different methods to get this to work, but have failed so far. Here is updateData:
private void updateData() {
// Get all of the notes from the database and create the item list
DatabaseHandler db = new DatabaseHandler(this);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.txtview, listItems);
final ListView myList = (ListView) findViewById(R.id.cardListView);
int num = db.getHikesCount();
for (int i=1; i<num+1; ++i){
Hike name = db.getHike(i);
String nam = name.getName();
listItems.add(nam);
}
myList.setAdapter(adapter);
db.close();
}
The updateData does have some unintended consequences when I use it to update the view after adding an item to a non-empty list, but it works for now. The item is successfully deleted, since I can close the app and reload it and the item will be gone. I just cant seem to get it to update properly for me.
Just use
adapter.notifyDataSetChanged();
I am having items in a gridview which where displayed from sqlite ..Now using another thread i am fetching data from json webservice and storing the data in sqlite now i want to display the updated items in the same grid view along with the existing items..
private void displayUpdate(String Bid) {
Log.w("Update cALL","Executing Update");
System.out.println("aeqw cursor that in display table value"+getid(Bid).getCount());
Cursor cursorx =getid(Bid);
int p=Integer.parseInt(Bid);
System.err.println("Recieving Bid to displayUpdate method"+p);
if (getid(Bid) != null)
{
while(cursorx.moveToFirst())
{
Log.e("Entering Loop", "WHILE EXECUTING");
String temp_id1 = cursorx.getString(0);
System.err.println("Name related to Bid to displayUpdate method"+temp_id1);
final String temp_name1 = cursorx.getString(1);
System.err.println("Name related to Bid to displayUpdate method"+temp_name1);
String temp_author1=cursorx.getString(2);
String temp_desc1=cursorx.getString(3);
byte[] temp_image1 = cursorx.getBlob(4);
String temp_rating1 = cursorx.getString(5);
String temp_price1 = cursorx.getString(6);
String temp_update1=cursorx.getString(7);
System.err.println("Name related to Bid to displayUpdate method"+temp_name1);
mapIdUp.add(temp_id1);
mapNameUp.add(temp_name1);
mapAuthorUp.add(temp_author1);
mapDescUp.add(temp_desc1);
mapRatingUp.add(temp_rating1);
mapPriceUp.add(temp_price1);
mapUp.add(temp_image1);
mapUpdatedUp.add(temp_update1);
Log.e("temp_id from the sqlite", temp_id1);
Log.i(temp_name1, temp_name1);
Log.i(temp_desc1, temp_desc1);
Log.i(temp_rating1, temp_rating1);
Log.e(temp_update1,temp_update1);
String[] captionArray1 = (String[]) mapNameUp.toArray(new String[mapNameUp.size()]);
ItemsAdapter itemsAdapter1 = new ItemsAdapter(
Bookicon.this, R.layout.item,captionArray1);
gridView1=(GridView)findViewById(R.id.list);
gridView1.setAdapter(itemsAdapter1);
itemsAdapter1.notifyDataSetChanged();
gridView1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
Intent i = new Intent(getApplicationContext(), DetailsActivity.class);
i.putExtra("id", position);
startActivity(i);
}
});
break;
}
}
}
this method is called in the second thread to display the updated books ..
where are this method is used to display all the items in the sqlite table
private void getDataAndPopulate()
{
Log.w("hello","zyuk,");
Cursor cursor = getEvents("bcuk_book");
while (cursor.moveToNext())
{
String temp_id = cursor.getString(0);
final String temp_name = cursor.getString(1);
String temp_author=cursor.getString(2);
String temp_desc=cursor.getString(3);
byte[] temp_image = cursor.getBlob(4);
String temp_rating = cursor.getString(5);
String temp_price = cursor.getString(6);
String temp_update=cursor.getString(7);
mapId.add(temp_id);
mapName.add(temp_name);
mapAuthor.add(temp_author);
mapDesc.add(temp_desc);
mapRating.add(temp_rating);
mapPrice.add(temp_price);
map.add(temp_image);
mapUpdated.add(temp_update);
Log.e("temp_id from the sqlite", temp_id);
Log.i(temp_name, temp_name);
Log.i(temp_desc, temp_desc);
Log.i(temp_rating, temp_rating);
Log.e(temp_update,temp_update);
String[] captionArray = (String[]) mapName.toArray(new String[mapName.size()]);
ItemsAdapter itemsAdapter = new ItemsAdapter(
Bookicon.this, R.layout.item,captionArray);
gridView=(GridView)findViewById(R.id.list);
gridView.setAdapter(itemsAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
Intent i = new Intent(getApplicationContext(), DetailsActivity.class);
i.putExtra("id", position);
startActivity(i);
}
});
}
}
Issue is i am not able to display the updated one whereas it was showing already stored items ..
If let us assume there are items like 1,2,3,4,5 when i update new item with 6 i.e one record it is displaying first item i.e 1. If update 2 records then it displaying only first two records..
How to solve this issue
I have a listview that when clicked opens up but doesnt display detailed information about that list view item. The data for the listview is entered in by a class into a sqlite datase and pulled from a sqlite database by another class. Not sure where I went wrong with the class the should pul the data when a list viewitem is clicked. I do not have enough pont to post imaged of the related xml files but the onClick methods are below
Listview:
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Toast.makeText(getApplicationContext(), "clicked on :" + arg2, Toast.LENGTH_SHORT).show();
Intent updateDeleteLoginInfo = new Intent (this, UpdateDeleteLoginList.class);
LoginDetails clickedObject = loginArrayList.get(arg2);
Bundle loginBundle = new Bundle();
loginBundle.putString("clickedwebSite",clickedObject.getsName());
loginBundle.putString("clickedwebAddress",clickedObject.getwUrl());
loginBundle.putString("clickeduserName",clickedObject.getuName());
loginBundle.putString("clickedpassWord",clickedObject.getpWord());
updateDeleteLoginInfo.putExtras(loginBundle);
startActivity(updateDeleteLoginInfo);
Update Class:
#Override
public void onClick(View v){
loginSitetext = sName.getText().toString();
loginAddresstext = wUrl.getText().toString();
loginUsertext = uName.getText().toString();
loginpassWordtext = pWord.getText().toString();
LoginDetails loginDetails = new LoginDetails();
loginDetails.setsName(bundledWebSite);
loginDetails.setwUrl(bundledWebAddress);
loginDetails.setuName(bundledUserName);
loginDetails.setpWord(bundledPassWord);
if(v.getId()==R.id.rucBttn){
finish();
}else if(v.getId()==R.id.ruuBttn){
updateLoginDetails(loginDetails);
}else if(v.getId()==R.id.rudBttn){
deleteLoginDetails(loginDetails);
}
}
private void updateLoginDetails(LoginDetails loginDetails){
dataStore androidOpenDbHelper = new dataStore(this);
SQLiteDatabase sqliteDatabase = androidOpenDbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(dataStore.COLUMN_NAME_SITE, loginSitetext);
contentValues.put(dataStore.COLUMN_NAME_ADDRESS, loginAddresstext);
contentValues.put(dataStore.COLUMN_NAME_USERNAME, loginUsertext);
contentValues.put(dataStore.COLUMN_NAME_PASSWORD, loginpassWordtext);
String[] whereClauseArgument = new String[1];
whereClauseArgument[0]= loginDetails.getsName();
System.out.println("whereClauseArgument[0] is :" + whereClauseArgument[0]);
sqliteDatabase.update(dataStore.TABLE_NAME_INFOTABLE, contentValues, dataStore.COLUMN_NAME_SITE+"=?", whereClauseArgument);
sqliteDatabase.close();
finish();
}
private void deleteLoginDetails(LoginDetails deleteLoginDetails){
dataStore androidOpenDbHelper = new dataStore(this);
SQLiteDatabase sqliteDatabase = androidOpenDbHelper.getWritableDatabase();
String[] whereClauseArgument = new String[1];
whereClauseArgument[0] = deleteLoginDetails.getsName();
sqliteDatabase.delete(dataStore.TABLE_NAME_INFOTABLE,dataStore.COLUMN_NAME_SITE+"=?", whereClauseArgument);
sqliteDatabase.close();
finish();
you can use notifyDataSetChanged() function to achive updating the listView.
or
assign a new adapter evrytime you update list that needs updating.
Found the 'C' in whereClauseArgument in another class was not capatalized. After capitalizing it every thing worked as it should.