Contacts backup and sync application - android

I am working on a contacts backup and sync.
The target is to send all details of all contacts to a server (custom protocol defined) as a backup.
During initial launch of application, all the contacts will be queued and sent to the server.
And after that, a background service will be running all time which will listen to new contact addition/ contact update, and this new/updated contact will be sent to server by the background service.
I am using RawContactsEntity for fetching the records.
I tried using ContentObserver on RawContacts/Data tables to get notification of contact addition or contact-change. But, AFAIK, the ContentObserver gives notification (onChange()) of changed data in table as a whole and not ID of individual record.
Now my problem is, how to get the exact id's of changed/new records?
I thought of creating a backup-table to compare with native contacts table and get the changed records. But as the number of contacts increase, the performance will decease drastically and this will hamper the battery life too.
Can you suggest me, The best way for achieving this contacts backup operation from performance and memory usage point of view?
Is there any other way for contacts sync operation?
It would be very helpful if anyone can share examples which can help me in this.

If the contacts are stored within your account(AccountManger), Android will mark the dirty flag in raw contacts. If it is not your account then you can not trust the dirty flag as the accounts sync adapter might have updated the contact to the server and reset the dirty flag. Your only option is to either re-upload the full contacts(simple and easy to code) or keep track of the version column in RawContacts and check which one has changed. It is actually not recommended to copy and upload contacts from other accounts as the corresponding sync adapter will anyways maintain a backup of those. Like Google will have a copy of Google contacts on their server.

Related

How apps like Truecaller, messenger maintains sync with native contacts application if any contact changes in the native contact app

I have observed if we update/delete a the contact in native contacts application same changes is reflected into the TrueCaller instantly.
I can think of two ways it get the changes:
It refresh the whole contact list by deleting all the existing entries in app and query all the entries from native contact using contact provider every time app comes to foreground.But this approach might involve querying the RawContact table and Data table on every launch. (This might be a costly in terms of computation)
Each raw contact maintains VERSION which increments if any change is made to the raw contact via native app. This can be leveraged for modifications but will require to maintain the old values in the truecaller(or similar app) so that we can compare.This approach will still require you query the RawContacts table.
The later approach requires to maintain the Version on the TrueCaller app database as well.
Following operations will be required to detect any changes :
Check the version of the raw contact in the TrueCaller if the version is less than that of raw contact in native contacts db, then, query the corresponding Data table for all the changes.
If any raw contact is deleted from native then it's either removed from the RawContact table or marked Deleted. Thus we need to check for Deleted flag or if any pervious RawContact entry is missing in the RawContact table.
Other cases like a new contact is added hence a new raw contact entry in the RawContact table will be found etc.
Is there any better way to import the contact in your app and maintain proper synchronization if any operation like addition, deletion or modification is performed in the native app?
Certainly, app like TrueCaller does a great job with this. Any article on import contacts etc any relevant source will be appreciated.
As apps such as TrueCaller are closed source, there's no way to give you a definite answer, however option 2 would be my course of action to manage the sync with the device contacts.
You can add to that ContentObserver on the ContactsContract ContentProvider which will call your code whenever something changes so you can run the suggested code at option 2, however note that contacts tend to change very very very frequently, so I would limit such background syncs if they are needed to once a day to prevent hogging the battery/CPU.

how to display device address book ordered by custom external data

In my android application I would like to display the mobile user's contacts (names, profile picture ) displaying first the contacts that have already installed and registrered that application (the matching is made by contact's email).
Trying to loop over each contact and match if their email is already registered (in an external SQLITE table) don't seems to be an efficient way.
I would like to directly add (somewhere in the address book ?) the extra data "isRegistered = true/false) and order my addreess book query by this value to scroll the address book.
Is it possible? How to implement this in detail ?
OPTION 1
I think the most efficient way would be what you thought about initially, with a slight improvement:
store the list of registered emails (for the user's contacts) in a local SQLite DB.
read the entire list of emails on application launch, and store them in a HashSet
When sorting the contacts, create a custom Comparator to first check if the contact is an app user or not, and only then fallback to name compare.
OPTION 2
If you still want to check the option of storing the custom value in the Contacts DB, and integrate it into your query, you need to create a SyncAdapter.
This is basically a service that is able to sync contacts to/from a server into your own RawContact, which is then aggregated into one-or-more existing RawContacts, like Google does for Google Contacts.
You can set it to be notified when a new contact is added, and have your SyncAdapter add the needed info to the contact so it'll show links to your app.
If you go to your phone settings > accounts, you can see Whatsapp and Google's SyncAdapters there, where you can turn them off/on.
To create a sync adapter, you can follow the official docs, or this great tutorial.

Which contacts have my application installed?

I'm building a small app for messaging (in some way a bit similar to 'WhatsApp' or 'Viber'). WhatsApp and Viber show you contacts that are from your contact list and have an account with them. so my question is how to sync?
For now, I have database which stores all users using the application and their phone number.
Do I need to run a query for each contact in my phone in order to find it in the database?
It looks a lot of queries for every sync request.
What is the efficient way in order to do this?
If you have both sets of data as database tables, then can't you just join on some attribute like 'Full Name' and the resulting table will be all people in your contacts list with the app installed?
You can display contacts in your app that are just pulled from the contact list on the phone. Using LoadManager you can get a contact list that is synced with the phone list.
Check out these links for more info
http://developer.android.com/training/contacts-provider/retrieve-names.html
https://developer.android.com/training/load-data-background/setup-loader.html

Contact sync adapter in android

I want to use sync adapter in my application to sync the native and third party contacts (except FB) with server. ( Only client to server one way sync)
I have two doubts here -
1) If there are multiple sync adapters in the device and If dirty bit is already cleared by another sync adapter , would my sync adapter be able to detect the contacts change/update immediately.
2) I have used
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 1);
ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true);
to sync the contacts with server .
It does start the sync in every 30 seconds .
But I want it to get notified immediately when ever contacts are added Or Deleted or Updated to start perfromSync operation.
Do I need to use observer too ?
In order to see changes to the contacts you will have to register an observer with the ContentResolver. The sync API is not intended to watch for every change, it is intended to be a background API that Android runs periodically automatically for you, so that it can batch operations and use the network more efficiently, not run when network is disabled, etc...
The dirty bit is used on a per account basis. In general the sync is designed to have an "owning" account per contact, and is not designed for exporting all the contacts from the device to a particular service. There is an aggregation process that handles joining contacts from multiple accounts into one "Contact" as seen by the user. See:
http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html
For more information on how this works.
If you intend to export all contacts on the device to your service you will need to walk the contacts and insert a raw contact for your service. You will then also want to watch the ContentResolver with an observer to see when the user adds a new contact on some service or periodically walk the table looking for contacts you have not yet exported.
use the version bit. If any contact edited
It automatically increased by 1.
so you create local database for compare previous version to current version. If any changes happen you trigger the update query.
for more information visit here.
This version helps for my sync updates. So I share this answer for all.

CONTACT_ID - Keeping it in sync

I am interested in your opinions on the best way to keep a robust reference to a contact starting android 2.0. I have read a lot regarding this issue but i don't know which technique is advisable and if there's any new ones. Below are the 3 options i found so far:
1- Don't use your own db. Extend the contacts.contract to write your data
2 - Use ContentObserver to keep track of any changes made to the contacts. This technique would however require your application to be running
3- Store all RAW contact IDs related to a CONTACT_ID in your db and infer the content of the aggregate contact from all its constituent RAW contacts
In my case i need to keep a separate db and i was wondering if there's any other new technique of keeping the CONTACT_ID current after aggregations and dis-aggregations...
Please advise
I am playing with the new Contacts API at the moment, writing an app which is also a source of contact data. I can't recommend #3 at all. To get all of "my" contact data I simply store them with a magic value in the RawContacts.SYNC1 field and query the contacts content provider for that when my app starts up.
Re. your question, don't use CONTACT_IDs, as they are volatile. Use the lookup API, i.e. if you have a raw contact ID, use RawContacts.getContactLookupUri() to get to the Contact. Likewise if some API gives you a contact ID, use Contacts.getLookupUri() to get a persistent identifier you can use later on.

Categories

Resources