Im working on a self-test app.
And I wondering on how to store the data, I've got over 200 questions and more is on the way.
Was thinking of storing them as XML but didnt find a way to get a random question without reading the whole string-array to a variable, which is bad for the memory.
So the correct way to go is to use a SQL-database, right?
But how do I make such a database so that it exists at boot and dont need to be made during start up?
Can't seem to find any tutorial on this subject, on how to handle questionnaires.
Here's a good tutorial on SQLite and Content Provider. It'll introduce you to using SQL databases on Android, and wrapping them into a ContentProvider.
As for how to get the data to the device - you have two options:
You pack the SQLite .db file in the application assets folder. Pros: the database is ready for consumption on the first run of the app. Cons: your .apk is too big. Updating is hard.
You download the data on the first run. Pros: your .apk is slim. updating is easy Cons: there's a delay before the user can use the app.
You ship a small .db file with the first 10 questions. Pros: Your users can start using the app immediately, while you download the rest of the questions in the background. Cons: You have to pick 10 questions you're likely to never or rarely change, or you risk your app to start with outdated data.
Create the db offline and either put it in the apk or download it.
Related
I have started learning Android development and I have a very newbie question. I understand that Android can store data in SQLite for example, but what other approaches are there to the storage of data within your application?
Do Android apps ever have data 'embedded' within the application, in which case what sort of data structure or concept would this use?
I am thinking of a scenario where the data is static but is perhaps not a large enough dataset to warrant a database..e.g. an app with general knowledge questions and answers
Any guidance much appreciated
Rowan
Yes You are correct You can use SqLite Database for storage
other ways to store data is SharedPreferences
But in your case you wanrted to save questions and answers which is static one so you can create a text file and put that in your assets folder and you can read that file as any other text file in java
Refer this link how to read file from assets folder
1.Sqlite Database
2.Shared preferences
3.Internal memory
4.external memory i.e sd card
i would suggest you to go with Database. as it will let you store as much data as your app needed, There are some other option also present like
Sharedpreference i.e. cookies in general term. It let u store only few KB data and not good to store much data. When u retrieve data from cookies. All data will be store into ram and use app memory. that is use less when u do not need all data to retrieve and store into ram and then remove
Store into file and ship that file with your app. Yeah. this could be better idea again. you need to read it byte by byte. and hence reading to mid or last line will store all data into ram and hence will take memory.
Use Web Service to download data. It will let you store Large data and you have to download using Web APi. Hence it could be better idea. But this requires active Internet connection to play game to run app.
There must be some other option also present. You can search. surely you will find them :)
Overall Database it good solution for all app. As it will let you do search store delete and let you do other operation in less amount of memory. In Mobile Development Memory is very Important thing we have to take care of.
Let me know if you have other unclear thought.
item
You could also store info in a server.
Pros :
You can change the content without needing user-side update of the app.
Cons :
Your app (mostly the UI) would need to manage connection problems.
You may need to implement async tasks for querying data from server.
Let me explain how my application is supposed to work:
Application will ship with a sqlite database in its assets folder which will be copied into databases folder later and it has some content in it(categories, sub categories, products and news) which they all have image. Then after download user can update the content via internet and the application store the new content in database so the application can perform offline.
So my question is, after a while this content will increase in size, is it gonna cause my application to crash? Lets say I release the application with 1 MB database and after 2 years of work the database size goes up around 120 MB. Is it gonna make the application to crash?
Also the other concern is that currently I'm storing the images in database and I load'em from there. Is it a good approach? Because I don't want user to be able to clear the cache or delete the images because later on updating the content it has to download those deleted images again and it will consume traffic imo.
please remember that the Application should be able to load content offline
No, applications don't just crash because they have a large database.
Part of the point of a Cursor is that it gives you a view into a large set of data, without having to load it all into memory at the same time.
If you follow best practices I see no problem - you're using a database. Forget for a second that it's on Android - you should optimize your table structure, indexes, etc, as best you can.
Also, large database or not, don't make any queries to it on the main thread. Use the Loader API if you need to show the result of a query in your UI.
Last, potentially most importantly, rethink why you even need such a large database. Is it really that common that a user will need to access all data ever while offline? Or might it make more sense for you to only store data from the last week or month, etc, and tell them that they need to be online to access older data.
Regarding your 2nd question - please in the future separate that into a separate question. But, no, storing binary blobs (images in this case) in a sqlite database is not good approach. Also, if they clear data on the app, everything is gone, so there's no advantage to using a database to avoid that. I would suggest storing images in a folder named after your app in external storage of the device, potentially storing image URIs/names in the database.
Any problem with database will cause SQLiteException which you are able to handle in your app to prevent the abnormal termination.
Having said that, a database of 120 MB seems to be too much, are you sure your users will want all that?
I have been asked to create a tiny android app.
In everyday work i code for .NET and I have no experience connected with Android, but as it is a really small app I guess it's going to be a good experience rather than something hard.
The core of the app would be a small database (probably XML, unless somebody suggest better solution) that would contain categories, names of the institutions assigned with each category and logo (not very high resolution I guess a single file would be <100kB) of the institution.
The database also would not be very big - I expect not more than 1000 records in total. The DB has to be totally offline and local, it cannot require Internet access when operating.
The model I assume would be to ship new version of the application when the database changes (which is not going to be very frequent).
What is the best way to deal with these requirements?
My first idea was to create an XML file that would contain the records and link to the image. The XML and all the images linked to it would be stored in single file (preferably zip) that would be stored in app resources. This is very good as it is going to be very easy to update the database.
The second idea that somebody suggested me would be to use SQLite and store images in BLOB. In general I have read that it isn't a good idea to store images in database directly, and I am afraid if it's going to be possible to meet all requirements mentioned above.
Mostly I have no idea how to update the database easily and attach it to new version of application.
Any suggestions?
I would be grateful for any response.
I wouldn't go about using XML to save your data and by no means zip anything.
I think your way of thinking is ok, but you're making things really complicated for yourself.
Seeing as you're used to .NET I suppose you're also pretty confident with SQL, so I'd suggest you have a look at how to use the built-in SQLite database in Android.
If you would go the XML route you'd have to serialize and de-serialize the XML file over and over again and then parse the XML. Ok you don't have a lot of data, but searching inside an XML file with at least 1000 nodes would be slow in comparison to the performance of a database.
Also upgrading an existing SQLite database is not that hard - Android has methods for that (onUpgrade coming from the SQLiteOpenHelper).
As to saving images I'm assuming that you won't fetch new pictures from the Internet, so it would be best just to store them in the drawable folder of your app (be mindful of different screensizes) and then reading them into an ImageView when needed. To figure out what image should go for what institution I would store either the image name of each image in the SQLite database or store the resource id for each image in the database - for instance R.drawable.myawesomepictureformyinstitution.
I know my answer is somewhat "superficial", but your question is also somewhat "broad" and hard to answer without me actually writing most of the code, and that's not my intention ;-)
Hope this helps - let me know if anything is unclear.
I'm trying to create some sort of backup & restore function in my app. Before that, I've been reading for a while to understand if it's possible to achieve, but I found out this question:
Sqlite DB Android Backup/Restore
The only other way I could see to do it, would be to read the actual contents of the DB and generate a file containing the SQL which which it can be restored from, this is obviously a more complex and doesn't offer any advantages to justify this complexity.
This answer, I think, is the best way to accomplish that; not explorting the .db file, but exporting queries.
You know; when you export a SQL data from mysql, you get a file which contains all the queries that creates the structure and queries that fill the structure with data.
That's what I'm trying to mimic; generate a file which contains sql queries from a .db file.
Do you guys think it's possible, I mean, is there any builtin method to achieve that?
Otherwise, if its too hard to handle, how do you manage to avoid what this user (https://stackoverflow.com/a/10842043/1943607) is talking about?
So, I disabled WAL with "PRAGMA journal_mode = DELETE" and then I was able to view the database in the browser and able to restore it on my test device fine.
That previous part, I can't understand it. Is this a configuration you set to sqlite?
Thanks
I haven't actually tried this with sqlite, but with mysql you could do things like create "dumps" of your database. Those dumps contained exactly what you describe: a set of queries that, when executed together, recreate the database, including the contents.
Judging from the "sqlite3" documentation found at http://www.sqlite.org/sqlite.html (especially the "Converting An Entire Database To An ASCII Text File" section), you can do the same for sqlite. Since you can execute shell commands from a java application (using Runtime.getRuntime().exec() methods), and you are the "owner" (Linux user id) of the database, you should be able to run this "sqlite3 .dump" command even on a non-rooted device. I have never seen an Android device without the sqlite3 tool installed, so the command should always be available.
Moreover, since dump file is just a text file, you should be able to prepend any PRAGMA's to it that are required for compatibility (like the one you quoted).
I haven't tested any of this, but just wanted to think with you on this interesting topic.
An sqlite database is just a file so you could copy the file but I think you may have problems with permissions in android preventing you from accessing the database.
A better solution IMO would be to sync your data to an external website.
Using a combination of a custom sync adapter and the account manager with a website or web service that has a RESTfull api to receive and send the synced data would be the most reliable approach.
http://developer.android.com/training/id-auth/identify.html is a great introduction to setting up the account manager.
And for a custom sync adapter this is a great starting point.
http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/
and http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-2/
And finally an explanation of how it all fits together
https://sites.google.com/site/andsamples/concept-of-syncadapter-androidcontentabstractthreadedsyncadapter
The above approach would enable a user to switch phones and retain data at the same time and the data would always be up to date (providing you sync at the appropriate times.
It seems like a lot of work as you will need to set up a web service but it is the BEST way to make sure data is kept safe and secure and can be restored and backed up at any point.
For a web service there are lots of options available to you including cloud services such as Google docs or writing your own website. Ruby on Rails is a great solution for developing your own site as you get a full RESTfull api out of the box and it;'s dead easy to secure/lock down a rails site to authorised users only with a couple of lines of code and with Heroku you can get free hosting.
As usual with Android development the simplest of requirements actually ends up being the most difficult to implement but where data safety is paramount then it's worth the effort to do it properly.
The question is too open to answer simply because the changes that may apply to the db file content are open and one can't guarantee a specific behavior .
On the positive side sqlite project is an open source and the format of the DB file is specified Here
After taking a look there, it seems very possible/not too complicated to parse any DB file looking for Data Only and write it/dump it to another functional db file.
I believe this is the fastest and cleanest solution to the issue in hand.
so to wrap up:
Copy DB file everytime you want to back it up.
When you want to restore create a new DB using Android APIs.
Parse the data from the backed up file and write them to the newly created DB.
P.S:
regarding how to use
PRAGMA journal_mode = DELETE
Simply use db.exec("PRAGMA journal_mode = DELETE"); when creating the DB
I have an Android app that needs to work offline and requires a lot of static data.
Currently I'm using a JSON file in the /res/raw and loading it with the Jackson parser into my POJO scheme. It works really well since I have an external program that will be generating this data and once in a while when there is a change I'll just publish new version to the Market so I don't have to deal with running an update server and so on.
However, right now my JSON file is about 2.5MB with limited dataset for testing, in the end it'll be about 5-10MB.
The issue is that it already takes about 3-5 seconds to parse the file and this needs to be done every time the application is restarted.
So, what are my options here? I could put the data to a sqlite database, but that would require rewriting the external application and changing the data structure quite a bit. But then I could only query the things I need at the moment and not loading the entire thing at once.
Is there some easier/better way? Also, is there a good way to publish the app with the sqlite database? All the articles I've found talk about creating the database for user data at first startup, but this is not user data and I need it to be deployed from the Market.
JSON feels like the wrong approach for this - it's a good way to encode data to transfer, but that's pretty much it.
It'd be nice to have a bit more info on what exactly your app does, but I'm struggling to imagine a use-case where having several MB of POJOs in memory is an efficient solution. I think it'd be much better to use SQLite, and this is why:
I could put the data to a sqlite database, but that would require rewriting the external application and changing the data structure quite a bit.
You can still use your other program's JSON output, but instead of loading everything into POJOs with Jackson, you could populate the database on first app launch. This way, the app boot time is negligible if the dataset is unchanged.
If you still want to work with POJOs in the rest of your app, it'd be trivial to write a query that retrieved data from the database, and created objects in the same manner as Jackson.
But then I could only query the things I need at the moment and not loading the entire thing at once.
What're you doing that requires access to all the data at once? Searching or ordering a set of objects is always going to be slower than a SQL query to achieve the same thing.
Also, is there a good way to publish the app with the sqlite database?
You can definitely ship your app with a database, though I've not done so personally. This is a relevant question:
By Default load some data into our database sqlite
Hope that's of some help.
There's an excellent API called JExcel (just google it) that works with .xls spreadsheets. If you're not going to be doing any selecting and just loading data from a source, I like to use JExcel because it's more manageable from a desktop and produces easier-to-read code.
Not sure of any performance differences, however. Just throwing in my 2 cents :p