Android Tutorial How I manage multi language in my Android App

Hi everyone !

I would like to share my own way to manage multi languages for my Android App.
I'm sure there are more than one method to do it, I just want to share mine.

This functionnality is base on a SQL server database where all translations are stored (and used for Windows App clients side).
I use a WebService to retrieve the full list of them in Android App.

The most important thing in my solution is to use "live" translations.
I mean as translations are available and shared in an SQL server database, you are sure to be up to date with.

By the way, if you don't want to use an SQL Server database, you can, for sure, adapt it !

The way it works:

- it is based on a property of Login: Language.
Each person who create a login have to set a language. If not, English will be set as default one.

- After the user logged in (with an appropriate screen) the full list of translations is loaded from the Web service to an SQLlite database on Android device.

- each time I initialize a textbox (or watever with text) in my code, I call a function with the appropriate text ID and language name and retrieve the good translation.

Hereafter code used to do that:

On the first screen after the user log in:

B4X:
Sub Activity_Create(FirstTime As Boolean)

    Activity.LoadLayout("selection")
    listOfArrayTrad.Initialize
    
    'call the webservice
    AppelWSTrad
        
End Sub

Where listOfArrayTrad is a list of "StructTrad" as define below:

B4X:
Type StructTrad(Id As Int,Francais As String,Anglais As String,Espagnol As String,Polonais As String)

And AppelWSTrad is:

B4X:
Sub AppelWSTrad()
    

    Dim job1 As HttpJob
    job1.Initialize("Trad", "Selection")
    job1.Download("URL to the right webservice")
    job1.GetRequest.Timeout = 60000
    
        
End Sub

When the job is done and succesfull (I removed all stuff about if it's not successful), I parse the result like this :

B4X:
Sub JobDone(job1 As HttpJob)
    If job1.Success = True Then

            Dim JSON As JSONParser
            JSON.Initialize(Job1.GetString)
            Dim Root As List = JSON.NextArray
            For Each Map1 As Map In Root
                Dim myrecordTrad As StructTrad
                myrecordTrad.Id = Map1.Get("id")
                myrecordTrad.Francais = Map1.Get("francais")
                myrecordTrad.ANglais = Map1.Get("anglais")
                myrecordTrad.Espagnol = Map1.Get("espagnol")
                myrecordTrad.Polonais = Map1.Get("polonais")
                listOfArrayTrad.Add(myrecordTrad)
            Next
            
            Trad.LoadTrad(listOfArrayTrad) 'explain below
            
    End If
end sub

The next part is to store those informations in an SQLlite table:

I've added a code module "Trad" in my project with:

B4X:
Sub LoadTrad (Lst As List)
    
    Main.Sql.Initialize(File.DirInternal, "Trad.db", True)
'table is dropped each time to be sure to have the last good translations and also all new translations
'(I know a "Drop" is a bit radical, but ....)
    Main.sql.ExecNonQuery("DROP TABLE IF EXISTS Trad")
    Main.sql.ExecNonQuery("CREATE TABLE Trad(Id INTEGER, Francais TEXT,Anglais TEXT,Espagnol TEXT,Polonais TEXT)")
  
    For i = 0 To Lst.Size -1
        
        Dim Une As StructTrad
        Une = Lst.Get(i)
        
        Dim Sql As String = "INSERT INTO Trad VALUES(" & Une.Id & ",'" & Une.Francais & "','" & Une.Anglais & "','" & Une.Espagnol & "','" & Une.Polonais & "')"
        
        Log(Sql)
        
        Main.sql.ExecNonQuery(Sql)
        
        
    Next
        
End Sub

In the same module, I've added a new Sub to retreive a translation according to Id & Language (function):

B4X:
Sub LaTrad(Id As Int, Langue As String) As String
    
    If Langue = "" Then Langue = "Anglais"
    
    Private CursorTrad As Cursor
    
    Log("Id= " & Id)

    CursorTrad = Main.Sql.ExecQuery("select " & Langue & " from Trad where id = " & Id)
    CursorTrad.Position = 0
    
    
    Dim MaTrad As String
    
    If CursorTrad.RowCount > 0 Then
    
            MaTrad = CursorTrad.GetString(Langue)
    
            If MaTrad = "" Then
                CursorTrad = Main.Sql.ExecQuery("select Anglais from Trad where id = " & Id)
                CursorTrad.Position = 0
                MaTrad = CursorTrad.GetString("Anglais")
                
            End If
        
    Else
        'In case no translation whith the ID
        Select Case Langue
            
            Case "Francais"
                MaTrad = "Traduction manquante. Veuillez en informer votre administrateur"
                
                Case "Anglais"
                    MaTrad = "Missing translation. Please inform your administrator"
                    
                    Case "Espagnol"
                        MaTrad = "Falta la traducción. Por favor, informe a su administrador"
                        
                        Case "Polonais"
                            MaTrad = "Brak tłumaczenia. Proszę powiadomić administratora"
                            
        End Select
        
            
    End If
    
    Return MaTrad
    
End Sub

And finally, each time I need a translation I have to do:

B4X:
TextBox.text = Trad.LaTrad(Id,Language)


Of course, you know the Id because you have first to store all translations in all languages and then get the Id in the SQL server database (for me it's an identity).

Hope this way may help you ;)

Yannick.
 

Yayou49

Active Member
Licensed User

Yes it is a good example also, but as I said, in my case, translations are not fixed and can change from a day to another (update translations, add translations, ....)
Excel file is a quite static method and it is not shared.
The list of translations I used are shared between Windows applications and Android application.
BTW, as I said there are more than one solution !!!
Keep the good for you ;)
 

aeric

Expert
Licensed User
I do similar but I load the translation in Starter service module. Not sure it is a good idea but so far I have no issue with it.
 
Top