Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Facebook Contacts

  By using the Facebook Developer Toolkit and the Bluetooth and Contacts APIs from the Coding4Fun Developer Toolkit, I created an application which transfers information about your Facebook friends to your mobile phone.
Clarity Consulting

Difficulty: Intermediate
Time Required: 6-10 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions, Microsoft Windows Vista, Coding4Fun Developer Toolkit, Facebook Developer Toolkit
Hardware: Bluetooth-enabled computer and phone
Download: Download

 

Facebook is a great social networking site which keeps track of all kinds of information about your friends. Since things like your friends’ hometown, picture, and even the correct spelling of their name are already provided for you there, it would be great if you could automatically send all of that information to your phone, instead of having to manually type it in yourself. By using a couple of different toolkits, I was able to create a simple application which does all of this for me without writing a lot of code.

Disclaimer: Unfortunately, the Facebook API does not allow you to get a user’s contact information, such as phone number or e-mail address. If it did, they would certainly be included here, but as it is I’m limited to the information that Facebook provides.

To give a quick overview, the sample first uses the Facebook Developer Toolkit to connect to Facebook and download information about the user’s friends. These are displayed in a list on the main form, and multiple users can be selected with checkboxes. Then, using the Bluetooth API from the Coding4Fun Developer Toolkit, I get a list of Bluetooth devices (including mobile phones) within range, allowing the user to select one of them. Finally, when the user clicks “OK”, I use the Contacts API, also from the Coding4Fun toolkit, to turn each of the selected users into a transferable file, and then send it to the phone over a Bluetooth connection. The following sections describe this process in more detail.

facebookContactsScreen 

Figure 1: The Facebook Contacts main screen

 

Retrieving Information From Facebook

To get started developing applications with the Facebook API, you first need to register your application and get an API key from Facebook which will allow you to connect to their site and download data. Their Get Started page will lead you through the process.

Now that you have an API key, you can start developing. While you can connect to Facebook and get the information manually through HTTP REST calls, I chose to use the Facebook Developer Toolkit, which took care of maintaining a connection, requesting the information, and parsing the response into objects that I can use in code. The following code loads the user’s friends into memory, using the included FacebookService component:  

C#

private void LoadFriends() { List<User> users = new List<User>(); try { users = new List<User>(facebookService1.GetFriends()); } catch (FacebookInvalidUserException) { this.Close(); return; } catch (FacebookException) { // do nothing: this exception just means no friends were returned, // so we can leave the users list empty } users.Sort(Compare); _friends = users; }

VB.NET

Private Sub LoadFriends() Dim users As List(Of User) = New List(Of User)() Try users = New List(Of User)(facebookService1.GetFriends()) Catch e1 As FacebookInvalidUserException Me.Close() Return Catch e2 As FacebookException ' do nothing: this exception just means no friends were returned, ' so we can leave the users list empty End Try users.Sort(AddressOf Compare) _friends = users End Sub

I sort the users by comparing their last names, and then their first names if the last names are equal:

C#

private int Compare(User leftUser, User rightUser) { int lastNameComparison = leftUser.LastName.CompareTo(rightUser.LastName); if (lastNameComparison != 0) { return lastNameComparison; } return leftUser.FirstName.CompareTo(rightUser.FirstName); }

VB.NET

Private Function Compare(ByVal leftUser As User, ByVal rightUser As User) As Integer Dim lastNameComparison As Integer = leftUser.LastName.CompareTo(rightUser.LastName) If lastNameComparison <> 0 Then Return lastNameComparison End If Return leftUser.FirstName.CompareTo(rightUser.FirstName) End Function

On Facebook, most users are a part of one or more “networks”, such as “Chicago, IL”, or “Notre Dame”. For my application, I wanted to be able to filter the displayed friends according to their associated networks. To do this, I first had to get a list of networks from all my Facebook friends:

C#

private List<string> GetNetworks() { List<string> networkNames = new List<string>(); foreach (User friend in _friends) { foreach (Network network in friend.Affiliations) { if (!networkNames.Contains(network.Name)) { networkNames.Add(network.Name); } } } networkNames.Sort(); networkNames.Insert(0, ALL_NETWORKS); return networkNames; }

VB.NET

Private Function GetNetworks() As List(Of String) Dim networkNames As List(Of String) = New List(Of String)() For Each [friend] As User In _friends For Each network As Network In [friend].Affiliations If (Not networkNames.Contains(network.Name)) Then networkNames.Add(network.Name) End If Next network Next [friend] networkNames.Sort() networkNames.Insert(0, ALL_NETWORKS) Return networkNames End Function

This list was displayed as a combo box on my form. Then, whenever the selection in the combo box changed, I had to filter the displayed list:

C#

private void FilterDisplayedFriends(string selectedNetwork) { List<User> friendsToDisplay; if (selectedNetwork.Equals(ALL_NETWORKS)) { friendsToDisplay = _friends; } else { friendsToDisplay = new List<User>(); foreach (User friend in _friends) { foreach (Network network in friend.Affiliations) { if (network.Name.Equals(selectedNetwork)) { friendsToDisplay.Add(friend); continue; } } } } Display(friendsToDisplay); }

VB.NET

Private Sub FilterDisplayedFriends(ByVal selectedNetwork As String) Dim friendsToDisplay As List(Of User) If selectedNetwork.Equals(ALL_NETWORKS) Then friendsToDisplay = _friends Else friendsToDisplay = New List(Of User)() For Each [friend] As User In _friends For Each network As Network In [friend].Affiliations If network.Name.Equals(selectedNetwork) Then friendsToDisplay.Add([friend]) Continue For End If Next network Next [friend] End If Display(friendsToDisplay) End Sub

Connecting to the Phone via Bluetooth

Now we have a list of friends that we can search through and select from. The next step is to transform the users we are going to send to the phone into vCard files. vCards are a common, human-readable file format for exchanging contact information between computers or other devices. Fortunately, the Contacts API released with the Coding4Fun Toolkit can create vCards for me. All I have to do is provide the mapping from the properties of a Facebook User object to those of a Contact object (using the included SimpleContactView).

C# 

private void FillContact(Contact contact, User facebookUser, WebClient webClient) { SimpleContactView simpleContact = new SimpleContactView(contact); simpleContact.FirstName = facebookUser.FirstName; simpleContact.LastName = facebookUser.LastName; Location location = facebookUser.CurrentLocation; if (location != null) { simpleContact.HomeCity = location.City; if (location.StateAbbreviation != Facebook.Entity.StateAbbreviation.Unknown) { simpleContact.HomeState = location.StateAbbreviation.ToString(); } if (location.Country != Facebook.Entity.Country.Unknown) { simpleContact.HomeCountry = ToString(location.Country); } simpleContact.HomeZip = location.ZipCode; } if (facebookUser.Sex == Facebook.Entity.Gender.Female) { simpleContact.Gender = Contacts.Gender.Female; } else if (facebookUser.Sex == Facebook.Entity.Gender.Male) { simpleContact.Gender = Contacts.Gender.Male; } else { simpleContact.Gender = Contacts.Gender.Unspecified; } if (!facebookUser.PictureUrl.Equals(DEFAULT_FACEBOOK_PICTURE)) { string pictureFile = Path.GetTempFileName(); webClient.DownloadFile(facebookUser.PictureUrl, pictureFile); using (FileStream fs = new FileStream(pictureFile, FileMode.Open)) { contact.Photos[PhotoLabels.UserTile] = new Contacts.Photo(fs, "image"); } File.Delete(pictureFile); } }

VB.NET

Private Sub FillContact(ByVal contact As Contact, ByVal facebookUser As User, ByVal webClient As WebClient) Dim simpleContact As SimpleContactView = New SimpleContactView(contact) simpleContact.FirstName = facebookUser.FirstName simpleContact.LastName = facebookUser.LastName Dim location As Location = facebookUser.CurrentLocation If Not location Is Nothing Then simpleContact.HomeCity = location.City If location.StateAbbreviation <> Facebook.Entity.StateAbbreviation.Unknown Then simpleContact.HomeState = location.StateAbbreviation.ToString() End If If location.Country <> Facebook.Entity.Country.Unknown Then simpleContact.HomeCountry = ToString(location.Country) End If simpleContact.HomeZip = location.ZipCode End If If facebookUser.Sex = Facebook.Entity.Gender.Female Then simpleContact.Gender = Contacts.Gender.Female ElseIf facebookUser.Sex = Facebook.Entity.Gender.Male Then simpleContact.Gender = Contacts.Gender.Male Else simpleContact.Gender = Contacts.Gender.Unspecified End If If (Not facebookUser.PictureUrl.Equals(DEFAULT_FACEBOOK_PICTURE)) Then Dim pictureFile As String = Path.GetTempFileName() webClient.DownloadFile(facebookUser.PictureUrl, pictureFile) Using fs As FileStream = New FileStream(pictureFile, FileMode.Open) contact.Photos(PhotoLabels.UserTile) = New Contacts.Photo(fs, "image") End Using File.Delete(pictureFile) End If End Sub

Finally, now that we can create vCards for Facebook users, we can make one for each selected user and send them off to the phone. First, however, we need to learn a little bit about how Bluetooth works. Every Bluetooth device implements a set of “profiles”, which are interface specifications that let Bluetooth devices know how to communicate with each other. Each profile is responsible for providing a different kind of service, such as phone headset communication, video streaming, and file transfer. To communicate with another Bluetooth device, you have to first find out if the device supports the profile you wish to use, connect to the device using that profile, and use the interface defined by the profile to accomplish your tasks.

For this application, I used the Object Push Profile (known as OBEX Object Push in the API), which is specifically designed to transfer objects such as vCards from one phone to another. The OppMananger component in the API takes care of the more difficult parts of making the connection. Once I’m connected, I just create a vCard for each user, transfer each one, and disconnect when I’m done:

C#

private void SendToPhone(IEnumerable<User> users) { Device device = (Device) cmbDevices.SelectedItem; RemoteService pushService; try { pushService = deviceServicesManager1.DiscoverServicesByType(device, ServiceType.OBEXObjectPush).ElementAt(0); } catch { MessageBox.Show("Could not connect to Bluetooth device " + cmbDevices.Text + ". It may be out of range."); return; } try { oppManager1.NetworkStream = pushService.Connect(); } catch (ServiceConnectionException) { MessageBox.Show("Could not connect to Bluetooth device " + device.Name); return; } oppManager1.Connect(); WebClient webClient = new WebClient(); foreach (User user in users) { Contact contact = CreateContact(user, webClient); string tempFile = Path.GetTempFileName(); string tempVCard = Path.GetDirectoryName(tempFile) + "\\" + Path.GetFileNameWithoutExtension(tempFile) + ".vcf"; File.Delete(tempFile); contactsService1.SaveContactToVCard(contact, tempVCard); oppManager1.PushObject(tempVCard); File.Delete(tempVCard); } oppManager1.Disconnect(); pushService.Disconnect(); MessageBox.Show("Successfully transferred " + users.Count() + " friends to " + device.Name + "."); }

VB.NET

Private Sub SendToPhone(ByVal users As IEnumerable(Of User)) Dim device As Device = CType(cmbDevices.SelectedItem, Device) Dim pushService As RemoteService Try pushService = deviceServicesManager1.DiscoverServicesByType(device, ServiceType.OBEXObjectPush).ElementAt(0) Catch MessageBox.Show("Could not connect to Bluetooth device " & cmbDevices.Text & ". It may be out of range.") Return End Try Try oppManager1.NetworkStream = pushService.Connect() Catch e1 As ServiceConnectionException MessageBox.Show("Could not connect to Bluetooth device " & device.Name) Return End Try oppManager1.Connect() Dim webClient As WebClient = New WebClient() For Each user As User In users Dim contact As Contact = CreateContact(user, webClient) Dim tempFile As String = Path.GetTempFileName() Dim tempVCard As String = Path.GetDirectoryName(tempFile) & "\" & Path.GetFileNameWithoutExtension(tempFile) & ".vcf" File.Delete(tempFile) contactsService1.SaveContactToVCard(contact, tempVCard) oppManager1.PushObject(tempVCard) File.Delete(tempVCard) Next user oppManager1.Disconnect() pushService.Disconnect() MessageBox.Show("Successfully transferred " & users.Count() & " friends to " & device.Name & ".") End Sub

Voila! You can now see your Facebook friends, including their profile pictures, on your phone. This application can also save Facebook friends as Windows Contacts. The code is mostly identical, except that the contacts get saved directly to the local machine using the ContactsService component, instead of using Bluetooth to connect to a separate device.

Conclusion

The three APIs I used for this project (Facebook, Bluetooth, and Contacts) made the application a breeze to set up. With the exception of one or two bits of code that could be improved, the APIs were all very simple and easy to use, and took care of all the low-level details so that I could focus on the code relevant to this project. There’s still more work that could be done, including more ways to search through Facebook friends besides the network and improving load time. Overall, though, I’m very pleased with how it came out, and I hope this has shown you how you can take advantage of some of these APIs to create a really useful tool.

About the Author

Jon Schuster is a consultant at Clarity Consulting, and can be reached at his e-mail address, jschuster [at] claritycon [dot] com

Follow the Discussion

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.