Good evening everyone
Brief overview before a greater explanation. I currently have a SQL database which feeds into an arraylist thanks to a modal, we then feed this arraylist to our recycle view adapter which then populates the row.
Now i'm trying to build in the option for the user to select a row and then a check becomes true and tick is displayed. As you all currently know if the state is not stored then it start moving to random rows or being removed completely.
Lets start at the beginning with my SQL Lite database. Three simple rows Title , Description and checkbox state. Note that when a new row is added to the sql he checkbox column is automatically set to false.
Snippet below of the SQL query used to populate my recyclerView adapter
ArrayList<NoteInfoModal> noteInfoModalArrayList = new ArrayList<>();
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + Primary_Table + " ORDER BY Col_DateOrder ASC", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()){
NoteInfoModal noteInfoModal = new NoteInfoModal();
noteInfoModal.setNoteName(cursor.getString(cursor.getColumnIndex(Col_NoteTitle)));
Applying it to the adapter
homeScreenAdapter = new HomeScreenAdapter(getContext(), primaryDatabase.populateHomeScreenOldestFirst(), filterOption, HomeScreenFragment.this);
Finally binding the information inside the adapter to the correct view (This one is for the check box)
((CustomViewHolder) holder).chkNote.setChecked(Boolean.valueOf(noteInfoModal.noteCheckBox));
Now I understand that I could simply update the row of the SQL DB to be true as this will then save the state, but if the user closes and then opens the app again I want them all to unchecked / false each time
Just looking for another way of approaching this issue.
Thank you
I thought I would input the current way in which I have resolved the issue.
Now when the user click a check box it will update the SQL to become true or false and because I want all results to be false upon app reopening I have implemented a small section of SQL Lite code which will set a column to false for me.
public boolean checkboxStateColumn ()
{
SQLiteDatabase db = this.getReadableDatabase();
ContentValues args = new ContentValues();
args.put(Col_CheckedRow, "false");
int i = db.update(Primary_Table, args, Col_CheckedRow + "=" + Col_CheckedRow , null);
return i > 0;
}
Related
In my project, I use SQL (SQLite since its android) to save my data.
I encountered some odd problem:
In my application, I have three tabs and in order to know which data belong to which tab I have in my chart a column for each tab. the number in the column (Integer) represent if and how many of that data suppose to be in this tab.
So, when the tab initialized, it reads from the chart, and using the relevant column, it can tell which data needs to be read and how many.
When I retrieve data from the server (the database of the server is not related to the problem at hand), I check if the data is new or that I already have a similar one in my SQL DB. If its new, I add it to the SQL chart and put 1 in the relevant column. If it already exists, it checks if the data in the SQL is updated (it update the data if necessary) and add 1 to the relevant column (the same column it puts 1 in it in case the data is not in the SQL DB).
now here's my problem:
when it reads from the SQL DB to see the number in the column, so it can add 1 to it and then update the chart, it always return 1 regardless the actual number that in the column in that moment (I know its not really 1 because when I read from the DB in the same column from other places in my app it does read the actual number).
Since in other places in my app it doesn't happen I tried to see what is the difference between the places but I did not find anything wrong (the only difference is that I used WritableDatabase instead of just ReadableDatabase in that time but that should not be an issue as far as I know, at least not in such case).
the code where the problem occurs (the problem is with COL_CART):
writable = db.getWritableDatabase();
Cursor cursor = writable.query(
ShopContract.ShopChart.TABLE_NAME,
new String[]{ShopContract.ShopChart.COL_NAME, ShopContract.ShopChart.COL_PRICE, ShopContract.ShopChart.COL_PIC, ShopContract.ShopChart.COL_CART},
ShopContract.ShopChart.COL_PROD_ID + " = '" + product.getProd_id() +"'",
null,
null,
null,
null
);
if(cursor.moveToFirst()){
//check if the data match, if not, replace.
if(!cursor.getString(cursor.getColumnIndex(ShopContract.ShopChart.COL_NAME)).equals(product.getName())){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_NAME,product.getName());
update(values);
}
if(cursor.getDouble(cursor.getColumnIndex(ShopContract.ShopChart.COL_PRICE)) != product.getPrice()){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_PRICE,product.getPrice());
update(values);
}
if(!cursor.getString(cursor.getColumnIndex(ShopContract.ShopChart.COL_PIC)).equals(product.getPicture())){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_PIC,product.getPicture());
update(values);
}
//check how many there are already in cart (already in the cursor) and update it to be ++
Log.d(TAG, "run: the number in col_cart is: " + cursor.getInt(cursor.getColumnIndex(ShopContract.ShopChart.COL_CART)));
int inCart = cursor.getInt(cursor.getColumnIndex(ShopContract.ShopChart.COL_CART)) + 1; // because of the new product we just added
Log.d(TAG, "run: inCart = " + inCart);
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_CART,inCart);
Log.d(TAG, "run: change cart");
update(values);
edit:
here is the update method code (the writable is being initialized in the code above):
private SQLiteDatabase writable;
private void update(ContentValues values){
writable.update(ShopContract.ShopChart.TABLE_NAME, values, ShopContract.ShopChart.COL_PROD_ID + " = '" + product.getProd_id() +"'",null);
}
I'm currently trying to retrieve values from my SQLite Database. Screenshot
And output the value of the subname and units on checkboxes. I'm pretty sure I just have to get the IDs so I could output the subname and units values as checkboxes, so subname + unit = 1 checkbox. Could you please provide a sample code or link me a tutorial on how to do this? I'm rather clueless on how to do this and really new to Android.
I'm also looking for a way on how to save their IDs afterwards and add them into another table, so when I retrieve the IDs it will output the values. If you know how to do this too please do help. Thank you! Your time is much appreciated
Currently I have this in my DatabaseHandler.java. I just really don't know the code or syntax on how to retrieve it in my MainActivity and output it on checkboxes.
//get all subjects
public List < Subject > getAllSubjects() {
List < Subject > subjectList = new ArrayList < Subject > ();
//select all query
String selectQuery = " SELECT * FROM " + TABLE_SUBJECTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
//loop through all rows and add it to list
if (cursor.moveToFirst()) {
do {
Subject subject = new Subject();
subject.setID(Integer.parseInt(cursor.getString(0)));
subject.setSubName(cursor.getString(1));
subject.setUnits(cursor.getString(2));
//ADD CONTACT TO LIST
subjectList.add(subject);
} while (cursor.moveToNext());
}
return subjectList;
}
this is my query
SELECT *
FROM articles
WHERE id >1
ORDER BY id ASC
LIMIT 1
my requirement is very simple. I just want to select only one record and bind to textViews . This is what I had done so far.
public Article oneRecord()
{
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM articles WHERE id=3;", null);
if(c.moveToFirst()){
Article a= new Article();
a.setId(c.getString(c.getColumnIndex("id")));
a.setImage_url(c.getString(c.getColumnIndex("image_url")));
a.setTitle(c.getString(c.getColumnIndex("title")));
a.setBody(c.getString(c.getColumnIndex("body")));
}
return a;
}
I am not sure I have understood you problem correctly or not. However there is not special thing to do. Just update TextView after getting article from database.
Article a = getOneRecordFromDB();
titleView.setText(a.getTitle());
bodyView.setText(a.getBody());
I am fairly new to Android and trying to learn how things work module by module. Here's what I am trying to do:
Show a word with a favorite checkbox (image). If a user taps on it then the database is updated and a column in database table stores its value (1 for checked, 0 for unchecked). I am using a cursor to retrieve values of both the word and favorite checkbox. Tapping on the favorite image correctly updates the database without any problem.
The problem I am facing is:
Unless I exit the application and start it again, the cursor doesn't fetch the recent changes made to the database. To explain it further, when I navigate to the next/previous word (using a button at the bottom of screen) the values retrieved aren't the latest ones i.e it seems like the cursor still has the old database values and not the updated ones.
I did search through Google, StackOverflow to get a concrete solution but it seems like I am not using the right search terms. I know this has something to do with updating cursor and the fact that requery is depreciated but again I have lost direction.
[EDIT] Using the below mentioned method to get Cursor:
public Cursor getWords() {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String[] sqlSelect = {"_id", "word", "favourite"};
String sqlTables = "word_list";
qb.setTables(sqlTables);
Cursor c = qb.query(db, sqlSelect, null, null,
null, null, null);
c.moveToFirst();
return c;
}
This method is called when user taps on favorite image to update the database:
public void setFavWord(int markFav, int wordPos) {
SQLiteDatabase db = getWritableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
ContentValues values = new ContentValues();
values.put("favourite", markFav);
db.update("word_list", values, "_id = " + wordPos, null);
}
A cursor is not dynamic; it shows a snapshot of the database at the time the query was executed.
When the database changes, you must execute the query again.
As suggested by #Sreekanth in comments section, I am updating the cursor whenever favorite image is tapped. Although it is working just fine but I think it as a workaround rather than a solution. Maybe I am wrong in saying so.
I would like to create a FIFO table in order to save only the most 50 recent infomations by deleting the oldest elements when a new infomation arrives. I can do it by manipulating ID in the table but I don't think it is the best solution. Any idea of doing it well?
Instead of checking for date time, sorting your items, and whatnot, you can just assume that the first row in your table is the last to be inserted.
In your Content Provider's insert(Uri uri, ContentValues cv), before doing your db.insert call, you can first query the number of items on that table using getCount() and delete the first row if count>50. Then proceed with your insert call.
You dont need to play with IDs in order to create a FIFO logic. The best would be to add another column as DATETIME in your table which automatically inserts current time-stamp that will help you to select records in ascending order with respect to this column. Your new column should be something like:
DateAdded DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
Make sure when ever you insert new record, you must do a COUNT check of total records in this table and if necessary delete the oldest record with respect to DateAdded. Moreover, you can make use of LIMIT and/or MAX in your select-query when it comes to delete the oldest record.
Add a datetime type column to your table if it doesn't contain it yet and set it to 'now' on each insert. Then on each insert select all with limit set to 50 sorted by date. Choose the last item and run a delete query to delete everything older than this last item.
is it must to use sqlite? can you use file handling? you can use simple Queue object and save it to file.
Here is what I did for a list of transactions, and it works okay. When inserting a new entry I check if the count is above 50, if so, I just delete the very last entry:
// Adding new transaction
public void addTransaction(Transaction transaction) {
SQLiteDatabase db = this.getWritableDatabase();
if(getTransactionsCount() > 50){
List<Transaction> allTransactions = getAllTransactions();
Transaction oldestTransaction = allTransactions.get(allTransactions.size()-1);
deleteTransaction(oldestTransaction);
}
ContentValues values = new ContentValues();
values.put(KEY_TRANSACTION_UID, transaction.getUID());
values.put(KEY_TRANSACTION_AMOUNT, transaction.getAmount());
values.put(KEY_TRANSACTION_IS_ADD, transaction.getIsAdd());
// Inserting Row
db.insert(TABLE_TRANSACTIONS, null, values);
db.close(); // Closing database connection
}
And getAllTransactions() returns the list in descending order (based on the id primary key):
// Getting All Transactions
public List<Transaction> getAllTransactions() {
List<Transaction> transactionList = new ArrayList<Transaction>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_TRANSACTIONS + " ORDER BY " + KEY_TRANSACTION_ID + " DESC";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Transaction transaction = new Transaction();
transaction.setID(Integer.parseInt(cursor.getString(0)));
transaction.setUID(cursor.getString(1));
transaction.setAmount(cursor.getString(2));
transaction.setIsAdd(cursor.getString(3));
// Adding contact to list
transactionList.add(transaction);
} while (cursor.moveToNext());
}
// return contact list
return transactionList;
}