Android Tutorial [B4X] Localizator - Localize your B4X applications

Localizator is a cross platform solution for strings localization.

The strings are defined in an Excel workbook.

SS-2016-07-07_17.00.16.png


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

SS-2016-07-07_17.21.20.png


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 XLUtils).

B4A, B4i and B4J examples are also attached.

Localizator v1.01 is attached.

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

B4XPages example: https://www.b4x.com/android/forum/threads/localization-example-in-b4xpages-how.148649/post-942204
 

Attachments

  • B4J_LocalizatorExample.zip
    5.7 KB · Views: 1,505
  • ExcelWorkbook.zip
    7.1 KB · Views: 1,930
  • B4i_LocalizatorExample.zip
    6.1 KB · Views: 1,193
  • Localizator.bas
    4.4 KB · Views: 1,910
  • B4A_LocalizatorExample.zip
    11.6 KB · Views: 1,461
  • B4J_LocalizatorConverterSource.zip
    10 KB · Views: 690
Last edited:

Roberto P.

Well-Known Member
Licensed User
Longtime User
excellent!
thank you
 

JoanRPM

Active Member
Licensed User
Longtime 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.
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Very nice tool. Thanks Erel
 

OliverA

Expert
Licensed User
Longtime 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

  • IMG_2111.PNG
    IMG_2111.PNG
    182.1 KB · Views: 1,172
  • IMG_2112.PNG
    IMG_2112.PNG
    183.9 KB · Views: 1,096

Ed Brown

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

Eme Fibonacci

Well-Known Member
Licensed User
Longtime 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.
 

MaFu

Well-Known Member
Licensed User
Longtime 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
Longtime 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
 

Cableguy

Expert
Licensed User
Longtime User
Does it only work with .xlsx files? Open Officce cannot save with such an extension!
 

Cableguy

Expert
Licensed User
Longtime 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)
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Does it only work with .xlsx files? Open Officce cannot save with such an extension!
It will work with XLS files as well.

Even the example (B4A) fails at the exact same point, in the initialize sub..
It was a bug in the Localizator class. It is fixed in v1.01.
 

Cableguy

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

Erel

B4X founder
Staff member
Licensed User
Longtime 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
Longtime 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