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!
On first run of the app, the user must authorize the app to be able to download the contacts from Google.
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.
New features:
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
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.
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>
Tested successfully on Nexus 5 running Android 4.4.4.