I am writing a backup application and need to know which records in the contacts database have been updated, so that I can backup only those records. I have looked at the documentation and it seems that there is a "DIRTY" constant field in ContactsContract.RawContacts class, which is supposed to be set to "1", for the rows that are updated. But it is not clear to me as to when will this field get cleared to "0". Can someone provide me example code on how to use this? Can this field be used to determine if a contact has been added or updated?
If this is not the correct way to achieve what I am trying to do can anyone suggest me another way. I am also aware that I can use the RegisterContentObserver() call to identify whenever there is a change in the Contacts database but this will require my application to be running always in the background, which is way too expensive and I do not want to do that.
If there is anyway to extract the timestamp when the various contacts have been added or updated that would be perfect too, but I cannot find how to do that.
Any help is very much appreciated.
I have looked at the documentation and it seems that there is a "DIRTY" constant field in ContactsContract.RawContacts class, which is supposed to be set to "1", for the rows that are updated. But it is not clear to me as to when will this field get cleared to "0".
In my experience, whenever there is a 'dirty' indicator of some sort, it is the responsibility of the backup/sync app to reset it once the data has been successfully committed during a backup/sync operation.
This can cause problems, however, when more than one application is used - the first one run at any time after data has been updated will reset the flag and the next one run wont find anything to backup/sync.
In this case if you require that a user is able to use a 'sync' app (for example) but you also want to have a 'backup' operation then registering a ContentObserver would serve a better purpose and there's no reason why this should be 'expensive' on resources if implemented correctly.
EDIT: Although there is no 'timestamp' there is a 'VERSION' field which is updated (which is when 'DIRTY' is set). If you backup this field, you could simply leave the 'DIRTY' flag set and compare current VERSION in the contacts DB with your most recent backup.
Related
I have a pretty broad question and mainly want some advice and best practices for this Sqlite Exception and how to handle it. I am catching it no problem, just needing help with handling it. In my app, I have only one field for my database that is labeled unique for this reason, as I do not want this one particular value to be duplicated in the database. I am using the method insertWithOnConflict() but am wondering what is the best constant to set for the conflictAlgorithm parameter. I have read up on all of them that are available from the SQLiteDatabase|Android reference page and am still not sure which would be my best bet. I would ideally prefer to accomplish this:
Prompt the user immediately with either an AlertDialogueBuilder or Toast message that the value they have entered, is already contained in the database and they need to alter this current value before continuing. Since this unique field is one of the first one's out of all 15 of them, I would even be fine with writing and committing the current transaction with all the other data collected for the other remaining fields and just labeling that unique field with a message indicating a default "Needs Unique" value or something but this would be last resort. At this point, when the exception is caught, my app does not crash, it just does not commit the write, and returns to the previous calling Activity, which is a listView of all previously collected assets in the database. Would it be wise to just go ahead and relaunch the Activity where the data collection takes place, prompting them about the duplicate key at that time? Or stop the transaction from attempting to be committed and not written before the app is sent back to the calling Activity? I just can't seem to do anything with the exception once it happens. Any advice or tips would be greatly appreciated. Whatever are the best practices for working with data and databases I would like to know and learn for the future. Thank you all.
Im am developing a webservice for an App that I am writing. I want to make the App offline accessible.
I made that webservice so that if you request JSON from the webservice you can give a date:
/color/colors/date/2014-03-01T12:00/
If you don't give the date you will get everything that is inside the database and that is active. If you give the date you will only get everything that is updated after that date.
Now my problem is that if I remove something from the webservice of from the App then it will not be synced and the other devices will never know that it is removed.
I could work with a field where I say that a record is removed but then I need to keep every record and I can't delete any record.
Is there a better way to do the syncing? Or what is the best way?
I think there is no possible way to detect the deleted entry's change, unless you send the information that the entry is deleted. The best practise you set a field in the table with integer type, then you can set this value on updates. You don't have to set it only 1 or 0, you can use bigger numbers (for example I used 30 on that entries, that I deleted on 20th march , on this day was a big code logic change. after that i knew when the status integer is 30, then i deleted this row after that date.) It may be a silly example, but you can implement your own logic.
It depends on how important it is to update the rest of the devices when a change is made.
If it is critical, then it would be worth implementing push notifications or something similar to each device to let them know about the updated situation. Otherwise, you would simply have the other devices poll the server to check for changes on their own accord, and the frequency or the trigger of this poll would depend again on how critical it was that they get an update. Maybes they only need updating when they visit a certain activity, so in that case you would only poll when you reach the onResume() event of that activity
Update
If you don't need to keep a history of the deleted record, then why can't you just delete it, and then when the rest of the devices update, you clear all and download a fresh set? If that is too intensive, you would NEED to have a reference to the id, which you could do in a table or use a special value in the field (like null, 0 or -1) to mark it. Otherwise there would be no way to reference it
I am writing an Android app that needs to be notified whenever a given SQLite database changes (any new row added, deleted or updated).
Is there any programmatic way to listen to these notifications ?
Is writing DB triggers for each table the only way ?
SQLite provides Data Change Notification Callbacks. I don't think that Android exposes them directly but it does have for example CursorAdapter which provides some change notifications.
As thinksteep asked however, do you expect your DB to be changed outside the scope of your own application?
You can register an observer class such as DataSetObserver
Then whenever you change something you can call cursor.registerDataSetObserver(..) to register observe changes.
It's not well documented but I'm sure that there are some examples out there
You can use also use the getContentResolver().registerContentObserver but unfortunately it doesn't tell you what kind of change was made, it could be a delete, insert or update.
If you control the ContentProvider that interfaces with the DB then you could fire an Intent or use getContentResolver().notifyChange to send a special Uri notification that identifies both the table and action. An example Uri you could notify with might be: content://my-authority/change/table-name/insert
But even then you don't know exactly which rows were effected by the change.
Seems like triggers that write to a change log table will guarantee you hear about all changes regardless of where they came from, and you can know the exact id and action that occurred. Unfortunately it means slower inserts/updates/deletes and it means you probably need a Service of some kind to process and delete changes.
I'd love to hear if these is some better solution out there!
I want to insert required data for my application at the beginning and I will use these data. And I want to insert once, and there must be no duplicate. Therefore, in "onCreate", I'm doing like that : if the row count of table(such as student etc) is 0, I'm inserting students. I don't think it's the best way to do this. Therefore I want to learn if there is a better way.
If you want your database populated at install time and never any other time, your only reasonable option is to package your pre-populated database with your APK as a built-in resource. This has the advantage of simplifying your app.
Alternately, if you implement the SQLiteOpenHelper for your database, anything you insert during SQLiteOpenHelper.onCreate(SQLiteDatabase) will only ever be inserted either on the first run of you app or when someone clears all your app's data (which is more or less putting you back to a fresh install anyway). The SQLiteOpenHelper superclass knows whether or not to run the creation code when you call one of the getWritableDatabase() or getReadOnlyDatabase() methods to get your database reference.
It is worth noting that Android doesn't really let you run an installer the way desktop software does. If you need to do any setup work, you need to be able to detect and remember when your app has been run before.
I am trying to adapt my application from a confirmation model to an undo model. For those of you who don't know, this is where you can delete something with one click but if it was a mistake you can undo it just as easily, as opposed to interrupting the user every time he/she wants to do something to ask the annoying "Are you sure you want to...?" question via dialog.
My app is backed by the Android SQLite DB and I want to be able to undo a limited set of delete and update operations. Also, I only need to be able to undo one sequential change and the information does not have to stick arround for very long.
Everything I read on undo/redo says to use a command model to store the data. My question is how can I store the database changes in a lightweight restorable way?
The idea of the command pattern is, that every command knows how it can be undone. For instance, an AddPersonCommand would add a new record to the Persons-table in your database. To undo this command, you would have to delete that person again.
Depending on the type of application and the complexity of the database, you can just write the changes to the database like you normally would. You always keep the last X command objects (X being the number of actions that can be undone), and if necessary, invoke their undo-method.
You can also use RestorableSQLiteDatabase library which is a wrapper around android's SQLiteDatabase and automatically generates restoring SQL queries to undo changes using a tag name.