[android-developers] Re: Stable contact identity CONTENT_LOOKUP_URI

2009-11-04 Thread jarkman
Dmitri - thanks - that's perfect.

So, we have two choices -

(1) For each incoming contact URI, loop over our table of stored
lookup keys, looking each one up with
ContactsContract.Contacts.lookupContact(resolver, lookupUri) and
comparing with the incoming contact.

I think that will be reliable, and makes the best use of your cunning
lookup mechanisms, but could be a performance problem.


(2) Move our custom data into the generic data store in the contacts
database ( as hinted at here:
http://groups.google.com/group/android-developers/browse_thread/thread/690cd4e531205b0c/364e21a52b00491c?lnk=gstq=contacts#364e21a52b00491c
)

That should be reliable, but I am not sure what will happen to the
generic data rows over contact aggregation and disaggregation.
Presumably we may find a contact who has two instances of our custom
data (after aggregation) or none (after disaggregation, if our custom
data stayed with the other half of the results).


(3) In our own table, keep all the raw contact IDs for each aggregated
contact we are interested in. That lets us deal with the aftermath of
aggregation and disaggregation explicitly, and it lets us search
quickly by comparing IDs, but it means we need to do something
complicated to clean up our data after a disaggregation has has
happened.

Do you think that covers it ?


Richard

On Nov 3, 7:17 pm, Dmitri Plotnikov dplotni...@google.com wrote:
 Hi Richard,

 Lookup key is unique at any point in time.  It's not unique over time.

 The anatomy of a lookup key is basically this.  If an aggregate contact has
 three raw contacts with server-side IDs A, B and C, the lookup key
 will effectively be  accountA/A.accountB/B.accountC/C

 We don't attempt to find a contact with that exact lookup key.  We actually
 parse it, find all those three raw contacts and infer the id of the new
 contact ID, which will be the one containing the most of the original raw
 contacts. In other words, even though the result is a bit unpredictable, the
 user shouldn't be surprised by what they see.  The original contact had A, B
 and C - now I am looking at something that has either A or B or C or a
 couple of those or maybe A,B,C and D.

 You are right that you should not use lookup keys to compare contact
 identities to each other.  You can use the
 ContactsContract.Contacts.lookupContact(resolver, lookupUri) method, which
 will give you the current contact ID for your contact.  Be careful though -
 between the moment you get it and the moment you use it the contact may
 change.  Any kind of background sync could cause this change to happen.  I
 would try to design the software in such a way that either doesn't need to
 do this type of resolution or uses something even more robust than lookup
 keys, e.g. raw contact IDs.

 I hope this helps,
 - Dmitri

 On Tue, Nov 3, 2009 at 6:40 AM, jarkman jark...@gmail.com wrote:
  Oh - one more question:

  Am I right in thinking that the lookup URI is not itself a unique,
  stable identifier ? That is, the lookup URI for one contact may be
  different at different times.

  Right now, we store some contact row IDs in a table, along with per-
  contact settings of our own. We use a WHERE clause on the contact ID
  to pull out the settings for a particular contact.

  If we store lookup URIs in the table, and want to find some current
  contact in that table, we cannot do it by comparing lookup URIs
  directly, because the lookup URI for the target contact may have
  changed since we wrote the table. If we want to compare two lookup
  URIs to see if they refer to the same person, we need to look them
  both up in the contacts table and see if they have the same record ID
  right now. Is that right ?

  Thanks,

  Richard

  On Nov 2, 5:32 pm, Dmitri Plotnikov dplotni...@google.com wrote:
   Hi Richard,

   You are exactly right.  If you want a robust persistent reference to a
   contact, you now need to use the lookup URI.  Android itself uses lookup
   URIs for shortcuts, Quick Contact etc.  The main reason contact ID is
   volatile is that Android 2.0 has contact aggregation, both automatic and
   manual.  Let's say your app stored a long ID of a contact.  Then the user
   goes and manually joins the contact with some other contact. Now we have
  one
   contact where we used to have two - the stored long contact ID points
   nowhere.  However, the lookup key is more resilient.  It's a string
   concatenating identities of raw contacts.  Using that string, we can
  still
   track down a contact as it is joined with others or separated from them.

   There are two options available to you: you can store just the lookup
  key,
   which is a string id of a contact, or you can use both the lookup and the
   long id of a contact.  The latter will give you better performance, but
   functionally the long id is not required.  I would take this approach: if
   you need to bulk-process contacts, maintain both ids.  If your app works
   with a single contact per 

Re: [android-developers] Re: Stable contact identity CONTENT_LOOKUP_URI

2009-11-04 Thread Dmitri Plotnikov
Hi Richard,

I can tell you what we did when we faced a similar requirement.  We needed
to store things like custom ringtone, straight-to-voicemail etc on a
per-contact basis.  What we ended up doing is simply replicating this
information into each raw contact in the aggregate. When raw contacts are
re-aggregated, we use a heuristic to figure out the values for the entire
aggregate (e.g. if one of the raw contacts has straight-to-voicemail=false,
then the entire contact has straight-to-voicemail=false).

I would do the same in your case.  You can always get _ids of all raw
contacts in an aggregate contact and then in your database have a row for
each of those raw contacts.   To retrieve the information for an aggregate
contact, you would pull it for all constituent raw contacts and use an
algorithm to aggregate the data.

Does that make sense?

Cheers,
- Dmitri

On Wed, Nov 4, 2009 at 4:45 AM, jarkman jark...@gmail.com wrote:

 Dmitri - thanks - that's perfect.

 So, we have two choices -

 (1) For each incoming contact URI, loop over our table of stored
 lookup keys, looking each one up with
 ContactsContract.Contacts.lookupContact(resolver, lookupUri) and
 comparing with the incoming contact.

 I think that will be reliable, and makes the best use of your cunning
 lookup mechanisms, but could be a performance problem.


 (2) Move our custom data into the generic data store in the contacts
 database ( as hinted at here:

 http://groups.google.com/group/android-developers/browse_thread/thread/690cd4e531205b0c/364e21a52b00491c?lnk=gstq=contacts#364e21a52b00491c
 )

 That should be reliable, but I am not sure what will happen to the
 generic data rows over contact aggregation and disaggregation.
 Presumably we may find a contact who has two instances of our custom
 data (after aggregation) or none (after disaggregation, if our custom
 data stayed with the other half of the results).


 (3) In our own table, keep all the raw contact IDs for each aggregated
 contact we are interested in. That lets us deal with the aftermath of
 aggregation and disaggregation explicitly, and it lets us search
 quickly by comparing IDs, but it means we need to do something
 complicated to clean up our data after a disaggregation has has
 happened.

 Do you think that covers it ?


 Richard

 On Nov 3, 7:17 pm, Dmitri Plotnikov dplotni...@google.com wrote:
  Hi Richard,
 
  Lookup key is unique at any point in time.  It's not unique over time.
 
  The anatomy of a lookup key is basically this.  If an aggregate contact
 has
  three raw contacts with server-side IDs A, B and C, the lookup key
  will effectively be  accountA/A.accountB/B.accountC/C
 
  We don't attempt to find a contact with that exact lookup key.  We
 actually
  parse it, find all those three raw contacts and infer the id of the new
  contact ID, which will be the one containing the most of the original raw
  contacts. In other words, even though the result is a bit unpredictable,
 the
  user shouldn't be surprised by what they see.  The original contact had
 A, B
  and C - now I am looking at something that has either A or B or C or a
  couple of those or maybe A,B,C and D.
 
  You are right that you should not use lookup keys to compare contact
  identities to each other.  You can use the
  ContactsContract.Contacts.lookupContact(resolver, lookupUri) method,
 which
  will give you the current contact ID for your contact.  Be careful though
 -
  between the moment you get it and the moment you use it the contact may
  change.  Any kind of background sync could cause this change to happen.
  I
  would try to design the software in such a way that either doesn't need
 to
  do this type of resolution or uses something even more robust than lookup
  keys, e.g. raw contact IDs.
 
  I hope this helps,
  - Dmitri
 
  On Tue, Nov 3, 2009 at 6:40 AM, jarkman jark...@gmail.com wrote:
   Oh - one more question:
 
   Am I right in thinking that the lookup URI is not itself a unique,
   stable identifier ? That is, the lookup URI for one contact may be
   different at different times.
 
   Right now, we store some contact row IDs in a table, along with per-
   contact settings of our own. We use a WHERE clause on the contact ID
   to pull out the settings for a particular contact.
 
   If we store lookup URIs in the table, and want to find some current
   contact in that table, we cannot do it by comparing lookup URIs
   directly, because the lookup URI for the target contact may have
   changed since we wrote the table. If we want to compare two lookup
   URIs to see if they refer to the same person, we need to look them
   both up in the contacts table and see if they have the same record ID
   right now. Is that right ?
 
   Thanks,
 
   Richard
 
   On Nov 2, 5:32 pm, Dmitri Plotnikov dplotni...@google.com wrote:
Hi Richard,
 
You are exactly right.  If you want a robust persistent reference to
 a
contact, you now need to use the lookup URI.  Android itself 

[android-developers] Re: Stable contact identity CONTENT_LOOKUP_URI

2009-11-03 Thread jarkman
Dmitri - thanks - that's very helpful. I have a couple more questions,
if that's OK:

In the short term, if we do not use the lookup URI, and go on storing
record IDs, we will clearly lose track of a contact when aggregation
or dis-aggregation of a contact takes place. Are there any other
circumstances where we will lose track ? For example, might an ID
change as a result of a sync which does not aggregate or disaggregate
a contact ?

When we use the lookup uri and a contact is disaggregated, will the
lookup URI we are holding still refer to one of the two resulting
contacts, or will it no longer refer to either of them ?

Incidentally, I wonder if it might be worth mentioning this change a
bit more prominently in the 2.0 release notes. If I hadn't happened
across the lookup key in the docs, I would not have realised that 2.0
broke all our contact references. I imagine other developers may not
be so lucky.

Thanks,

Richard

On Nov 2, 5:32 pm, Dmitri Plotnikov dplotni...@google.com wrote:
 Hi Richard,

 You are exactly right.  If you want a robust persistent reference to a
 contact, you now need to use the lookup URI.  Android itself uses lookup
 URIs for shortcuts, Quick Contact etc.  The main reason contact ID is
 volatile is that Android 2.0 has contact aggregation, both automatic and
 manual.  Let's say your app stored a long ID of a contact.  Then the user
 goes and manually joins the contact with some other contact. Now we have one
 contact where we used to have two - the stored long contact ID points
 nowhere.  However, the lookup key is more resilient.  It's a string
 concatenating identities of raw contacts.  Using that string, we can still
 track down a contact as it is joined with others or separated from them.

 There are two options available to you: you can store just the lookup key,
 which is a string id of a contact, or you can use both the lookup and the
 long id of a contact.  The latter will give you better performance, but
 functionally the long id is not required.  I would take this approach: if
 you need to bulk-process contacts, maintain both ids.  If your app works
 with a single contact per user action - you don't need to bother with the
 long id.

 I hope this helps,
 - Dmitri

 On Mon, Nov 2, 2009 at 9:02 AM, jarkman jark...@gmail.com wrote:
  In the course of moving to the 2.0 cotnact APIs, I've stumbled across
  CONTENT_LOOKUP_URI :

 http://developer.android.com/reference/android/provider/ContactsContr...

  As long as the contact's row ID remains the same, this URI is
  equivalent to CONTENT_URI. If the contact's row ID changes as a result
  of a sync or aggregation, this URI will look up the contact using
  indirect information 

  Currently, we store contact IDs to identify particular contacts. If I
  read this right, contact IDs will no longer be stable in the world of
  2.0, and we will need to store a lookup URI (or at least a LOOKUP_KEY
  and a row ID) in order to identify a contact in a stable way.

  That would be a substantial change in our code. So, before I rush off
  to do it, I'd love to find out if a contact row ID change is going to
  be a routine thing (say, on every sync), or if it will be a very rare
  thing (say, when two contacts are manually combined into one, or some
  even rarer exception).

  Any clues ?

  Thanks,

  Richard

  --
  You received this message because you are subscribed to the Google
  Groups Android Developers group.
  To post to this group, send email to android-developers@googlegroups.com
  To unsubscribe from this group, send email to
  android-developers+unsubscr...@googlegroups.comandroid-developers%2bunsubscr...@googlegroups.com
  For more options, visit this group at
 http://groups.google.com/group/android-developers?hl=en



-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


[android-developers] Re: Stable contact identity CONTENT_LOOKUP_URI

2009-11-03 Thread jarkman
Oh - one more question:

Am I right in thinking that the lookup URI is not itself a unique,
stable identifier ? That is, the lookup URI for one contact may be
different at different times.

Right now, we store some contact row IDs in a table, along with per-
contact settings of our own. We use a WHERE clause on the contact ID
to pull out the settings for a particular contact.

If we store lookup URIs in the table, and want to find some current
contact in that table, we cannot do it by comparing lookup URIs
directly, because the lookup URI for the target contact may have
changed since we wrote the table. If we want to compare two lookup
URIs to see if they refer to the same person, we need to look them
both up in the contacts table and see if they have the same record ID
right now. Is that right ?

Thanks,

Richard


On Nov 2, 5:32 pm, Dmitri Plotnikov dplotni...@google.com wrote:
 Hi Richard,

 You are exactly right.  If you want a robust persistent reference to a
 contact, you now need to use the lookup URI.  Android itself uses lookup
 URIs for shortcuts, Quick Contact etc.  The main reason contact ID is
 volatile is that Android 2.0 has contact aggregation, both automatic and
 manual.  Let's say your app stored a long ID of a contact.  Then the user
 goes and manually joins the contact with some other contact. Now we have one
 contact where we used to have two - the stored long contact ID points
 nowhere.  However, the lookup key is more resilient.  It's a string
 concatenating identities of raw contacts.  Using that string, we can still
 track down a contact as it is joined with others or separated from them.

 There are two options available to you: you can store just the lookup key,
 which is a string id of a contact, or you can use both the lookup and the
 long id of a contact.  The latter will give you better performance, but
 functionally the long id is not required.  I would take this approach: if
 you need to bulk-process contacts, maintain both ids.  If your app works
 with a single contact per user action - you don't need to bother with the
 long id.

 I hope this helps,
 - Dmitri

 On Mon, Nov 2, 2009 at 9:02 AM, jarkman jark...@gmail.com wrote:
  In the course of moving to the 2.0 cotnact APIs, I've stumbled across
  CONTENT_LOOKUP_URI :

 http://developer.android.com/reference/android/provider/ContactsContr...

  As long as the contact's row ID remains the same, this URI is
  equivalent to CONTENT_URI. If the contact's row ID changes as a result
  of a sync or aggregation, this URI will look up the contact using
  indirect information 

  Currently, we store contact IDs to identify particular contacts. If I
  read this right, contact IDs will no longer be stable in the world of
  2.0, and we will need to store a lookup URI (or at least a LOOKUP_KEY
  and a row ID) in order to identify a contact in a stable way.

  That would be a substantial change in our code. So, before I rush off
  to do it, I'd love to find out if a contact row ID change is going to
  be a routine thing (say, on every sync), or if it will be a very rare
  thing (say, when two contacts are manually combined into one, or some
  even rarer exception).

  Any clues ?

  Thanks,

  Richard

  --
  You received this message because you are subscribed to the Google
  Groups Android Developers group.
  To post to this group, send email to android-developers@googlegroups.com
  To unsubscribe from this group, send email to
  android-developers+unsubscr...@googlegroups.comandroid-developers%2bunsubscr...@googlegroups.com
  For more options, visit this group at
 http://groups.google.com/group/android-developers?hl=en



-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en


Re: [android-developers] Re: Stable contact identity CONTENT_LOOKUP_URI

2009-11-03 Thread Dmitri Plotnikov
Hi Richard,

Lookup key is unique at any point in time.  It's not unique over time.

The anatomy of a lookup key is basically this.  If an aggregate contact has
three raw contacts with server-side IDs A, B and C, the lookup key
will effectively be  accountA/A.accountB/B.accountC/C

We don't attempt to find a contact with that exact lookup key.  We actually
parse it, find all those three raw contacts and infer the id of the new
contact ID, which will be the one containing the most of the original raw
contacts. In other words, even though the result is a bit unpredictable, the
user shouldn't be surprised by what they see.  The original contact had A, B
and C - now I am looking at something that has either A or B or C or a
couple of those or maybe A,B,C and D.

You are right that you should not use lookup keys to compare contact
identities to each other.  You can use the
ContactsContract.Contacts.lookupContact(resolver, lookupUri) method, which
will give you the current contact ID for your contact.  Be careful though -
between the moment you get it and the moment you use it the contact may
change.  Any kind of background sync could cause this change to happen.  I
would try to design the software in such a way that either doesn't need to
do this type of resolution or uses something even more robust than lookup
keys, e.g. raw contact IDs.

I hope this helps,
- Dmitri


On Tue, Nov 3, 2009 at 6:40 AM, jarkman jark...@gmail.com wrote:

 Oh - one more question:

 Am I right in thinking that the lookup URI is not itself a unique,
 stable identifier ? That is, the lookup URI for one contact may be
 different at different times.

 Right now, we store some contact row IDs in a table, along with per-
 contact settings of our own. We use a WHERE clause on the contact ID
 to pull out the settings for a particular contact.

 If we store lookup URIs in the table, and want to find some current
 contact in that table, we cannot do it by comparing lookup URIs
 directly, because the lookup URI for the target contact may have
 changed since we wrote the table. If we want to compare two lookup
 URIs to see if they refer to the same person, we need to look them
 both up in the contacts table and see if they have the same record ID
 right now. Is that right ?

 Thanks,

 Richard


 On Nov 2, 5:32 pm, Dmitri Plotnikov dplotni...@google.com wrote:
  Hi Richard,
 
  You are exactly right.  If you want a robust persistent reference to a
  contact, you now need to use the lookup URI.  Android itself uses lookup
  URIs for shortcuts, Quick Contact etc.  The main reason contact ID is
  volatile is that Android 2.0 has contact aggregation, both automatic and
  manual.  Let's say your app stored a long ID of a contact.  Then the user
  goes and manually joins the contact with some other contact. Now we have
 one
  contact where we used to have two - the stored long contact ID points
  nowhere.  However, the lookup key is more resilient.  It's a string
  concatenating identities of raw contacts.  Using that string, we can
 still
  track down a contact as it is joined with others or separated from them.
 
  There are two options available to you: you can store just the lookup
 key,
  which is a string id of a contact, or you can use both the lookup and the
  long id of a contact.  The latter will give you better performance, but
  functionally the long id is not required.  I would take this approach: if
  you need to bulk-process contacts, maintain both ids.  If your app works
  with a single contact per user action - you don't need to bother with the
  long id.
 
  I hope this helps,
  - Dmitri
 
  On Mon, Nov 2, 2009 at 9:02 AM, jarkman jark...@gmail.com wrote:
   In the course of moving to the 2.0 cotnact APIs, I've stumbled across
   CONTENT_LOOKUP_URI :
 
  http://developer.android.com/reference/android/provider/ContactsContr.
 ..
 
   As long as the contact's row ID remains the same, this URI is
   equivalent to CONTENT_URI. If the contact's row ID changes as a result
   of a sync or aggregation, this URI will look up the contact using
   indirect information 
 
   Currently, we store contact IDs to identify particular contacts. If I
   read this right, contact IDs will no longer be stable in the world of
   2.0, and we will need to store a lookup URI (or at least a LOOKUP_KEY
   and a row ID) in order to identify a contact in a stable way.
 
   That would be a substantial change in our code. So, before I rush off
   to do it, I'd love to find out if a contact row ID change is going to
   be a routine thing (say, on every sync), or if it will be a very rare
   thing (say, when two contacts are manually combined into one, or some
   even rarer exception).
 
   Any clues ?
 
   Thanks,
 
   Richard
 
   --
   You received this message because you are subscribed to the Google
   Groups Android Developers group.
   To post to this group, send email to
 android-developers@googlegroups.com
   To unsubscribe from this group, send email to