In my previous blog post, Bing Translator for Windows Phone, I explained how you can develop a simple translation service using Bing's SOAP API. This time, I'll demonstrate how you can develop the same service using Google's REST API.
Download the application source code and read the following tutorial to learn how to develop it yourself.
Note: REST is an HTTP-based architectural style, used to send and receive data. It is generally more light-weight than SOAP, but it does not expose methods. As a result, we need to handle the data ourselves in order to extract the desired values. Data can be serialized either as XML or JSON (Google Translate uses JSON format).
Step 1: The User Interface
The user interface is exactly the same as the one we created for Bing. Launch Visual Studio, create a new Windows Phone 7 portrait application, name it "WindowsPhoneGoogleTranslate
" and start dragging-n-dropping the appropriate controls: Two list boxes (for language selection), two text boxes (for input and output text) and a button (for translation). Here is the corresponding XAML code:
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<StackPanel Orientation="Vertical">
<TextBlock>From</TextBlock>
<ListBox Name="lbxFrom"
Height="140"></ListBox>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock>To</TextBlock>
<ListBox Name="lbxTo"
Height="140"></ListBox>
</StackPanel>
</StackPanel>
<TextBox Name="txtInput"
Text="" Height="180" />
<Button Name="btnTranslate" Content="Translate"
Click="btnTranslate_Click" />
<TextBox Name="txtOutput"
Text="" Height="180" />
</StackPanel>
Step 2: Creating the Languages Source
Copying from my previews post, each language has two properties: A name (such as "English
", "French
", "Greek
", etc.) and a unique code (such as "en
", "fr
", "el
" respectively). An object containing both properties is necessary, so create the following class and place it in a Language.cs file:
public class Language
{
public string Code { get; set; }
public string Name { get; set; }
}
The user needs to see the language name only - and not the code. So, when retrieving the appropriate data, only the Name
property will be displayed in the UI. Modify the DataTemplate
of the list boxes to achieve this:
<ListBox Name="lbxFrom" Height="140">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" FontSize="25" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now navigate to MainPage.xaml.cs and create a list to store the languages:
private List<Language> _languages = new List<Language>();
Unfortunately, the Google API offers no means to retrieve the available languages programmatically. As a result, I had to hard-code them in an XML file named Languages.xml. Its structure is the following (you can easily add more languages if Google ever extends its API):
="1.0"="utf-8"="yes"
<languages>
<language>
<code>af</code>
<name>Afrikaans</name>
</language>
<language>
<code>sq</code>
<name>Albanian</name>
</language>
<language>
<code>ar</code>
<name>Arabic</name>
</language>
</languages>
The above languages ought to be displayed when MainPage.xaml.cs finishes loading. I have used a simple LINQ-to-XML query, but you can use whichever retrieval method you are comfortable with. The query selects the values of the XML file's nodes and then populates our Language
list. Finally, the list is binded to the proper list boxes.
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
XDocument langDocument = XDocument.Load("Languages.xml");
_languages = (from language in langDocument.Descendants("language")
select new Language
{
Code = language.Element("code").Value,
Name = language.Element("name").Value
}).ToList();
lbxFrom.ItemsSource = _languages;
lbxTo.ItemsSource = _languages;
}
Step 3: Using Google REST Services
Unlike SOAP, REST does not require a service reference addition. The results are generated according to the query-string we provide. Here is an example of a valid Google Translate query-string which translates "Hello world
" from English
(en
) to French
(fr
):
https://www.googleapis.com/language/translate/v2?key=YOUR-API-KEY&source=en&target=fr&q=Hello world
Firstly, obtain a free Google application key and paste it in the above URL replacing "YOUR-API-KEY
" parameter. Then, type the URL in your browser address bar and hit enter. The browser should respond to the following:
{"data":{"translations":[{"translatedText":"Bonjour tout le monde"}]}}
This is nothing but a simple JSON response containing the text value we want! Let's find out how we can get that value programmatically.
We need a pattern for the Google API URL, specifying the proper parameters (key
, source
, target
and q
). Trying to keep the code snippets simple, I consider the key
parameter as not a subject to change.
private readonly string SERVICE_URL =
"https://www.googleapis.com/language/translate/" +
"v2?key=YOUR-API-KEY&source={0}&target={1}&q={2}";
Someone has to manage the web requests and web responses now. Fortunately, Silverlight supports WebClient
class for this work, making our life easier!
private WebClient _proxy = new WebClient();
WebClient
generates a proxy able to create an HTTP request and then download its response in plain text format. We only need to handle DownloadStringCompleted
event handler (declare it in MainPage
constructor):
_proxy.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(DownloadStringCompleted);
DownloadStringCompleted
will be called right after proxy's DownloadStringAsync
method makes the HTTP request and finishes downloading the response. So, let's navigate to our button's event handler and specify the source
, target
and q
parameters in SERVICE_URL
according to the user's choices:
private void btnTranslate_Click(object sender, RoutedEventArgs e)
{
Language from = lbxFrom.SelectedItem as Language;
Language to = lbxTo.SelectedItem as Language;
string googleTranslateUrl = string.Format(SERVICE_URL,
from.Code, to.Code, txtInput.Text);
_proxy.DownloadStringAsync(new Uri(googleTranslateUrl));
}
Handling DownloadStringCompleted
is pretty straightforward. It only extracts the desired text from the JSON response and assigns it to the output text box. e.Result
contains the whole JSON response. Note: For simplicity, I have used a short regular expression in order to parse JSON. Windows Phone supports DataContractJsonSerializer, which is the appropriate way for object serialization and deserialization.
void DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
string text = Regex.Match(e.Result,
"\"translatedText\":\"(.*?)\"").Groups[1].Value;
txtOutput.Text = text;
}
We are done! Windows Phone translates text using Google API! Once again, here is the application (download source code):
Resources
Compare this post with Bing Translator service for Windows Phone 7.