I have a quiz app which populates a sqlite database with questions of around 20 different categories. I want to implement in app billing so that if someone purchases Category1 for example, then these questions are added to the database and no others. Some of my questions fall within two categories so let's say Category1 and Category2.
try {
for (int n = 1; n < sqlString.length; n++) {
db.execSQL("INSERT INTO " + DATABASE_TABLE + " VALUES ("
+ sqlString[n] + ");");
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
This is my current set up in the SQLite class onCreate method. sqlString is a string array containing all my 500 questions so far.
I'm going to store whether a category has been bought in another table (but I am open to other suggestions on how to do this). I plan on creating a class which reads this database setting up boolean values of true or false whether each category has been bought. So
boolean cat1 = CheckIfCategoryHasBeenBought(category1)
etc. Then if it has been bought I will implement a method such as
boolean[] catChecker = {cat1, cat2, cat3, etc....}
SQLite info = new SQLite(this);
info.open();
info.addQs(catChecker)
//this will pass the true and false boolean values for each method then
//based on that I choose to implement or not
info.close();
However I don't know if this is even a good way to do it. I'm not sure how to check if the value has already been added (as a result of it crossing over with another category that's been bought). I was thinking a cursor would be best to check if the value is already added however how do I get the cursor to search?
The ways I've thought this could be achieved is
1) I create a string array only with the strings associated with bought questions.
2) I create an if statement within the for loop above which checks whether the string is from a bought category
3) I give the value "null" to all strings that haven't been bought then add an if statement only executing the SQL if the sqlString[n] is not null.
Do you guys have any idea how it would be best to set this up?
Have you thought about starting with a full database - i.e. containing all questions that could be purchased by anyone - and then delete those that are no longer applicable?
There are lots of ways to do this, and I think there will be more than 1 good answer. If you have a server, you can do things like return a list of authorized databases/strings/etc. You can use that to reference different tables. You also can create a table or use sharedpreferences of which tables are downloaded. The list goes on.
The server option would add a layer of security. The stored table index would be easier to pirate, but also might be easier to implement and gives you the ability to use the categories offline.
Related
I have in my app a database with two tables : country and rights. Long story short, the db tells me whether a right (there is 10 rights in total) is legal or not in a specific country.
Now, I want the user to be able to search in my db by criterias. I have a layout with checkbox. If the user check a box, it mean he want to see every country in where the right is legal. For exemple, if he check the box "criteria1" and "criteria6", the user want the list of every country where criteria1 and criteria6 are legal, but we don't care wether the other rights are legal or not.
I asigned values to the checkboxs (1 if legal, 0 if illegal, just like in my db) and passes all of them to the activity who display the result of the search.
My problem is, I can't figure out how to search in my database. I need to only get the country where where the selected criters are equal to 1, but I don't know how to formulate my sql request (since I never know which criterias are going to be checked or not). My request need to only be about the criterias who has the value 1.
I had the idea of sending all my values to a function (witch returns a cursor) where I excecute a select statement if the value is equal to one, but I don't know how I could join all the result of my selects in a cursor. I also thought about using "CASE WHEN..." but it doesn't seem to work.
Does anyone have a clue on how I could deal with my search ?
If you need precisions on my problem, please ask.
This guy here (https://www.youtube.com/watch?v=NGRV2qY9ZiU&list=PL200JxfhYIgCrrpH4rCz-uNfBTb5sng1e) has the right idea.
The clip may be a bit slow but it does exactly what you want.
He creates a custom string based on if checkbox is checked and removes it from the string if unchecked.
To get what you want, you need to do a couple of things.
First, create a table with countries as rows, and rights as columns. Add 1 for right is present in country and 0 if not. Get this into an sqlite database (eg import via csv in DB browser for SQLite, free software; don't forget to create the android_metadata table in the sqlite database - search online for this). Import the database in the app (there is plenty of documentation for this online).
Second, change the text inputed in the if/else checkbox part of the script (he writes fruit names, you write for ex. "right1 = 1", or the exact query the checkbox should do on the column right1).
You also need to pay attention to the selection.add and selection.remove (know that selection is an array list which will store all your criteria for search by column).
Third, you need to change the content of his finalSelection (View view).
Delete all he has written and just create two strings:
String final1 = android.text.TextUtils.join(" or ", selection);
String final2 = "select country from table where " + final1;
The string final2 is your key for a cursor with a rawQuery. Just create a cursor in the database and pass the key to it. This can be done easily.
PS the method android.text.TextUtils.join() is amazing :)
You can place the operator of choice there.
If you need more than one operator (and, or etc), you can create different ArrayLists which you fill in the if/else checkbox is filled and join later in the finalSelection.
Oh, btw, if you have too many checkboxes, you will get a warning in the XML file (layout has more than 80 views is bad for performance).
In order to get around that, you need to get to know grid views a bit better. After reading a few tutorials on the basic use of GridViews, a good start for checkboxes inside them is here.
It may seem like a lot, but you need to learn to use holders to get information out of the getView of the modified BaseAdapter.
If you want to understand it better, follow the arrPath.
It is a String[] filled with all the paths of images found inside the cursor (string values from the dataColumnIndex, which contains paths of images).
Within the onClick() listener of the Button, from the arrPath he extracts only the rows of the cursor that were selected by checkbox click (thumbnailsselection[i] is a boolean - with a value TRUE/FALSE for each row in the cursor).
The selected paths are placed in the selectImages String, separated by OR.
I have problems in updating rows in SQLite database in my Android application. It works successfully only, if I update it two times. But when I try to do it on the third time, it doesn't update the same row anymore.
LogCat doesn't show any exceptions. db.update() returns '1'.
I've searched similar issues on StackOverflow and the web. People advic]sed to remove db.close(); from database-helper, because I call it several times, or to use db.update method instead of db.rawQuery() or db.execSQL().
I also tested my query in SQLite client, and it works as it's supposed to.
Here is code of simple database-helper method:
public int updateEventDoneMark(Event event)
{
ContentValues args = new ContentValues();
args.put("completed", event.getCompleted());
return db.update("Event", args, "id" + "='" +event.getId() + "'", null);
}
Is there some SQLite-related issue I should know while I update one database entry several times in a row?
What does your content provider update and URI match look like?
Typical Content providers have a URI for each Table/View for a single row where _id is passed as a where_argument and a URI for multiple rows which uses where and where_arguments to select the rows to be updated.
Also it looks like you update by id. Android really want the id column named "_id", although I don't think is currently your issue, but it really depends on the URI it's using. Content Providers are usually coded with the _id and select by the column for a single row based on _id. That's why I want to see content provider. Your also selecting by the id yourself, this doesn't seem normal, although it could be accomplished, but not the norm. Typically the where part is something like 'colunm name = ?" and the next parameter where_arguments is a string array containing the value to replace the '?'.
Hope this helps.
I'm newbie in Android.
I want to display a new ID in the TextView.
So, I just think of getting latest ID that had been store in the database and declare as Integer add 1 to the value that I get then display to the TextView.
I have read many of the question regarding the getting the latest ID. How can I use select last_insert_rowid();?
Thanks!
last_insert_rowid() works only for records that have been inserted in the same session.
If your column is declared as INTEGER PRIMARY KEY, then SQLite will automatically generate a value for it if you don't specify one in a new record.
If you really need the ID before you have inserted the record, you can execute something like this:
SELECT max(_id) FROM MyTable
if you use autoincrement use
SELECT * from SQLITE_SEQUENCE;
to get the latest id.
Cursor c = database.rawQuery("SELECT last_insert_rowid()", null);
c.moveToFirst();
int id = c.getInt(0);
id += 1;
I'm a newbie too so can't explain very well. The above will get the last insert id from the same session. It won't work if a new session is started, ie you insert something and close the connection and reopen it, as it will then return 0 so you'll need to bear that in mind as your TextView would always show 1. As like you I read many questions about it without knowing how to implement it. The above code is how I managed to use it without getting outofbounds exceptions.
I just finished the NotepadV1-3 tutorial for Android apps, and I was thinking of creating my own inventory app for fun, which for now basically consists of a list of names (such as "DVD" or "Grocery"), each of which can be clicked, which will bring up another specific list associated with that name. However, with the SQLiteDatabase.insert(..) method, the ContentValue can only take (among many others) "String, String" as argument, and I can't figure out how to input into the database a list of Strings associated with a particular key. I'm having trouble researching on how to resolve this as I am not that familiar with SQL.
What would be the best way to store a key with its associated list of Strings?
Any pointers and suggestions are appreciated!
Android newb :[
The best thing you could is to make a database-design that doesn't need you to input the list as as "string of strings". You might (I have not thought this trough all the way) have a table with lists (id and listName) and another table with contents (id and contentName) and finally a table that connects the two (tableId and contentName).
If you REALLY want to store that string-of-strings, you could serialize it into one string, and then when you've read it from the db, you can rebuild the string. This is NOT recommended though.
Example for a (simpler) database
Table 1 "lists": listId, listName
Table 2 "items": itemId, itemName, listId
e.g.:
Lists:
listId listName
1 DVD's
2 Grocery
Items
itemId itemName listId
1 film1 1
2 film2 1
3 sugar 2
4 milk 2
You can find all items of the grocery list by:
SELECT i.itemName
FROM lists l
JOIN items i ON l.listId = i.listId
WHERE l.listName='Grocery'
i have database with only a counter....i wanted to know how to increment it....
i have seen this article
Increase the value of a record in android/sqlite database
but dont really understand it....
does someone have a code sample which might be useful?
i basically want to make a quotes application...
in that say the user has seen 50 out of 100 quotes and exits the application...
i want to restart from 50 next time the user starts up the application...
is there any other way apart from databases to accomplish this task?
Well I don't think you want a database. A database contains tables which in turn contain rows and columns. That's not what you want. You just want to store one single value; the "page" number.
For that you should use the SharedPreferences:
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(this);
p.edit().putInt(PAGE_PREFERENCE, pageNumber).commit();
Then when you start your activity, you can retrieve this value like this:
int page = p.getInt(PAGE_PREFERENCE, 0);
Now if you insist to use a database, you can increment a value like this:
db.execSQL("UPDATE tableX SET value = value + 1 WHERE key =" + key, null);
I hope this helps.
Check this out: http://developer.android.com/guide/topics/data/data-storage.html
You probably want SharedPreferences if you are only storing one key-value pair.
Not very efficient but if you know how to create a DB then just have your oncreate append a boolean to the DB each time its called. The _id will autoincrememnt and you can just query for _id.
You can also put the quotes in the DB and query for quotes that have not been read by sorting by the boolean. When the quote is output it then puts a boolean in the DQ by the quote so it will be skipped the next time. Once the end of the list is reached you can (in theory) clear the booleans and start over.