EDIT: Assume a rooted phone for this post.
I deleted a previous question I posted on this topic because none of the answers even came close to answering the question. Long story short, I need to open a database and modify an existing record. I do not want to use a "helper class" because I actually want to see and understand what is going on in a few lines of code rather than an unnecessary (for my purposes) class that contains 100 lines of code. So please don't tell me to "use the notepad tutorial." I have, and it doesn't explain what I need.
To simplify, here is what I am doing:
SQLiteDatabase myDB = this.openOrCreateDatabase("/data/data/MY_APP/databases/settings.db", MODE_PRIVATE, null);
myDB.execSQL("INSERT INTO my_table (SOME_FIELD) VALUES ('SOME_VALUE');");
This works very nicely. However it fails if I try to open/edit a database in a different path. For example I might want to edit a database that another app uses. How can I do this? Is it a simple matter of permissions? Should it work if my app requests and gets root access?
EDIT: There are tons of apps I can install on my phone that are capable of editing every single database on the system so obviously this CAN be done.
Regarding Android security, you cannot access others' app DB directly. If other applications create ContentProvider then you can access theirs DBs (if exist) through its Providers. Otherwise, there's no way out AFAIK.
I don't know if you are still looking for this answer. I was looking to do the same but couldn't really find anything. I knew I needed to use root for the process, but again, couldn't find anything. I started messing around and just trying a lot of random things, and finally found a way to do it.
The short version that worked for me is you need to, as root, change the permissions of the database, access it directly (not through an sqlite helper), do whatever you wish, and then put the permissions back. I detail all of this on my blog:
http://rratmansky.wordpress.com/?p=259&preview=true
Related
Background: I'm taking an Android class right now and part of our final project requires retrieving data through an SQLite query. We're using the Chrome browser history to populate a RecyclerView. We're working off of an AVD and changed permissions on the history file (since, obviously, this isn't something that would normally be done) to make it readable. We have to use a SQLite query to get the data, though, and then do other stuff with it inside the app.
I've been digging around for the past couple of days and have found quite a few different examples for database connections in Android but they all seem to have a lot of unnecessary bloat that I don't need. I don't need to create or delete tables, I'm not adding or changing entries at all, I just need to query and get information back to play around with. I looked through the SQLiteDatabase documentation and the only thing that kind of looked like what I wanted would involve the beginTransaction() and endTransaction() methods. But I wasn't entirely sure.
I'm definitely not trying to like, covertly get others to do the work for me, but I wonder: is there a way I can query the database directly with a few lines in my code or from a relatively simple method? Or do I need to go through and implement something resembling the various database helper classes I've seen with all the extra functionality I don't need right now? Feel free to ask any follow up questions that may arise, if any. Thanks for any help you all can give!
You probably want to use one of the SQLiteDatabase.openDatabase() methods, with the OPEN_READONLY flag. Then, you can use methods like query() or compileStatement() on the returned SQLiteDatabase object.
The problem
I need to do a T9 contact search for an Android project I'm working on. Now, it would be simple if I just had to pull contacts from the native contacts storage and then do T9 on that, but the problem I have is that I have an additional local database where we store extra content for some contacts in the form of additional numbers that our application displays and handles. I need to do a search based on the contact’s name, number, and the extra numbers (if any) contained in the local database. The local database has IDs that match those of the contacts in the native Android database.
I have been looking for a solution to this problem, and I have gone through these ideas, but none of them seem to be the right solution.
Try #1
Write a ContentProvider for our local database, in order to be able to perform a simple join operation between the native Android contacts table and our table, however, it seems that joining tables via ContentProviders is only possible when you write your own ContentProvider, thus making this solution not viable for me, not to mention that Android documentation states that you should not write a ContentProvider if you don’t want to share your data with other applications, which we currently don’t.
Try #2
Copy all the needed data from Android’s contacts database into our database, and use ContentObservers to update it constantly. This solution had two major problems: 1) It seemed to have a big overhead, not just on the processor of the device, but also on the development, as we would have to introduce some really delicate update/read/write mechanisms and ensure that our data always stays relatively fresh, while also being performant; 2) A colleague has stated that during contact sync, the ContentObserver fires off events very often, thus making a need for special code to delay the updating, which he says has never really worked out great.
Try #3
Use a CursorJoiner to join the two cursors that I have received and then use a MatrixCursor to display all the data, but that solution is not viable since all the data would be kept in memory, and we are working with datasets that have more than 10k rows of data. Even if the memory could handle it, it would be slow to load, which for T9, isn’t really an option. This also pretty much excludes any solution that doesn't use a Cursor to look over data, which is why I am going in that direction.
Question
Am I missing something obvious? If I am, please point me in the right way. All of the things that I have tried don’t seem feasible to me, but I’m open to someone modifying them in order to make them worthwhile.
I want to copy a premaded database in user's device. then use it in the android App.
but I don't know where is the best place for that. (a place that I can copy file to it)
for example:
I have a database named "FoodsDB.db" in assets folder
When application starts for first time, it copies the DB from assets to user's Device
Then in DatabaseHelper address it and use it
Right off the bat without knowing exactly your code I'd try and guess that when you say "I don't want to submit changes" means you shouldn't invoke SaveChanges(). Shouldn't you try to completely discard the entities, then? I doubt it's that simple, but I post this nonetheless.
After you've added the example code I can see it's different then I thought. You won't be able to use a rollback (see unit of work pattern). What you need here is a PARTIAL undo, which is different then the full-scale undo I initially proposed by throwing away the entire context.
Look here for an excellent solution to your problem:
Entity Framework .Remove() vs. .DeleteObject()
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 seen this question here, and was wondering if the same method of "pre-loading" a database for an android application still works. I will be developing my application on the 2.2 platform, but I want to make sure that going forward I will not have to completely redesign if I use this method.
Secondly, is this the best method if I have unchanging data that needs to be looked up? Or is XML a better choice?
Example: I have a Car, a car has attributes like weight, color, make, model, engine, etc. these all need to be accessed in a lookup but the attributes and entries will never change (and if they do, they change as such a slow rate that I would release an update to add the few things that changed).
Thanks for any help.
Yes, the pre-loading method mentioned in the blogpost that article links to (http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/) still works for me after some tweaks prompted by a number of force closes from users. There were some issues with the database not being found on the Desire HD, which caused problems. It was difficult to isolate what exactly the problem was, but I think it was the file locations that was the problem. You should define
private static String DB_PATH = Environment.getDataDirectory() + "/data/your/app/package/databases/"
instead of
private static String DB_PATH = "/data/data/your/app/domain/databases/"
I also changed all database access to writeable as I had read that caused problems, but not sure if that was really the issue.
In terms of your second question, I would say it depends on exactly how much data you have. If it's a lot of data, you're probably better off using a database anyway for performance reasons. There are pitfalls to using the SQLite APIs, such as apostrophes in the fields (make sure you use the convenience methods query, update and insert rather than rawQuery). But I'm sure there are with XML too - I don't think there's any "correct" method more what you are most comfortable with - i.e. do you prefer working with databases or raw XML? If neither, and you're not planning to do major updating or querying, I would use XML, or even JSON, because of the reasons above and what Jodes alludes to.
The answer is not simple, you need to cross reference the version of SQLite used in different phones with the file format used for those versions.
A previous SO question showing difficulties in determining SQLite versions are here:
Version of SQLite used in Android?
And a page listing differences in file formats for different SQLite versions is here:
http://www.sqlite.org/formatchng.html