Android SQLite adding contacts 'dynamically' - android

In my Android app, an Activity performs a query to get the contacts on the phone and stores them into a sqlite database. For now, this is performed only once during the first launch of the Activity because that operation takes about two seconds to execute (which is actually a lot of time)
However that workaround comes with an issue: if the phone user adds some contact my app will never be able to get them. Then, I was wondering if it was possible for my app to ´listen ´ for that event and add the contact in the database when it occurs.
Is such a thing possible?

You can do it by using ContentObserver.
You have to simply
Implement a subclass of ContentObserver
you have to register your ContentObserver to listen the change.
For more detail how to do it you can follow this article Use Android’s ContentObserver in Your Code to Listen to Data Changes

Related

Should I store my contacts list in DB or Sharedpreference to avoid running the same task

I have my app such that when entered in a certain activity, I show a list of contacts in my phone( similar to Chat app where you see a list of contacts when trying to start a new chat).
So I just wanted to know about the implementation details of these task for best/ efficient work.
Is the contact list is fetched everytime from my device whenever I enter the activity(which is actually redundant, because we maybe doing same work over and over again,
But again we cannot rely on saved data in DB/SharedPref as contacts data is dynamic and bound to change,
so need your expert suggestion how to actually make this work in best possible way(I have already written method to fetch contacts- so whould I fetch the contacts afresh everytime or any other way around is there, what the popular chat apps implemet to show the contacts everytime?
Personally, I would implement the fetching of the contacts on a background thread (using coroutines) that is called periodically (perhaps each time they the activity is created, as you suggested, or maybe once when they open the app).
Because it's on a background thread, it would prevent them using the app (or any dropped frames while the activity is created). They might have thousands of contacts or be using a really slow device.
Presumably, you would want to store some other data associated with each contact: for example, if you opened up a chat with the user, you would want to associate all the messages with the user, so I would use a database such a realm rather than shared preferences.
So the entire process would probably look something like this:
Opening the app triggers a service that fetches all of the user's contacts on a background thread.
Service updates the database, perhaps removing contacts which don't exist and adding the new ones.
If you were handling this in a view model, your fragment or activity could observe the list of contacts and update the UI once it had changed.

Android - Listen to changes in android contacts and get the deltas

I'm trying to understand the whole concept of sync adapters from last couple of weeks and have few questions regarding the functionality.
I want to listen to all the changes in android contacts
Approach 1:
I have created a custom account and also created a sync adapter.
Written a broadcast listener listening to ContactsContract.Contacts.CONTENT_URI and in
public void onChange(boolean selfChange) of ContentObserver class i'm calling ContentResolver.requestSync(account,ContactsContract.AUTHORITY,bundle) which is acting as a trigger point to start the sync adapter when ever there is a change to contacts data.
Everything looks fine till here but in the SyncAdapter class i'm not getting any data in SyncResult variable in onPerofmSync
So how Can I get the delta changes from contacts?
Correct me if this is not the way to trigger sync adapter.
Approach 2:
I have followed some example where they were talking about querying the contacts database where dirtyFlag is set to 1.
I was able to get the changes but my question is
who will set that dirtyFlag value back to '0' ?
If I have to do that then lets say there are multiple applications on the phone which does the same thing. If some application sets the flag to '0' before my application tries to access the information. I'll be missing out on all the changes.
Approach 3:
Query the database and keep track of version for each contact in my own database and if 'version' has changed consider that as a change in contact. This looks like a heavy process.
Finally my question is what is the best way to listen to changes in
contacts on user's device?
What you can do is persist (possibly using a local MySql database) a mapping between Contacts.LOOKUP_KEY and its RawContacts.VERSION values.
Once you get a broadcast that a change happened in the Contacts DB (via onChange) you query for all RawContacts.VERSIONs and their Contacts.LOOKUP_KEY and compare it to the state your have persisted before, if one of them changed, you'd know that contact changed.

How to determine where a contact was added?

I have been struggling with an approach to this problem for some time now. There is no Intent action fired off when a contact is added (as far as I know). What are my options to solve this issue?
Here are some ideas I have been playing with:
Firstly I kept a record of user locations with timestamps and periodically scan the Contacts DB and add new entries to my own DB with a timestamp. I could then compare these and try to find a decent match. I do not like this approach as it is very error prone.
Recently I've been looking at a ContentObserver for the Contacts DB, but I am not sure how to set this up so that it will constantly be observing, and not just when my app is in focus. Perhaps in a service? The documentation isn't clear to me about the life-cycle of a content observer, i.e does it die after the service/activity that registered it dies?
So really what I want is a seamless way to record where and when a user adds a contact when my app is installed on the device. It is not enough that the app should be in focus/running.
The second idea of yours is the correct one. The observer needs to be in a service as you had rightly guessed. Register the observer in the onCreate(). You will use contentProvider in the onChange of the contentObserver. You will need to maintain time when you last read the database using shared preferences. Note the changes of entries after the time stored in shared preferences. Now update the time of shared preferences to current time. Also unregister the content observer in onDestroy().

How to modify android's default (original) contact addition code

I am developing an app where I need to execute a piece of code whenever user adds a new contact. The solution for this is to use ContentObserver to get notified and then execute the code but for this I need to run the observer service in background which in turn will affect battery life of user's handset.
Instead can I extend the original contact addition code provided by android so that after storing contact in contact db it will execute my code. In this way task becomes efficient.
Is it possible?

Android SQLite DB notifications

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!

Categories

Resources