androidandroid-contentproviderandroid-syncadapteraccountmanagerandroid-authenticator

Syncing contacts using SyncAdapter ,Working


I am currently working on a android project in which I want to Sync mobile contacts to server, After researching a lot about SyncAdapter and Creating account in accountmanager, I have learned it myself. however there are two things I don't understand, I searched about these in google but could not get perfect answer. Please don't duplicate the question, I want to know more clearly how it works.

  1. As the Google documentation says whenever a sync is done, the dirty flag of the contact gets changed. My doubt is how will the android OS detect the status of the Sync of that particular contact as I am programatically specifying what contacts go to server?

Ex:- In below example, I want to send a bundle to server.

    Bundle extras = new Bundle();
      extras.putInt("contact name after filtering", "number after filtering");  
      ContentResolver.requestSync(account,ContactsContract.AUTHORITY, extras);

then the Bundle extras received on the onPerformSync Method and send to server.

    @Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {

    for (String key : extras.keySet())
    {
        Log.d("Bundle Debug", key + " = \"" + extras.get(key) + "\"");
    }

       //Code to send to server

}

Let's say in the above example, variable extras is a bundle which obtained after filtering changes in the contacts list,want to update them to server.Now how will the SyncAdapter framework or OS detect the changes and update dirty flag of that contact? Of course I have provided AUTHORITY, don't know how does that help in finding what changed. IS the above method is correct way to implement?

  1. How to find if the sync is failed? or Finished ?

Solution

  • Every modification of a contact that's done without the CALLER_IS_SYNC_ADAPTER on the Uri will make the ContentProvider set the DIRTY flag of the modified contact to 1. Similarly, every delete request without that parameter will just set the DELETED flag instead of deleting the contact.

    Your SyncAdapter has to query the contacts that are flagged dirty or DELETED, take the appropriate action (send the new contact data to the server or delete the contacts from the server) and clear the dirty flag (by overriding it with 0 having the CALLER_IS_SYNCADAPTER parameter in place) or finish the removal by deleting the contact again (again having the CALLER_IS_SYNCADAPTER parameter in place).

    I believe that you can not "undelete" a contact by setting DELETED to 0, since (to my experience) the contact data has already been removed at that point. Only the RawContact entry is left (though, maybe I had just a misbehaving device when I tried that the last time).

    It's important to specify the CALLER_IS_SYNCADAPTER, otherwise nothing will happen (and your SyncAdapter is doomed to try to sync these contacts again and again).

    Regarding question 2:

    That's completely up to your SyncAdapter. You write the code to sync the contacts and you're SyncAdapter is the only one to tell if it succeeded or not. In general you probably can assume it succeeded if no Exceptions were thrown during the sync.