http://us.blackberry.com/devjournals/resources/journals/sep_2006/localization.jsp
Localization is the process by which an application's user interface is
adapted to meet the default language that is currently set on a
BlackBerry® device. The concept of localization is becoming more
important in the world of BlackBerry, as usage expands across the world.
Topics within this article include:
There are several benefits to implementing localization within an
application:
Localization can be added by using the ResourceBundle and
ResourceBundleFamily classes, which are members of the net.rim.device.api.il8n
package.
In general, the resources for a particular locale are stored within a
ResourceBundle. A ResourceBundleFamily will contain a collection of
ResourceBundle objects, which groups the resources for an application.
A locale represents a specific geographical, political, or cultural region
such as France, Spain or London.
The ResourceBundle and ResourceBundleFamily classes are outlined in the next
two sections.
Definition:
The net.rim.device.api.il8n.ResourceBundle class defines the base
functionality for locale-specific resource bundles.
protected ResourceBundle(Locale locale)
Constructs a new ResourceBundle instance. The parameter "Locale" is the
locale for this resource bundle.
Returns | Method | Parameter |
---|---|---|
ResourceBundleFamily | getBundle | String name |
Description:
Parameter:
Returns:
Returns | Method | Parameter |
---|---|---|
ResourceBundleFamily | getBundle | long bundle String name |
Description:
Parameters:
Returns:
Throws:
Returns | Method | Parameter |
---|---|---|
ResourceBundleFamily | getBundle | long bundle String name CodeSigningKey key |
Description:
Parameters
Returns:
Throws:
Returns | Method | Parameter |
---|---|---|
ResourceBundleFamily | getFamily | void |
Description:
Parameter:
Returns:
Returns | Method | Parameter |
---|---|---|
Locale | getLocale | void |
Description:
Parameter:
Returns:
Returns | Method | Parameter |
---|---|---|
Object | getObject | int key |
Description:
Parameter:
Returns:
Throws:
Returns | Method | Parameter |
---|---|---|
Object | getObject | int key boolean searchParent |
Description:
Parameters:
Returns:
Returns | Method | Parameter |
---|---|---|
String | getString | int key |
Description:
Parameter:
Returns:
Throws:
Returns | Method | Parameter |
---|---|---|
String[] | getStringArray | int key |
Description:
Parameter:
Returns:
Throws:
Returns | Method | Parameter |
---|---|---|
Object | handleGetObject | int key |
Description:
Parameter:
Returns:
Throws:
Definition:
The net.rim.device.api.il8n.ResourceBundleFamily class is a ResourceBundle
that contains a collection of ResourceBundles. The ResourceBundleFamily extends
ResourceBundle.
Returns | Method | Parameter |
---|---|---|
ResourceBundle | getBundle | Locale locale |
Description:
Parameter:
Returns:
Returns | Method | Parameter |
---|---|---|
long | getId | void |
Description:
Parameter:
Overrides:
Returns:
Returns | Method | Parameter |
---|---|---|
String | getName | void |
Description:
Parameter:
Returns:
Returns | Method | Parameter |
---|---|---|
Object | handleGetObject | int key |
Description:
Parameter:
Overrides:
Returns:
Throws:
Returns | Method | Parameter |
---|---|---|
boolean | isEmpty | void |
Description:
Parameter:
Returns:
Returns | Method | Parameter |
---|---|---|
void | put | Locale locale ResourceBundle bundle |
Description:
Parameter:
Throws:
Returns | Method | Parameter |
---|---|---|
boolean | verify | CodeSigningKey key |
Description:
Parameter:
Returns:
Resource files must be added into the application's project space before
implementing ResourceBundle or ResourceBundleFamily. Four file types are
required to add localization to your application:
This file defines descriptive keys for each localized string. The resource
header file should be the same name as the project with an extension of .rrh
Example: AppName.rrh
When the BlackBerry Java™ Development Environment (BlackBerry JDE) builds a
project, it creates a resource interface with the same name as the .rrh file and
appends "Resource".
Example: AppNameResource.java
The resource interface file contains references to the constants added under
the resource header file.
This file maps resource keys to string values for the root (or global)
locale. It has the same name as the resource header file, except that it ends
with an extension .rrc
Example: AppName.rrc
This resource content file maps resource keys to string values for specific
locales (language and country). These files are given the same name as the
resource header file, followed by an underscore (_) and the language code, and
then optionally followed by another underscore (_) and country code.
Example:
AppName_en.rrc
AppName_en_GB.rrc
AppName_fr.rrc
There is no restriction on how many resource content files can be added.
Please keep in mind that if you want to add Great Britain locale support, you
must add the default language locale - English.
This file initializes the resource bundle mechanism. It is only required when
the resources are compiled in a project that is separate from the main
application project.
In general, there are four steps to be completed when adding localization
support:
We will start off by adding the root (or global) locale into an application
named LocalizationExApp.java and then will move into adding additional locales.
The LocalizationExApp.java is a simple application that outputs a screen
containing a title and an ObjectChoiceField.
The code for this application is shown below:
package LocalizationExample; import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.*; public class LocalizationExApp extends UiApplication { InitialScreen _screen = new InitialScreen(); public static void main(String[] args) { LocalizationExApp theApp = new LocalizationExApp(); theApp.enterEventDispatcher(); } public LocalizationExApp() { pushScreen(_screen); } } final class InitialScreen extends MainScreen { LabelField _title; ObjectChoiceField _choiceField; String[] _options = { "January","February","March","April","May","June", "July","August","September","October","November","December" }; public InitialScreen() { super(); _title = new LabelField("Localization Sample"); setTitle(_title); _choiceField = new ObjectChoiceField("Month", _options); add(_choiceField); } }
The workspace for the application appears as:
For this sample, the screen title and ObjectChoiceField (label and String
array) will be changed to use resource files instead of hard-coded values within
the source code.
[ApplicationName].rrh
For this sample, the resource header filename is
"LocalizationExApp.rrh", which corresponds to the name of the Java source file
with the extension .rrh.
The package name is automatically generated within the "Add package
information:" field. It is identical to the package statement included within
the java source file. For this sample, the package name is
"LocalizationExample".
Confirm that the package statement appears correctly, and then close the file
(using the X in the top, right hand corner of the window)
The resource header file appears beneath the project once added.
Enter the name of the root resource content file in the "File name:" field.
This name should correspond to the application name with the extension .rrc
(i.e. [ApplicationName].rrc).
The root locale name would be LocalizationExApp.rrc
To do this, right-click on the name of your project, and select "Add File to
[Project Name]"
Browse to the location of the resource content file and select "*.rrc" from
the "Files of Type:" drop-down list. Highlight the resource content file and
select "Open."
The resource content file is added beneath the project within the BlackBerry
JDE. The workspace appears as shown below:
In the "Files" panel, double-click on the resource header file
(LocalizationExApp.rrh). The Resource Editor window appears and looks similar to
the following window:
The Resource Editor is used to enter the resource keys and values (strings or
string arrays) for each different locale. Since only the root locale (or
resource content file) has been added, the Resource Editor only displays a tab
for "Root" (as seen in the above screen capture). If more than one locale is
added, a tab will be displayed for each one.
Each row under the headers "Keys" and "Values" defines a single resource. A
blank row is also generated at the base of the list after adding a new resource.
The "Keys" column defines the descriptive name for the resource which will be
used in the source code to retrieve the associated (localized) value. The
"Values" column displays the text or content of that particular resource.
In this sample, three resource keys/values will be added.
(Single Value - String)
(Single Value - String)
(Multiple Values - String Array)
In the first row, enter APPLICATION_TITLE in the "Keys" field. In the
corresponding "Values" field, enter the title of the application - "Localization
Sample".
In the second row, enter "MONTH_TITLE" in the "Keys" field. In the
corresponding "Values" field, enter the title for the ObjectChoiceField -
"Months".
In the third row, enter "MONTH_VALUES" in the "Keys" field. The value for
this resource will be different than the first two that were added because this
will become an array of values as opposed to a single string value.
When a new key/value is added, it is considered to be a single value (only
one value) by default. However, a single value resource can be converted into a
multiple value by right clicking on the resource key and select "Convert to
Multiple Values".
Click "Yes" when prompted to change the resource from a single to multiple
value. Then right-click the keys value (MONTH_VALUES) and select "Properties" to
display the "Edit Resource Line" window. This is where you can add/edit/remove
values from this multiple-value resource.
For this resource, the names of the 12 months will be added. In the field
beside the three buttons - "Add", "Edit" and "Remove" - enter "January" and then
click on the "Add" button. This should display "January" in the "Values" box.
After all months have been added, the "Edit Resource Line" window appears
similar to below:
Click "OK" after all values have been entered.
The "Resource Editor" window appears as below:
After all resource keys and values have been entered into the resource editor
file, the only remaining step is to edit the existing Java source file to
include support for localization.
import net.rim.device.api.il8n.*;
A resource bundle object will have to be created as it will contain a
reference to all constants that have been added into the resource header/content
file(s).
In general, the declaration of a ResourceBundle object would appear as shown
below:
ResourceBundle resources = ResourceBundle.getBundle ([Resource Interface].BUNDLE_ID, [Resource Interface].BUNDLE_NAME);
The ResourceBundle object is defined as:
ResourceBundle _resources = ResourceBundle.getBundle (LocalizationExAppResource.BUNDLE_ID, LocalizationExAppResource.BUNDLE_NAME);
The resource interface will have the same name as the resource header file
(.rrh) with "Resource" appended to the end.
The getBundle() method will retrieve the appropriate resource bundle family.
The BUNDLE_ID and BUNDLE_NAME are automatically created within the resource
interface when the BlackBerry JDE compiles the application.
The original LabelField definition is replaced with obtaining the value from
a resource by invoking the getString() method and referencing the
APPLICATION_TITLE key value.
//LabelField title = new LabelField("Localization Sample"); LabelField title = new LabelField(_resources.getString (LocalizationExAppResource.APPLICATION_TITLE));
We have two parts for the ObjectChoiceField (Title and Values) that will be
replaced with resources:
_choiceField = new ObjectChoiceField(_resources.getString (LocalizationExAppResource.MONTH_TITLE), _resources.getStringArray (LocalizationExAppResource.MONTH_VALUES));
The multiple value key resource is retrieved by using the getStringArray()
method.
The updated LocalizationExApp.java file appears as shown
below:
package LocalizationExample; import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.*; import net.rim.device.api.i18n.*; public class LocalizationExApp extends UiApplication { InitialScreen _screen = new InitialScreen(); public static void main(String[] args) { LocalizationExApp theApp = new LocalizationExApp(); theApp.enterEventDispatcher(); } public LocalizationExApp() { pushScreen(_screen); } } final class InitialScreen extends MainScreen { LabelField _title; ObjectChoiceField _choiceField; ResourceBundle _resources = ResourceBundle.getBundle (LocalizationExAppResource.BUNDLE_ID, LocalizationExAppResource.BUNDLE_NAME); public InitialScreen() { super(); //LabelField title = new LabelField("Localization Sample"); _title = new LabelField(_resources.getString (LocalizationExAppResource.APPLICATION_TITLE)); setTitle(_title); // Creates a new object choice field, retrieving the field // title (MONTH_TITLE) and a list of months (APP_MONTHS) // from the resource file _choiceField = new ObjectChoiceField (_resources.getString (LocalizationExAppResource.MONTH_TITLE), _resources.getStringArray (LocalizationExAppResource.MONTH_VALUES)); add(_choiceField); } }
Now that the root locale has been added into the project/application, it is
simply a matter of adding additional resources for different locales.
Working from the sample above, additional locales - Great Britain, French and
Spanish - will be created and added into the same project.
Two extra items will have to be known prior to adding additional locales:
Both the language and country codes follow ISO standards. The language code
follows the IS0-639 standard and the country code follows the ISO-3166 standard.
Including the country code is optional where the language code is mandatory.
The language code, with optional country code, for additional locales will be
added into the sample.
Locale | Language Code | Country Code |
---|---|---|
English, Great Britain | en | GB |
French | fr | --- |
Spanish | es | --- |
Each locale is represented by an associated resource content file. Each file
will be named similar to the root locale, which includes the language and
country code if necessary.
The resource content file names for the three new locales would be as
follows:
LocalizationExApp_en_GB.rrc
LocalizationExApp_fr.rrc
LocalizationExApp_es.rrc
Since we are adding a country code to one of the locales, the project also
requires a resource content file to be added for the basic language of that
specific locale. This means is that since we are adding a locale for English,
Great Britain, we must also add a resource for English.
Four additional resources will be created and added into this sample project:
Local | English |
---|---|
Language Code | en |
Country Code | --- |
Resource Content Filename | LocalizationExApp_en.rrc |
Local | English, Great Britain |
---|---|
Language Code | en |
Country Code | GB |
Resource Content Filename | LocalizationExApp_en_GB.rrc |
Local | French |
---|---|
Language Code | fr |
Country Code | --- |
Resource Content Filename | LocalizationExApp_fr.rrc |
Local | Spanish |
---|---|
Language Code | es |
Country Code | --- |
Resource Content Filename | LocalizationExApp_es.rrc |
The general naming syntax for these additional locales would generally be as
follows:
[ApplicationName]_[LanguageCode]_[Country Code Optional].rrc
[ApplicationName]
[LanguageCode]
[CountryCode]
Country Code of the locale (Optional parameter)
Now that file naming conventions for the additional locales are understood,
we can move into creating and adding additional locales into the project.
The following steps must be followed to add resource content files. These
steps must be repeated for each resource that is created and added. In this
case, these steps will be repeated four times (English, English GB, French and
Spanish) using the files names defined above.
To create these additional locales, follow the same steps that were described
when creating the root locale above (Step # 2 - Add Resource Content File),
using the file naming convention described earlier.
After adding the locales, the workspace tree structure will appears as shown
below:
Double-click on the resource header file. The resource header file will
create additional tabs for each locale that has been added. This acts as a
centralized location to add resource keys/values. The sample file,
LocalizationExApp.rrh, appears as shown below:
For each locale added, the resource keys that were added into the root locale
will automatically be generated in the additional locales with blank values.
Please note that a root locale is required for any application that will use
localization. The root locale acts as a global locale and will be used by
default if the other locales are not supported on the BlackBerry device.
To add the content or values into each key value for each locale, follow the
steps outlined in Step # 3 - Add resource keys and values into the resources.
In addition to having the resources read by the application, you can also
localize the application name that appears under the icon on the main ribbon of
the BlackBerry device. To do this, right-click on the project name, select
"Properties", and then select the "Resources" tab.
Select the "Title Resource Available" check box. In the "Resource Bundle:"
and "Title Id" drop-down lists, select the correct resource file and key for the
application title.
No extra code is required within your application to support the additional
locales. Once the application has been installed onto a BlackBerry device, the
appropriate locale will be selected by default, based on the language that the
device is set to. To find out the current language on the BlackBerry device,
view Options - Languages.
If multiple locales are being implemented or maintained for an application,
it can be more efficient to add resource files into their own project based on
the locale. This can be done as follows:
The following steps use the sample developed in the previous steps, but all
resource files were removed from the project before worked was started.
Add a new project into the existing workspace for each resource bundle or
locale, including one for the root locale. The project names should match the
names of the resource content files, except that a double underscore should be
inserted prior to including the language code.
The general naming format is as follows:
[AppName]__[Language Code].jdp
... or if including a country code:
[AppName]__[Language Code]_[Country Code].jdp
For example, the resource content file for the English locale is named
"LocalizationExApp_en.rrc". The project will be named
"LocalizationExApp__en.jdp".
Once all resource projects have been added, the workspace should appear as
shown below:
Confirm each "Output File Name" associated with each project added in Step #
1.
Right-click on the project name and select "Properties". On the project
properties window, click on the "Build" tab. The first field listed is the
Output File Name and should be the same name as the project without the file
extension.
Example:
The Output File Name for the LocalizationExApp__en_GB project will appear as
follows:
The BlackBerry JDE provides a built-in initialization mechanism. As such, you
will be required to create a initialization class with an empty main() for each
resource project that is created.
The code that appears within this initialization class is:
package LocalizationExample; import net.rim.device.api.i18n.*; public class init { public static void main (String[] args) { } }
The last step is adding the appropriate resource files and initialization
files into the project, then making sure that the project is properly set up for
deployment.
Right-click on each resource project name and select "Properties"
On the resource project name property window, select the "Application" tab
Change the "Project Type:" to be a "Library"
Click "OK"
Now the application has been localized using a more efficient method. When
finished, the workspace is divided into six projects, as shown below:
Since each project that was created above will compile into its own cod file,
you can edit the jad file for the application project to include references to
all cod files. This will make the installation or wireless download process much
simpler.
Application deployment can occur wirelessly or by using the BlackBerry
Desktop Manager.
For further information on deployment, please refer to the Enterprise and WAP Deployment guides found under
BlackBerry Java Development Environment.