3

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 ?
Naroju
  • 2,637
  • 4
  • 25
  • 44

1 Answers1

1

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.

Marten
  • 3,802
  • 1
  • 17
  • 26
  • If I manually try to edit/update a contact from the contact app, I noticed that I can only edit the raw contact in the default a/c and the other linked rawcontacts (pointing to the same Contacts._ID) are not editable. So my question is when the user updates any rawcontact manually (default account), it's DIRTY flag will be set to '1'. Would it also set the DIRTY flag of the other linked rawcontacts, so that I can update and sync them with the server? – epiphany27 Aug 18 '17 at 01:53
  • The dirty flag is handled per rawcontact. Only the rawcontact which is actually modified will be dirty. Your sync app should not look into rawcontacts of other accounts.If a raw contact can not be edited there might be something wrong. Either the account is considered read-only or the contacts app is broken. – Marten Aug 18 '17 at 07:45
  • ^Sorry, I think I wasn't clear enough in my previous comment. What I meant was, I want to detect when the user manually edits the rawcontacts associated to my app's ACCOUNT_TYPE from device's native contact edit screen. From what I noticed, only the default rawcontacts (google or device-local) are editable from native contact screen, while rawcontacts like whatsapp, skype are non-editable. They are shown only in read-mode.(Let me know if you think linked contacts are editable from the native contact app too). Hence, in this case, DIRTY flag for linked rawcontacts will never be set. – epiphany27 Aug 18 '17 at 20:18
  • While going through Android sample code - (SampleSyncAdapter) I found out the following code which further confuses me. How did the following rawcontacts became dirty locally? // Find the local 'dirty' contacts that we need to tell the server about. // Find the local users that need to be sync'd to the server. 
dirtyContacts = ContactManager.getDirtyContacts(mContext, account); Am I missing something here? – epiphany27 Aug 18 '17 at 20:25
  • whatsapp and skype rawcontacts can not be edited because these apps have set their account types to *read only*. This really just depends on the sync app. It's perfectly possible to create a sync app which creates editable rawcontacts. whatsapp and skype just don't need that because you can not modify the phone number of your friends. – Marten Aug 18 '17 at 23:14
  • ^Could you tell me or point me to a proper resource, on how to make the ACCOUNT_TYPE or the sync-app's rawcontacts editable(i.e, configuring it to write-mode)? I searched the android documentation and web. I couldn't find anything. Also, do you know how Whatsapp might be updating its rawcontact's display name instantly when one edits the linked phone-contact/google-account's rawcontact's display name? I also noticed that as soon as the phone-number in device-contact/google-account is changed to some random invalid number, whatsapp account disappears instantly for that particular rawcontact. – epiphany27 Aug 28 '17 at 09:04
  • You probably don't specify an [`EditSchema`](https://stackoverflow.com/questions/21878237/use-android-contacts-app-to-edit-a-raw-contact-which-was-added-by-a-custom-conte). Unfortunately there doesn't seem to be any public documentation. I don't use Whatsapp, but I hardly believe they change the display name of their rawcontacts based on linked accounts. Regarding the phone number, in that case Android apparently unlinks both rawcontacts because it no longer considers them to be the same person. Note that none of this is about my original response, so please start a new question. – Marten Aug 28 '17 at 13:26