Hi Jake, The database structure is actually extremely straightforward:
"Contacts" represents an aggregated contact "RawContacts" represents a contact as it was inserted by the sync adapter. RawContact has a CONTACT_ID field that binds it to a Contact. "Data" represents everything about a RawContact: emails, phone numbers, notes, birthday, high school graduation year, you name it. Data has a RAW_CONTACT_ID field that binds it a RawContact. The other important field is MIMETYPE. That's what determines the kind of data stored in a Data row. Everything else is just convenience API. So here's the most common way of inserting a data row: values.put(Data.RAW_CONTACT_ID, rawContactId); values.put(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE); values.put(Note.NOTE, "Blah blah blah"); resolver.insert(Data.CONTENT_URI, null, values); I hope this helps. - Dmitri On Wed, Nov 4, 2009 at 6:11 PM, jak. <[email protected]> wrote: > Thank you Dmitri, > > Your response was very helpful. Along with that, and the sample you > posted on another thread about using both Contact Apis from one app, > I've gotten most of the way there. It is much appreciated. > > I'm still however having some problems that I'm hard pressed to find a > solution for. > I'd be grateful if anyone could help me. > > The biggest challenge I'm having with this API is that it's hard for > me to picture how the tables are laid out so I know which URI to query > to get the parts of the contact that I'm interested in. > I found to get the email address for a contact I'm looking at I can > query the uri:ContactsContract.CommonDataKinds.Email.CONTENT_URI, > looking at rows of the contact id i'm interested in. > > However to get the note from the same contact I can't use a similar > pattern, because there is no > ContactsContract.CommonDataKinds.Note.CONTENT_URI > The Note type exists in CommonDataKinds but it doesn't have an > associated CONTENT_URI. > > I'm finding it very frustrating to use this API because every time I > go to try to pull out another piece of data from the contact, the > method to access it seems to change (as I can't find a consistent way > to get a given field from a contact). And the documentation never > describes how these keys, tables, and URIs are related. Basically the > ContactsContract documentation just gives you a giant list of Objects > containing constants that describe indexes into some database that is > basically a black box without some basic documentation. > > I'm I the only one that finds this frustrating? > > Thanks again for your help. > > -Jake > > On Nov 2, 5:24 pm, Dmitri Plotnikov <[email protected]> wrote: > > You can always delegate contact creation to the Contacts app using the > > ContactsContract.Intents.UI.Insert intent with extras. This will show the > > edit UI. > > > > If you want to explicitly create the contact by yourself, that's now a > bit > > tricky because Android 2.0 support multiple accounts. > > > > First of all, you will need to figure out which account you want to > create > > the contact in. Get a list of all available accounts from AccountManager: > > > > AccountManager am = AccountManager.get(getContext()); > > Account[] accounts = am.getAccounts(); > > > > Also, get a list of all sync adapters and find the ones that support > > contacts: > > > > SyncAdapterType[] syncs > > = ContentResolver.getContentService().getSyncAdapterTypes(); > > > > for (SyncAdapterType sync : syncs) { > > if (ContactsContract.AUTHORITY.equals(sync.authority) && > > sync.supportsUploading()) { > > contactAccountTypes.add(sync.accountType); > > } > > > > } > > > > Now you have a list of all accounts and a list of account types that > support > > contacts. So here's your account list: > > > > for (Account acct: accounts) { > > if (contactAccountTypes.contains(acct.type)) { > > contactAccounts.add(account); > > } > > > > } > > > > If the contactAccounts list contains nothing - use accountType = null and > > accountName = null > > If it contains exactly one account, use it. > > If it contains multiple accounts, build a dialog and ask the user which > > account to use. > > > > From here on it gets easier. > > > > Let's start with a more traditional method. Insert a raw contact first: > > > > ContentValues values = new ContentValues(); > > values.put(RawContacts.ACCOUNT_TYPE, accountType); > > values.put(RawContacts.ACCOUNT_NAME, accountName); > > Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, > > values); > > long rawContactId = ContentUris.parseId(rawContactUri); > > > > Then insert the name: > > > > values.clear(); > > values.put(Data.RAW_CONTACT_ID, rawContactId); > > values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); > > values.put(StructuredName.DISPLAY_NAME, "Some Body"); > > getContentResolver().insert(Data.CONTENT_URI, values); > > > > You are done. > > > > Now here's a much better way to do the same. Use the > > new ContentProviderOperation API, which will ensure that the raw contact > and > > its name are inserted at the same time. > > > > ArrayList<ContentProviderOperation> ops = Lists.newArrayList(); > > ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) > > .withValue(RawContacts.ACCOUNT_TYPE, accountType) > > .withValue(RawContacts.ACCOUNT_NAME, accountName) > > .build()); > > > > ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI) > > .withValueBackReference(Data.RAW_CONTACT_ID, 0) > > .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE) > > .withValue(StructuredName.DISPLAY_NAME, "Some Body") > > .build()); > > > > getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); > > > > I hope this helps. > > - Dmitri > > > > > > > > On Mon, Nov 2, 2009 at 4:23 PM, jak. <[email protected]> wrote: > > > Hello, > > > > > I'm currently working on porting our Android app to 2.0 but I'm having > > > a rather hard time figuring out what is required to interact with the > > > new Contacts API. > > > I'm using reflection to decide whether the new API is available, if it > > > is I attempt to use the new features, otherwise I fall back to our old > > > methods. > > > > > However, I'm having a hard time finding analogs to the old > > > functionality in the new API. > > > For example in the past I was adding contacts to the database from an > > > external text source by creating a ContentValues object, filling it > > > with information on the contact and then adding it with a call to: > > > Contacts.People.createPersonInMyContactsGroup(...); > > > > > i.e.: > > > ... > > > > > ContentValues personValues = new ContentValues(); > > > personValues.put(Contacts.People.NAME, "Some Body"); > > > Uri personUri = Contacts.People.createPersonInMyContactsGroup > > > (curContext().getContentResolver(), personValues); > > > > > ... > > > How can I achieve the same goal in the new API? > > > > > I appreciate all the hard work going into improving the APIs but I > > > must admit I'm a bit frustrated by the lack of documentation and > > > examples. > > > I realize we have plenty of Javadocs on developer.android.com to > > > reference, but those only really show us what the new interfaces are. > > > I'm having a really hard time finding any discussion in terms of how > > > the new API is intended to be used. > > > > > Any help would be greatly appreciated! > > > Thanks! > > > > > -- > > > You received this message because you are subscribed to the Google > > > Groups "Android Developers" group. > > > To post to this group, send email to > [email protected] > > > To unsubscribe from this group, send email to > > > [email protected]<android-developers%[email protected]><android-developers%2Bunsubs > [email protected]> > > > 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 [email protected] > To unsubscribe from this group, send email to > [email protected]<android-developers%[email protected]> > 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 [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

