Android Tutorial [B4X] Localizator - Localize your B4X applications

Erel

Administrator
Staff member
Licensed User
Localizator is a cross platform solution for strings localization.

The strings are defined in an Excel workbook.



They are then converted to a SQLite database file with a B4J program:



The database file should be added to the Files tab of your application.

Localizator is a class. You need to add it to your B4A, B4i or B4J program. It loads the set of strings based on the device locale or based on the forced locale (Localizator.ForceLocale).
Each string is identified by a key. The key matching is case insensitive. If there is no match then the key itself is returned (the value passed to Localize method).

There are some helper methods to automate the tasks. The main one is LocalizeLayout. It will go over all the views and will replace the matched keys.

Values can include parameters. For example "Hello {1}!". LocalizeParams deals with such values:
B4X:
lblHello.Text = loc.LocalizeParams("Hello {1}!", Array(edtName.Text))
{1} will be replaced with the first parameter from the array.

Notes

- In B4A it is recommended to declare and initialize the Localizator from the starter service.
- The three examples attached are a bit more complicated as they allow the user to change the language.
In its simplest form you just need to initialize the localizator and call loc.LocalizeLayout.
- Languages two letters codes: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

upload_2016-7-7_17-13-53.png
upload_2016-7-7_17-14-9.png
upload_2016-7-7_17-28-25.png


The compiled executable jar of the B4J converter can be downloaded from: www.b4x.com/b4j/files/B4XLocalizator.jar
The source code is attached (depends on jPOI library).

B4A, B4i and B4J examples are also attached.

Localizator v1.01 is attached.

Automating the localizator: https://www.b4x.com/android/forum/threads/b4x-localizator-localize-your-b4x-applications.68751/page-3#post-548169
 

Attachments

Last edited:

JoanRPM

Active Member
Licensed User
Until now, I uses the AHLocale library.
I see that the structure is similar and I can insert variables.
The advantage is that different languages are all in the same file.

Thanks you.
 

OliverA

Expert
Licensed User
B4J version 4.20
B4i version 2.51
iPhone 6S Plus w/iOS 9.3.2
iPad Pro (12.9) w/iOS 9.3.2

I've ran both the B4J and B4i version of the localization demo. In the B4i version, I'm experiencing a "one off" effect when typing in the name. The "Hello" string would be one behind the characters that I type in (or delete from the end). So if I type in "O", just "Hello !" is displayed. If I then type a "l" (lower case L), I get "Hello O!". If I backspace out all the letters, I'm left with "Hello O!" (in this case, since I started out with typing in an "O"). Clearing the field using the "x" works correctly (it clears the field and displays "Hello !"). Is this because I'm using 2.51 instead of 2.80 of B4i or is there another reason for this issue. I'm attaching a couple of screenshots which may clarify what I'm trying to explain. BTW, this is not an issue with the B4J version of the demo, only the B4i (can't speak for the B4a version, I've not tried it yet).
 

Attachments

Ed Brown

Active Member
Licensed User
This is Brilliant! This couldn't have arrived at a better time.
Thank you Erel!!!!
 

Eme Fibonacci

Well-Known Member
Licensed User
Great work. Thank you.
It would be nice to have comment lines in the worksheet. If the line starts with ' it would be ignored by B4XLocalizatorConverter.
 

Erel

Administrator
Staff member
Licensed User
You can easily add such a feature.
Add this line to the loop that goes over the rows:
B4X:
If row.GetCell(0).ValueString.StartsWith("'") Then Continue
 

MaFu

Well-Known Member
Licensed User
Until now, I uses the AHLocale library.
I see that the structure is similar and I can insert variables.
The advantage is that different languages are all in the same file.

Thanks you.
I'm using AHLocale too. And have all strings in one excel file with almost the same structure as Localizator. I created a python script to create the resource files from the excel sheet.
 

Cableguy

Expert
Licensed User
This may seem a stupid question but, would it be possible to expand this tool adding localized images?
For instance, having different drawable according to localization, embedded directly in the excel file
 

Erel

Administrator
Staff member
Licensed User
Put all the images in the Files tab and store the images names in the Excel workbook.
B4X:
Dim bmp As Bitmap = LoadBitmap(File.DirAssets, Starter.loc.Localize("ImageKey"))
This will load the correct image based on the current locale.
 

Cableguy

Expert
Licensed User
I'm trying to implement the Localizator but it fails on deployment...
Even the example (B4A) fails at the exact same point, in the initialize sub...

B4X:
LogCat connected to: 0123456789ABCDEF
--------- beginning of system
--------- beginning of main
** Service (starter) Create **
localizator_initialize (java line: 94)
java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]
    at b4a.example.localizator._initialize(localizator.java:94)
    at b4a.example.starter._service_create(starter.java:135)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
    at b4a.example.starter.onCreate(starter.java:54)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2982)
    at android.app.ActivityThread.access$1800(ActivityThread.java:178)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1553)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5631)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
 

Cableguy

Expert
Licensed User
I look a look inside the class...
Is there a reason why you do not check the strings.db for existence?
 

Erel

Administrator
Staff member
Licensed User
Is there a reason why you do not check the strings.db for existence?
Do you mean to ask why is it copied without first checking whether it already exists? It can only work if you also add a versioning solution.

Assuming that the database file is quite small then the copying step will be very fast.
 

Cableguy

Expert
Licensed User
Another silly question...

Can the xls file have empty rows? in long files it would help create separation between "topics"

[edit] tested with success!!!
 
Last edited:
Top