App Inventor, API Access and Authentication


Accessing the Google Contacts API with App Inventor

Note: Google was modernizing OAuth interactions in Native Apps for Better Usability and Security, which means, this solution to receive an access token via webview unfortunately does not work anymore starting from April 20, 2017.
Currently there is no workaround available... Someone will have to write a Contacts extension...


In the forum there are questions like these:

With App Inventor unfortunately you can't get this information directly, but if the contacts are synchronised with Google, you can use the Google Contacts API to get it! The Google Contacts API allows client applications to view and update a user's contacts. Contacts are stored in the user's Google Account.

The demo app downloads 500 contacts of the current user and creates 2 lists: a phone number list and a contact name list. Now we can search for a phone number to get the corresponding contact name or search for a contact to get the corresponding phone number.

Issue 734, Issue 1233 and Issue 1522 are no issues anymore!

Screen1

Screenshots

On first run of the app, the user must authorize the app to be able to download the contacts from Google.

Blocks

For your own app, first register your application as described here, to be able to use OAuth to access Google APIs. In "APIs", just enable the Contacts API instead.

Then use these blocks for the further basic steps of the OAuth process.

Do you need help with your App Inventor project?

I can help you: for one hour I charge 25 USD.
Please contact me at info [at] puravidaapps [dot] com for details!
For questions about App Inventor, please use the App Inventor forum. Thank you.

Screen2

Screenshots


New features:

Blocks

Normally the data is provided in XML format. However with the parameter alt=json we can get it in JSON format, which is easier to convert into a list of lists in App Inventor for further processing. Normally only 25 contacts will be provided. Therefore I set the max-results parameter to 500 to be able to download 500 contacts.


Each item of listContact looks like this:

        ((category (((scheme http://schemas.google.com/g/2005#kind) (term http://schemas.google.com/contact/2008#contact))))
(content (($t *empty-string*) (type text)))
(gd$phoneNumber ((($t 29999997) (primary true) (rel http://schemas.google.com/g/2005#home))))
(id (($t http://www.google.com/m8/feeds/contacts/taifunbaer%40gmail.com/base/1bfe5b90e3ba938)))
(link (((href https://www.google.com/m8/feeds/photos/media/taifunbaer%40gmail.com/1bfe5b90e3ba938/1B2M2Y8AsgTpgAmY7PhCfg) (rel http://schemas.google.com/contacts/2008/rel#edit-photo) (type image/*))
((href https://www.google.com/m8/feeds/contacts/taifunbaer%40gmail.com/full/1bfe5b90e3ba938) (rel self) (type application/atom+xml))
((href https://www.google.com/m8/feeds/contacts/taifunbaer%40gmail.com/full/1bfe5b90e3ba938/1363548315854001) (rel edit) (type application/atom+xml))))
(title (($t Felipe) (type text))) (updated (($t 2013-03-17T19:25:15.854Z))) )

Note: In the example, I stored only the first phone number found for a contact.

The following blocks create 2 lists, a name list and a phone number list. Now it's easy to search for a phone number or a contact. As you can see, this is a nice example to demonstrate how to work with list of lists...




Searching for a phone number or a contact name

Notes

I did not take a look into creating, updating or deleting a contact, but most probably this is also possible using this interface with App Inventor.

Questions and Answers

Q1: How can I delete a contact?
A: Please take a look at the documentation of the Contacts API: To delete a contact, send an authorized DELETE request to the contact's edit URL.. First you need the id to be able to delete a contact. From the example above the id is this string: 1bfe5b90e3ba938. You will have to build a new list with the ids and while building the list you have to extract the id for each contact, similar as it is already done with the title, you can use my procedure getValue to get the complete string http://www.google.com/m8/feeds/contacts/taifunbaer%40gmail.com/base/1bfe5b90e3ba938 Now split the string at / to get a list using the split block. The id is the last item in that list.

Q2: How can I add a contact?
A: Please take a look at the documentation of the Contacts API: To create a new contact, send an authorized POST request to the user's contacts feed URL with contact data in the body.. Use Content-Type application/atom+xml and add a body in the same format as the example in the documentation.

Your screenshot looks line. However instead of the empty string you should send a xml format to the API. Just use the join block to build it. An example xml format is the following:

<atom:entry xmlns:atom='http://www.w3.org/2005/Atom'
    xmlns:gd='http://schemas.google.com/g/2005'>
  <atom:category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/contact/2008#contact'/>
  <gd:name>
     <gd:givenName>Elizabeth</gd:givenName>
     <gd:familyName>Bennet</gd:familyName>
     <gd:fullName>Elizabeth Bennet</gd:fullName>
  </gd:name>
  <atom:content type='text'>Notes</atom:content>
  <gd:email rel='http://schemas.google.com/g/2005#work'
    primary='true'
    address='liz@gmail.com' displayName='E. Bennet'/>
  <gd:email rel='http://schemas.google.com/g/2005#home'
    address='liz@example.org'/>
  <gd:phoneNumber rel='http://schemas.google.com/g/2005#work'
    primary='true'>
    (206)555-1212
  </gd:phoneNumber>
  <gd:phoneNumber rel='http://schemas.google.com/g/2005#home'>
    (206)555-1213
  </gd:phoneNumber>
  <gd:im address='liz@gmail.com'
    protocol='http://schemas.google.com/g/2005#GOOGLE_TALK'
    primary='true'
    rel='http://schemas.google.com/g/2005#home'/>
  <gd:structuredPostalAddress
      rel='http://schemas.google.com/g/2005#work'
      primary='true'>
    <gd:city>Mountain View</gd:city>
    <gd:street>1600 Amphitheatre Pkwy</gd:street>
    <gd:region>CA</gd:region>
    <gd:postcode>94043</gd:postcode>
    <gd:country>United States</gd:country>
    <gd:formattedAddress>
      1600 Amphitheatre Pkwy Mountain View
    </gd:formattedAddress>
  </gd:structuredPostalAddress>
</atom:entry>
      

Test

Tested successfully on Nexus 5 running Android 4.4.4.

Back to top of page ...


Home | Snippets | Tutorials | Extensions | News | Forums | Links | Search | Contact