Monday, July 26, 2010

 

Localize your Android apps via Google Translate, the easy way!

Smartphones are increasingly used all over the globe, and I expect English to be a minority language among their users pretty soon. Fortunately, both Android and the iPhone are designed from the ground up for multilanguage localization. It's basically a two-step process for both:

  1. Move all the strings you show your user from code into a strings file. You do this by using activity.getString() in Android, and the NSLocalizedString macro followed by a bit of command-line voodoo in Objective-C.
  2. Translate the strings file into another language.


There are various translation services you can pay for step 2. And if you're serious about it being a good translation, you probably want to do that. But for a first iteration, or a quick-and-dirty app, why not just use Google Translate?

"Because that would be really tedious" is one answer. Aha, but there is a JavaScript API for Google Translate! And hence I give you this one-page, two-click solution for translating an Android strings file into another language:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link type="text/css" rel="stylesheet" href="/static/main.css" />
<title>App Localizer</title>
</head>

<script type="text/javascript" src="http://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load("language", "1");
</script>

<body>
<div id="wrapper">
<table width=800><tr>
<td align=left><h3><a href="/">iTravelFree.net</a></h3></td>
<td align=right><img src="http://code.google.com/appengine/images/appengine-silver-120x30.gif"
alt="Powered by Google App Engine" height=30 width=120/></td>
</tr><tr><td colspan=2><HR></td>
</tr></table>

<div id="content">
<table width=800><tr><td>

<H3>Localizer</H3>
<form name="localize" onsubmit="return doGo();">
Translate the
<select name="xmlType">
<option>Android</option>
<option>iPhone</option>
</select>
string file on the top from
<select name="languageFrom">
<option value="en" selected="true">English</option>
<option value="fr">French</option>
<option value="de">German</option>
</select>
to
<select name="languageTo">
<option value="ar">Arabic</option>
<option value="zh">Chinese</option>
<option value="nl">Dutch</option>
<option value="en">English</option>
<option value="fi">Finnish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="he">Hebrew</option>
<option value="hi">Hindi</option>
<option value="it">Italian</option>
<option value="ja">Japanese</option>
<option value="ko">Korean</option>
<option value="pt">Portuguese</option>
<option value="ru">Russian</option>
<option value="es">Spanish</option>
<option value="sv">Swedish</option>
</select>
<input type="submit" name="go" value="Translate">
<textarea name="inbox" cols=85 rows=11></textarea>
<textarea name="outbox" cols=85 rows=11></textarea>
</form>

</td></tr></table>
</div>
<div id="footer">
<table width=800><tr><td colspan=2><HR/></td></tr><tr><td align=right>
<a href="/">Home</a> | <a href="/">App</a> | <a href="/map">Map</a>
</td></tr></table>
</div>
</div>

<script type="text/javascript">
var output;

function doGo() {
document.localize.outbox.value="Parsing, please wait...";

if (document.localize.xmlType.value == "Android") {
output = '<?xml version="1.0" encoding="utf-8"?>\n<resources>';
}
else {
output = 'TODO: iPhone';
}

// parse and translate the relevant values out of the XML
if (window.DOMParser) //
{
parser=new DOMParser();
xmlDoc=parser.parseFromString(document.localize.inbox.value,"text/xml");
}
else // Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(document.localize.inbox.value);
}

if (document.localize.xmlType.value == "Android") {
stringElements = xmlDoc.getElementsByTagName("string");
handleNextVal(stringElements, 0);
}
else {
//TODO: iPhone
}
return false;
}

function handleNextVal(elements, index) {
if (index>=elements.length)
return doFinish();

if (index>0)
output+= '</string>'

element = stringElements[index];
name = element.attributes.getNamedItem("name").nodeValue;
initialVal = element.childNodes[0].nodeValue;
output+= '\n\t<string name="'+name+'">'
google.language.translate(initialVal,
document.localize.languageFrom.value,
document.localize.languageTo.value,
function(result) {
if (result.error)
output+=initialVal;
else
output+=result.translation.replace("'","'");
handleNextVal(elements, index+1);
});
}

function doFinish() {
if (document.localize.xmlType.value == "Android") {
output+= '</string>\n</resources>';
}
else {
//TODO: iPhone
}
document.localize.outbox.value=output;
return false;
}
</script>
</body>
</html>


There now. Was that so hard? Just paste your initial strings file into the top text box, select your From and To language, hit "Translate", sit back for 30 seconds, let Google Translate work its magic, et voila: your translated strings file appears down below.

Still too lazy to get it up and running yourself? Fine, here's a fully functional version running on my iTravelFree app's App Engine service:
http://itravelapp.appspot.com/static/localizer.html

Right now it only handles Android strings-file syntax, but I'll be adding iPhone soon enough. (And really, if you know anything about JavaScript and XML, it won't be hard for you to customize it yourself.)

Hope y'all find it useful -

Jon

Labels: , , , , , , , , ,


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]