12

Just trying to determine if there is an easy way to determine what contact changes when using registerContentObserver, or some other method? I can tell when the database changes, but not sure I want to check all the records each time an update/change happens.

Basically if I have a list of contacts, and one gets updated via manual method (i.e. I change phone number for a contact or add a new contact), or automatic (say ActiveSync photo gets added, changed). I want to be able to A) Know that something changed, and B) Know what contact had some data changed.

I am trying to look for certain users where I may be able to match their photos from a remote service. If more information gets added to a user account, I want to be able to examine it to see if it provides for a match. I don't want to schedule it though, I would like to do it after an update happens.

Chris.

Chrispix
  • 16,821
  • 19
  • 60
  • 68
  • Right now as a temporary work around, I am parsing all the emails that don't contain photos grabbing the uid, and then downloading the photos. Hoping there is a better solution though. – Chrispix Feb 17 '11 at 19:33
  • Let me change the question a bit... Can you do this w/out content observer, where I can get the uid for the contact that was added (only that contact)? – Chrispix Feb 19 '11 at 04:36

2 Answers2

9

I'm not sure which Uri you are currently registering for updates, but when you register your ContentObserver, can't you just register an individual Uri that points directly to the contact you are interested in? Then your observer will only get notified when your interesting contact is modified. The section in the SDK Documentation title "Lookup URI" talks more about this:

http://developer.android.com/resources/articles/contacts.html

The lookup key is unique to each record (row), so I would imagine doing something like this is what you are after?

Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
getContentResolver().registerContentObserver(lookupUri, false, myObserver);

And do that for each individual contact in your list.

For Added Contacts

The best way that I can see to do this is to re-query a cursor to the Contacts table each time the ContentObserver changes (re-query is fast, even if you're doing it often with lots of data), and maintain the highest known CONTACT_ID value. Whenever the cursor contains an ID beyond what you have stored, it was just added.

Also, if you haven't seen this conversation yet, it might be a good read. Dianne seems pretty adament that they keep specifics of content changes out of ContentObserver

Cheers.

devunwired
  • 60,762
  • 12
  • 121
  • 136
  • 2
    So that is not too bad of an idea, but it only works if I know what contacts have been added, also not sure of the overhead of say 3000 content observers. In my case, I am looking to update new contacts added via exchange active sync, and update w/ a photo (look up & download) if they are not added w/ one. – Chrispix Feb 19 '11 at 04:34
  • Well, you only need to create one `ContentObserver` to pass in each registration call; it would just get registered with each unique `Uri` for the "list of contacts" you mentioned (assumed to be a subset of ALL contacts). This method doesn't really work for add, though. – devunwired Feb 20 '11 at 14:02
  • I am going to accept your answer, as it certainly handles the highest known item. I think I will have to save the value as a parameter that way I can monitor changes while the application is closed. I certainly appreciate the feedback, and the link to the conversation w/ Dianne. I still need think how to handle changed records... i.e. what happens if a contact adds an email account later, and that allows me to pull up their photo @ that time... – Chrispix Feb 21 '11 at 15:17
1

Since this question was answered, there is a new callback method available in the ContentObserver class that has the uri of the changed content: http://developer.android.com/reference/android/database/ContentObserver.html#onChange(boolean, android.net.Uri)

This is available starting with the Android API Level 16

Adrian Aslau
  • 170
  • 6