Android Question Kiosk initialize behavior

jareal

Member
Licensed User
Longtime User
Hi,

Want to share an experience that may help others save time.

I have a regular app and decided to Kiosk it following instructions from
https://www.b4x.com/android/forum/threads/device-owner-tasklock-kiosk-apps-2017.81765/#post-518018 and the app run flawless.

Made the app a Home Launcher Activity and restarted the device. Then I had some unexpected behaviors:

  • Main module 'Sub Activity_Create' try to use a ClientKVS global variable declared at 'starter service' and initialized at 'Sub Service Create' but... it was not initialized!

Moved the ClientKVS initialization to the Main activity and problem solved.

  • I get the IMEI from GetDeviceId (PhoneId library) to setup a global string variable in starter module 'Sub Service Create'.
It returned empty string !

Moved the code to Main activity and got the same value: "". Seems the library was not operational yet.

So tried this at Main activity:
B4X:
Dim pId As PhoneId
...
Do While pId.GetDeviceId.Length = 0
    Log("GetDeviceId não retornou IMEI")
  Loop

And after many lines of log the IMEI showed up!

Moved the code above to starter service and also worked.

That's it. Explanations and/or suggestions are welcome!
 

jareal

Member
Licensed User
Longtime User
Sure!
Log when the app is downloaded and executed:

*** Service (starter) Create ***
Starter: Inicializando ckvs
Starter: sImei=999999
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
Main: sImei=999999
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
** Activity (main) Pause, UserClosed = false **

Log when the device is restarted:
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
Starter: Inicializando ckvs
Starter: GetDeviceId não retornou IMEI
Starter: sImei=
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
Main: GetDeviceId não retornou IMEI
Main: GetDeviceId não retornou IMEI
... about 1800 lines ...
Main: GetDeviceId não retornou IMEI
Main: GetDeviceId não retornou IMEI
Main: sImei=999999
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
*** Service (soverlay) Create ***
** Service (soverlay) Start **
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is started properly, meaning that the starter service is created and started.

I would use this code to wait for the sim card to be ready:
B4X:
Dim StartTime As Long = DateTime.Now
Do While pId.GetDeviceId.Length = 0
    Log("GetDeviceId não retornou IMEI")
    If DateTime.Now - StartTime > 30000 Then Exit 'don't loop forevet
    Sleep(100)
Loop
 
Upvote 0

jareal

Member
Licensed User
Longtime User
Hi,

another bit of 'erratic' behaviour when we have an app in Kiosk Mode (Home app, Owner of the device) and power it up:

I have used the code from the previous post in 'Create_Service' from Starter service without problems on many devices but then on a new device happened that Activity_Create from Main was started and tried to use the globals long before they were initialized in Starter service.

Perhaps something related to new device runs Android 6 and the other devices run Android 5. Not sure if this is relevant.

So I copied the initialization code to Main and got this log:

Logger connected to: XXXXXXXXXX
--------- beginning of main
Main: sImei=999999
Cel_48
--------- beginning of system
RefreshUser PrevV_01
DropTable: DROP TABLE IF EXISTS [Clientes]
CreateTable: CREATE TABLE IF NOT EXISTS ...
DropTable: DROP TABLE IF EXISTS [Municipios]
CreateTable: CREATE TABLE IF NOT EXISTS ...
DropTable: DROP TABLE IF EXISTS [Produtos]
CreateTable: CREATE TABLE IF NOT EXISTS ...
DropTable: DROP TABLE IF EXISTS [PreviVend]
DropTable: DROP TABLE IF EXISTS [Hprod]
Starter: sImei=999999
*** Service (soverlay) Create ***
** Service (soverlay) Start **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
*** Service (reboot) Create ***
** Service (reboot) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **

Note that the initialization of some globals in Starter service (line 'Starter: sImei=999999') is reached after a lot of processing in Main.

It seems to me that in Kiosk mode (Home app, owner of the device) the initialization MUST be done in Main, not in Starter service.
 
Upvote 0

jareal

Member
Licensed User
Longtime User
When the device powers up and my app is the Home app the moment that we press the 'Connect' button is very sensitive. If too early we get a 'No device found', if a bit late some of the early logs don't show up.

I stripped down the app to better show what happens and created a sub to write my log to a file, so no need to play with the 'Connect' button:

Main:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    '
    X.Wlog("Main: Activity_Create")
    '
    If Not(Starter.ckvs.IsInitialized) Then
        x.Wlog("Main: ckvs não estava inicializado")
        '
        Starter.ckvs.Initialize(Me, "ckvs", "http://192.168.2.51:51041")
        '
        Starter.kvsVendas.Initialize(File.DirDefaultExternal, "kvsVendas")
        Starter.kvsTrocas.Initialize(File.DirDefaultExternal, "kvsTrocas")
        Starter.kvsClientes.Initialize(File.DirDefaultExternal, "kvsClientes")
        '
        Starter.mapProdCor.Initialize
    End If
    '
    Activity.LoadLayout("layMain")
    '
    If Starter.sImei.Length = 0 Then
        Dim pId As PhoneId
 
        x.wLog("Main: sImei vazio")
        Dim StartTime As Long = DateTime.Now
        Do While pId.GetDeviceId.Length = 0
            If DateTime.Now - StartTime > 30000 Then Exit 'don't loop forever
            Sleep(100)
        Loop
        If pId.GetDeviceId.Length = 0 Then
            X.Wlog("Main: Não conseguiu DeviceId")
        Else
            Starter.sImei = pId.GetDeviceId.SubString(9)
            x.wLog("Main: Inicializou sImei=" & Starter.sImei)
        End If
    Else
        X.Wlog("Main: sImei was OK")
    End If
    '
    Try
        GetManager.RunMethod("setLockTaskPackages", Array(GetAdminComponent, Array As String(Application.PackageName)))
        GetContext.RunMethod("startLockTask", Null)
        Starter.bAppLocked = True
        Starter.bKiosk = True
        x.wLog("Locked")
    Catch
        X.msgError("Falhou no LOCK", "Vai ficar em Kiosk simples" & CRLF & LastException)
        Starter.bKiosk = True        ' vai ficar em modo Kiosk pelo menos
        '
        x.wLog(LastException)
    End Try
    '
End Sub

Sub btSaida_Click
 
    Dim i As Intent
    i.Initialize("android.settings.SETTINGS", "")
    StartActivity(i)
 
End Sub

Sub lblLock_Click

    If Starter.bAppLocked = False Then        ' mandou dar Lock
        Try
            GetManager.RunMethod("setLockTaskPackages", Array(GetAdminComponent, Array As String(Application.PackageName)))
            GetContext.RunMethod("startLockTask", Null)
            Starter.bAppLocked = True
            lblLock.Text = "Locked"
            x.wLog("Locked")
        Catch
            x.wLog("Main: lblLock Error: " & LastException)
        End Try
        '
        Activity_Create(False)
    Else                        ' mandou dar UNlock
        GetContext.RunMethod("stopLockTask", Null)
        Starter.bAppLocked = False
        lblLock.Text = "UNLocked"
        x.wLog("UNlocked")
    End If

End Sub

Sub GetAdminComponent As Object
    Dim jo As JavaObject = Starter.admin
    Return jo.GetFieldJO("rec")
End Sub

Sub GetManager As JavaObject
    Dim jo As JavaObject = Starter.admin
    Return jo.GetFieldJO("dm")
End Sub

Sub GetContext As JavaObject
    Dim jo As JavaObject
    jo.InitializeContext
    Return jo
End Sub

Starter Service:
B4X:
Sub Service_Create
    Dim pId As PhoneId
    '
    X.Wlog("Starter: Service_Create")
    '
    ' Pq em modo KIOSK parece que inicializa antes em Main do que aqui
    If Not(ckvs.IsInitialized) Then
        x.Wlog("Starter: Inicializando ckvs")
        '
        ckvs.Initialize(Me, "ckvs", "http://192.168.2.51:51041")
        '
        kvsVendas.Initialize(File.DirDefaultExternal, "kvsVendas")
        kvsTrocas.Initialize(File.DirDefaultExternal, "kvsTrocas")
        kvsClientes.Initialize(File.DirDefaultExternal, "kvsClientes")
        '
        mapProdCor.Initialize
    End If
    '
    bCkvsUpdated = False
    '
    If sImei.Length = 0 Then
        Dim pId As PhoneId
 
        x.wLog("Starter: sImei vazio")
        Dim StartTime As Long = DateTime.Now
        Do While pId.GetDeviceId.Length = 0
            If DateTime.Now - StartTime > 30000 Then Exit 'don't loop forever
            Sleep(100)
        Loop
        If pId.GetDeviceId.Length = 0 Then
            X.Wlog("Starter: Não conseguiu DeviceId")
        Else
            sImei = pId.GetDeviceId.SubString(9)
            x.wLog("Starter: Inicializou sImei=" & sImei)
        End If
    Else
        X.Wlog("Starter: sImei was OK")
    End If
    '
    NativeMe.InitializeContext

End Sub

Sub Service_Start (StartingIntent As Intent)

X.Wlog("Starter: Service_Start")

End Sub

And here the wLog sub:
B4X:
Sub Wlog (pMsg As String)
    Dim twlog As TextWriter
 
    Log("Wlog: " & pMsg)
    twlog.Initialize(File.OpenOutput(File.DirDefaultExternal, "Log_app.txt", True)    )
    twlog.WriteLine(DateTime.Time(DateTime.Now) & " - " & pMsg)
    twlog.Close

End Sub

Finally here is the Log_app.txt file with two consecutives restarts of the device:

20:21:25 - Starter: Service_Create
20:21:25 - Starter: Inicializando ckvs
20:21:25 - Starter: sImei vazio
20:21:25 - Starter: Service_Start
20:21:25 - Main: Activity_Create
20:21:26 - Main: sImei vazio
20:21:27 - Main: Inicializou sImei=598218
20:21:27 - Locked
20:21:27 - Starter: Inicializou sImei=598218
--------------------------------------------
20:23:21 - Starter: Service_Create
20:23:21 - Starter: Inicializando ckvs
20:23:22 - Starter: sImei vazio
20:23:22 - Starter: Service_Start
20:23:22 - Main: Activity_Create
20:23:22 - Main: sImei vazio
20:23:24 - Starter: Inicializou sImei=598218
20:23:24 - Main: Inicializou sImei=598218
20:23:24 - Locked
(I inserted the line with dashes to better visualize)

As we see in this log each restart has a different behaviour.
This also happened with the cloudKVS initialization, I see once it was done in Main.
 
Last edited:
Upvote 0

jareal

Member
Licensed User
Longtime User
It is a mistake to initialize objects of other modules.
Agree

Is it correct to assume that the Sleep(10000) is to be inserted at the beginning of Main (Activity_Create) ?
To give time to Starter do its job?
 
Upvote 0
Top