I'm currently creating an app that downloads lists from a server and places those lists into an SQLite database. In the Mainactivity it calls the lists from the db and places them into a custom adapter, everything works fine and such.
After this I go through several screens to proces the listdata and in the final activity it uses a query to delete the row it's been working on from the db. I use logcat to print the db after this and it shows that the row has been deleted.
Next it takes me back to the Mainactivity and in its onResume I once again load the lists from the db only to find that the row that should have been deleted is still in it. The listview is being updated correctly, it's really an issue of retrieving data from the database that should have been deleted.
So, anybody has an idea why I get rows that have been deleted in another activity?
Mainactivity:
private List<String> list = new ArrayList<>();
public void onResume() {
super.onResume();
context = getApplicationContext();
ConsLoadListDataSource cllDataSource = new ConsLoadListDataSource(context);
cllDataSource.open();
list = cllDataSource.sqliteToListIds();
cllDataSource.close();
logcat("Jadajada: " + list.toString());
}
SQLiteHelper:
public List<String> sqliteToListIds() {
List<String> conList= new ArrayList<>();
if (!db.isOpen()) {
open();
}
Cursor cursor = db.query(ConsLoadListSQLHelper.TABLE_CONS_HEADER,
allConsListColumns, null, null, "loadlist" , null, "loadlist");
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
conList.add(cursor.getString(1));
cursor.moveToNext();
}
db.close();
return conList;
}
The deleting method works, but since it's being asked for:
public void deleteList(int id) {
if (!db.isOpen()) {
open();
}
db.delete(ConsLoadListSQLHelper.TABLE_CONS_HEADER,
ConsLoadListSQLHelper.CONS_HEADER_ID + " = " + id, null);
db.close();
}
edit
I've found a workaround solution by deleting the row on my server and once again retrieving all data from the server before I go back to my MainActivity, but I still don't know how to solve the original problem and this makes my app more dependent on an internet connection, so it's not perfect, but will have to do for now.
For deleting single item you have to use
public void deleteRule(String value) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(Table_Name, Key_value + " = ?",
new String[] { value });
db.close();
}
Hope it helps.
Related
I'm creating a forum application and I currently if I delete a thread I'm deleting all threads.
Is there a good method or query to check if the UserId == ThreadId?
My current code:
public void deleteThread() {
SQLiteDatabase db = this.getWritableDatabase();
// Delete All Rows
db.delete(TABLE_THREAD, null, null);
db.close();
Log.d(TAG, "Deleted all Thread info from sqlite");
}
You need to pass correct value to the well-documented delete method to narrow down the scope of deletion to a subset of all entries in the DB table.
public void deleteThreadById(String threadId) {
SQLiteDatabase db = this.getWritableDatabase();
String whereClause = "threadId = " + threadId;
db.delete(TABLE_THREAD, whereClause, null);
db.close();
}
Deleting all threads of a given user via their userId would be similar but probably doesn't make sense in a forum software.
This is how SQL works in general and it's a bit scary you started development without familiarising yourself with the very basics.
Something like this;
public void deleteThread(String threadName) {
SQLiteDatabase db = this.getWritableDatabase();
try {
db.delete(MYDATABASE_TABLE, "name = ?", new String[]{threadName});
} catch (Exception e) {
e.printStackTrace();
} finally {
db.close();
}
}
Something long these lines, querying database to find the specific row that has column which matches the parameter.
For example to delete a row which the name column is "Hello World";
deleteThread("Hello World");
I am new to android development and have come across a problem with deleting a row in a SQLite table that I have not been able to find a solution to. When I try to delete a row nothing is happening.
In my activity, called 'MainActivity,' I am using a context menu to call a method to delete an item from the list. This portion of code is as follows:
case R.id.delete_program:
DBAdapter adap = new DBAdapter(this);
adap.open();
long pass = (long) (position + 1);
adap.removeFromCurrent(pass);
adap.close();
Runnable run = new Runnable() {
public void run(){
refreshCurrent(getApplicationContext());
}
};
runOnUiThread(run);
proAdapt.notifyDataSetChanged();
return true;
In 'DBAdapter' the method removeFromCurrent():
public boolean removeFromCurrent(long cp_id) {
return this.dB.delete(PROGRAMS_TABLE, CP_ID + '=' + cp_id, null) > 0;
}
In 'MainActivity' the method refreshCurrent():
public static void refreshCurrent(Context context) {
CURRENT.clear();
DBAdapter adap = new DBAdapter(context);
adap.open();
ArrayList<Program> temp = adap.getCurrentPrograms();
for(Program item : temp) {
Toast.makeText(context, "Item added: " + item.getName(), Toast.LENGTH_SHORT).show();
CURRENT.add(item);
}
adap.close();
}
I'm using the toast to check if the table has changed but the display has not.
From 'DBAdapter' the method getCurrentPrograms():
public ArrayList<Program> getCurrentPrograms() {
ArrayList<Program> list = new ArrayList<Program>();
Cursor cursor =
this.dB.query(PROGRAMS_TABLE, new String[] {
CP_ID, CP_NAME, ACTUAL_DAY, D_ID, CP_CYCLE, CP_DAY_ONE },
null, null, null, null, null);
int rows = cursor.getCount();
if(cursor != null)
cursor.moveToFirst();
for(int i = 1; i <= rows; i++) {
list.add(new Program(cursor.getString(cursor.getColumnIndex(CP_NAME)),
cursor.getInt(cursor.getColumnIndex(ACTUAL_DAY)),
cursor.getInt(cursor.getColumnIndex(CP_DAY_ONE)),
cursor.getInt(cursor.getColumnIndex(CP_CYCLE))));
cursor.moveToNext();
}
return list;
}
The ArrayList 'CURRENT' is the list used to populate the ListView. My thinking was that I would be able to delete a row from the table and then repopulate this list as well as the ListView. I was also curious as to what happened to a SQLite table once a row is removed; do the other rows move up a position, or do they stay in the same place?
I am still very new to this so any help about my problem or tips for the rest of my code would be much appreciated. Let me know what else I'm doing wrong with my programming.
If you are using the SQLiteOpenHelper you should be getting a SQLiteDatabase object and then using a transaction, if you don't set it as successful then nothing will happen
SQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
//Do stuff
db.setTrasactionSuccessfull();
db.endTransaction();
Also I think when you pass null into the where clause the where doesn't matter.
You should have something like db.delete("tbl", "id=?", new String[]{String.valueOf(id)});
I am displaying data pulled from the Android OS sqlite database. I am successfully getting the items to delete when I click on them. However I am having an issue refreshing, or updating the listview after the operation.
Below is the code where I delete the contact.
deleteBtn = (Button)v.findViewById(R.id.deleteBtn);
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Deleted: " + c.getId() + " " + c.getName(), Toast.LENGTH_SHORT).show();
adapter.deleteContact(c.getId());
updateList();
}
});
Below is the updateList() method:
public void updateList(){
myList.refreshDrawableState();
myList.invalidateViews();
this.notifyDataSetChanged();
}
I included in this method all three ways I tried to refresh but none worked for me. Any idea how I might achieve this?
EDIT: I changed my code thinking this would be the solution but it did not work either:
DbAdapter class delete method():
public boolean deleteContact(int rowId){
getAllContactsList();
return db.delete(DB_TABLE, COLUMN_ID + "=" + rowId, null) > 0;
}
getAllContactsList():
public List<Contact> getAllContactsList(){
List<Contact> contactList = new ArrayList();
Cursor c = db.query(DB_TABLE, new String [] {COLUMN_ID, COLUMN_FNAME, COLUMN_LNAME}, null, null, null, null, null);
//loop through cursor rows and add to list
if(c.moveToFirst()){
do{
Contact contact = new Contact();
contact.setId(Integer.parseInt(c.getString(0)));
contact.setfName(c.getString(1));
contact.setlName(c.getString(2));
contactList.add(contact);
}while(c.moveToNext());
}
return contactList;
}public List<Contact> getAllContactsList(){
List<Contact> contactList = new ArrayList();
Cursor c = db.query(DB_TABLE, new String [] {COLUMN_ID, COLUMN_FNAME, COLUMN_LNAME}, null, null, null, null, null);
//loop through cursor rows and add to list
if(c.moveToFirst()){
do{
Contact contact = new Contact();
contact.setId(Integer.parseInt(c.getString(0)));
contact.setfName(c.getString(1));
contact.setlName(c.getString(2));
contactList.add(contact);
}while(c.moveToNext());
}
return contactList;
}
I thought by getting a new cursor before deleting the contact It would update the list accordingly. Unfortunately It made no difference. Any ideas ?
You have to notify the list's adapter that you have modified the underlying data.
Try using adapter.notifyDataSetChanged();
It seems that you have the Database Adapter class, but you're missing the ArrayAdapter class, which is intended to manage the list of items, displayed in your ListView. Take a look at this example, specifically at the WeatherAdapter.java class.
If I am wrong in my assumptions and the adapter object in your code is not a database adapter, but an ArrayAdapter class, try putting adapter.notifyDataSetChanged() instead of this.notifyDataSetChanged().
Let me know if this helped.
You must requery and and generate new list:
public void updateList(){
clear();
addAll(contactsDbHelper.getAllContactsList()); //addAll works since 11 API version.
notifyDataSetChanged(); //need this is you dissabled auto notify
}
P.S. You should done this job with using Content providers and CursorAdapter, but you need manually notify content provider about changes, because Cursor.requery() is deprecated since 11 version.
I have read so many posts about how to populate the listview from a database. but i simply cant do it on my app! i dont know what im doing wrong. I´m very new to programming so there are allot of things i dont understand but im trying to learn :)
I add items to the database without any problems using this code in the activity:
String selectedstone = (String) stonespinner.getSelectedItem();
String weight = etaddweight.getText().toString();
db.addStone(new MyStonesDatabase(selectedstone, weight));
in the DatabaseHandler.java i have this:
// Adding new stone
void addStone(MyStonesDatabase stone) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_STONE, stone.getStone());
values.put(KEY_WEIGHT, stone.getWeight());
// Inserting Row
db.insert(TABLE_MYSTONES, null, values);
db.close(); // Closing database connection
}
I can see that my database gets populated by running this:
Log.d("Reading: ", "Reading all items..");
List<MyStonesDatabase> items = db.getAllstones();
for (MyStonesDatabase cn : items) {
String log = "Id: " + cn.getID() + ", Stone: "
+ cn.getStone() + ", Weight: " + cn.getWeight();
// Writing Items to log
Log.d("Name: ", log);
}
But when trying to have a listview to show the database my app either crashes or dont show anything. In my DatabaseHandler.java i have this:
// Getting All items from database
public List<MyStonesDatabase> getAllstones() {
List<MyStonesDatabase> stoneList = new ArrayList<MyStonesDatabase>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_MYSTONES;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
MyStonesDatabase stone = new MyStonesDatabase();
stone.setID(Integer.parseInt(cursor.getString(0)));
stone.setStone(cursor.getString(1));
stone.setWeight(cursor.getString(2));
// Adding stone to list
stoneList.add(stone);
} while (cursor.moveToNext());
}
// return stonelist
return stone;
}
I dont know what to put in my activity that should show the listview.
public class MyStones extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Can someone please help me, im about to give up hehe :)
thanks!
Here is a great article/tutorial that might help you. Populating your listView isn't as simple as just doing something in your Activity. You need to create a listAdapter and a couple other things. In the tutorial, they use hard-coded values, in an array. You might try getting that to work, then removing the hard-coded data, and using the data you are getting from your DB.
Getting this to work is a little trickier than you might think, but not overly complicated.
Hope this helps:
http://www.ezzylearning.com/tutorial.aspx?tid=1763429
i'm working on a android app that will display Strings to the user, and the user then has the option to add one to a favorite list. I have searched and searched and cannot find the proper way of doing this. I did get one open source project, everything worked until the user removed a favorite. The database would clear the row of data, but when a new row is added, it would behave as if the deleted row still had data, leaving blanks in the favorite list.
this is my insert method
public long insertString(String newString)
{
ContentValues newStringValue = new ContentValues();
newStringValue.put(KEY_STRING, newString);
return db.insert(DATABASE_TABLE, null, newStringValue);
}
the long returned will always increment even if i use the remove method:
public boolean removeString(long _rowIndex)
{
return db.delete(DATABASE_TABLE, KEY_ID + "=" + _rowIndex, null) > 0;
}
if i try to remove the third index, and the user removed a question at the third index, the method returns false, is there a way to completely remove all rows with no data?
You should use a CursorAdapter or ResourceCursorAdapter and when you modify the data call cursor.requery() to refresh everything.
Maybe just encode String List as something like JSON, then save as long string (blob / clob)? I would use Jackson JSON processor, but there are many alternatives to choose from (Guice, or XStream if you prefer XML). I mean, assuming you don't really need relational aspects of data (no need to find users with specific list entry by querying) but just need to persist lists.
public static class OrderManager
{
private MyDBOpenHelper _db_Orders;
private static final String GET_Orders = “SELECT * FROM “+Order_TABLE_NAME ;
public OrderManager(Context context)
{
_db_Orders = new MyDBOpenHelper(context);
}
public boolean insert(String orderName, String orderStatus)
{
try
{
SQLiteDatabase sqlite = _db_Orders.getWritableDatabase();
/*
sqlite.execSQL(“INSERT INTO “+ Order_TABLE_NAME +
” (” + KEY_NAME +”, “+ KEY_STATUS + “)” +
” VALUES (‘” + orderName + “‘, ‘” + orderStatus + “‘)”);
*/
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, orderName);
initialValues.put(KEY_STATUS, orderStatus);
sqlite.insert(Order_TABLE_NAME, null, initialValues);
}
catch(SQLException sqlerror)
{
Log.v(“Insert ERROR”, sqlerror.getMessage());
return false;
}
return true;
}
public ArrayList<Order> getOrders()
{
ArrayList<Order> orders = new ArrayList<Order>();
SQLiteDatabase sqliteDB = _db_Orders.getReadableDatabase();
Cursor crsr = sqliteDB.rawQuery(GET_Orders, null);
Log.v(“Select Query result”, String.valueOf(crsr.getCount()) );
crsr.moveToFirst();
for(int i=0; i < crsr.getCount(); i++)
{
orders.add(new Order(crsr.getString(0), crsr.getString(1)));
//Log.v(“DATA”, crsr.getString(0) + ” ” +crsr.getString(1));
crsr.moveToNext();
}
return orders;
}
}