Translating Android Apps with KDE's Localization Infrastructure
For most of our cross-platform code our Gettext-based KF::I18n Framework takes care of translating user-readable texts on Android as well. It doesn’t cover Android-specific files and/or Android-native code though. Fortunately it’s not hard to integrate that with KDE’s translation infrastructure as well.
Marking strings for translation
For Android’s translation system all messages needing localization have to be put into the
res/values/strings.xml file and are assigned translation ids there.
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="application_name_full">KDE Itinerary</string>
<string name="application_name_short">Itinerary</string>
<string name="shortcut_label_current_ticket_short">Current Ticket</string>
...
</resources>Messages can then be referenced by their translation id, both in Java code and the various XML files including the Android manifest. The latter is probably the more commonly needed case for KDE’s apps, which have typically fairly little code written in Java directly.
In XML files those strings can then referenced using the @string/<translation_id>
notation:
<application
android:name="org.qtproject.qt5.android.bindings.QtApplication"
android:label="@string/application_name_full"
android:icon="@mipmap/ic_launcher">
<activity android:name="org.kde.itinerary.Activity"
android:label="@string/application_name_short">
...In Java code, those messages are accessible via the getString method in android.content.Context
and using the translation id constants R.string.<translation_id>.
Translation infrastructure integration
For KDE’s translation infrastructure to pick this up, a file named StaticMessages.sh
is needed in the project root directory. It’s used by the nightly translation run
to extract and merge translations that are stored in their own format rather than
the usual Gettext catalogs.
Using the following template only two paths need to be adjusted to the respective project:
#!/usr/bin/env bash
# the name of catalog we create (without the.pot extension)
FILENAME="your-catalog-name"
# relative path to the Android resource folder
ANDROID_RES_DIR="src/app/android/res"
function export_pot_file
{
mkdir outdir
ANSI_COLORS_DISABLED=1 a2po export --android $ANDROID_RES_DIR --gettext outdir
mv outdir/template.pot $1
rm -rf outdir
rm -f rc.cpp
}
function import_po_files
{
podir=$1
find "$podir" -type f -name "*@*.po" -delete
find "$podir" -name '*.po' -exec msgattrib --no-obsolete -o {} {} \;
ANSI_COLORS_DISABLED=1 a2po import --ignore-fuzzy --android $ANDROID_RES_DIR --gettext $podir
}See e.g. KDE Itinerary’s StaticMessages.sh for a full example.
After adding that file you should see translated strings.xml variants starting to appear
within a few days.