[android-developers] Re: Stable contact identity CONTENT_LOOKUP_URI
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
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
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
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
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