Android Tutorial Android "Kiosk mode" tutorial

Edit: A better kiosk implementation is available: https://www.b4x.com/android/forum/threads/device-owner-tasklock-kiosk-apps-2017.81765/#post-518018

Kiosk mode applications are applications that lock the device and do not allow the user to run any other application other than the kiosk application.

Android doesn't allow true kiosk mode without building a custom ROM.
However using the following methods you can build an application that will prevent "regular" users from playing with anything other than your application.

The application is made of two modules. The main activity and a service.
The service is configured to start at boot.
When the service is started it checks if the activity is running or not. If it is not running it uses a timer to start the main activity.

When the activity is paused it schedules the service to start in one second:
B4X:
Sub Activity_Pause (UserClosed As Boolean)
   If kiosk Then StartServiceAt(KioskService, DateTime.Now + 1 * DateTime.TicksPerSecond, False)  
End Sub
If the user presses on the home screen, the home screen will appear for several seconds. However your application will return to the front after a few seconds and the user will not be able to interact with any other applications or change the settings.

The service is set to be a foreground service. This prevents Android from killing our service.
Press on the Stop button to deactivate kiosk mode.
 

Attachments

  • Kiosk.zip
    6.7 KB · Views: 5,498
Last edited:

mkh42

Member
Licensed User
Longtime User
Hello

if you downloaded KioskAppExtended.zip and got an error with something like ..prgstart.ini ... please download fixed version KioskAppExtended_vc2.zip.

greetings
mkh42
 

mkh42

Member
Licensed User
Longtime User
hello

a few additional informations to KioskAppExtended.
The App was mainly developed an tested on Galaxy Tab GT-5110 Android 4.0.3
There everything should work as expected (mini apps I disabled via rooting the tab )

I made some test on a Nexus 7 4.2.2

unfortunately com.android.calendar does not exists on Nexus 7 so you have to edit appstart.ini and put some working app in e.g. com.android.contacts .

it's a pity that automatic unlock screen doesn't work on Nexus. I debugged it and found that the message CallSubDelayed("Main","ReturnFromSleep") creates is not executed until the screen gets unlocked manually. On Galaxy Tab automatic unlock screen works fine. This is not a show stopper but if someone knows a trick to change this behaviour I would like to hear it.

greetings
mkh42
 

Rusty

Well-Known Member
Licensed User
Longtime User
I have been successfully using a KioskService Service to start my application at boot and also when the user presses the HOME button, it returns to my application.
Recently, the start at boot option does not work, but the HOME button while running does work.
Any suggestions on how to deal with this? The below is the log where the kiosk fails at boot.
B4X:
LogCat connected to: B4A-Bridge: asus Transformer TF101-
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
problem enabling bandwidth controls
com.android.server.NativeDaemonConnectorException: Cmd {bandwidth enable} failed with code 400 : {Bandwidth command failed}
    at com.android.server.NativeDaemonConnector.doCommandLocked(NativeDaemonConnector.java:281)
    at com.android.server.NativeDaemonConnector.doCommand(NativeDaemonConnector.java:241)
    at com.android.server.NetworkManagementService.systemReady(NetworkManagementService.java:186)
    at com.android.server.ServerThread$1.run(SystemServer.java:722)
    at com.android.server.am.ActivityManagerService.systemReady(ActivityManagerService.java:7005)
    at com.android.server.ServerThread.run(SystemServer.java:711)
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
** Activity (main) Pause, UserClosed = false **
java.lang.RuntimeException: Unable to create service talkingsurvey.b4a.survey.kioskservice: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2263)
    at android.app.ActivityThread.access$1600(ActivityThread.java:123)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at talkingsurvey.b4a.survey.kioskservice.onCreate(kioskservice.java:33)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
    ... 10 more
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at talkingsurvey.b4a.survey.kioskservice.onCreate(kioskservice.java:31)
    ... 11 more
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at talkingsurvey.b4a.survey.main.initializeProcessGlobals(main.java:5442)
    ... 14 more
Caused by: java.lang.NullPointerException
    at anywheresoftware.b4a.BA.<init>(BA.java:100)
    at b4a.ts.libraries.crypto.innerInitialize(crypto.java:12)
    at b4a.ts.libraries.crypto._initialize(crypto.java:190)
    at talkingsurvey.b4a.survey.main._process_globals(main.java:7020)
    at talkingsurvey.b4a.survey.main.initializeProcessGlobals(main.java:5406)
    ... 14 more
Thanks in advance,
Rusty
 

mkh42

Member
Licensed User
Longtime User
hello

pherhaps you should try to set StartAtBoot of your kioskservice to false. in my KisokAppExtended i go this way. Nevertheless the app is restarted after reboot because the app is the default home app (and starts anyway the kioskservice at create). This could eventually prevent you from having racing conditions during boottime.


greetings
mkh42
 
Last edited:

CapReed

Member
Licensed User
Longtime User
Hi all,

I checked the kiosk mode operation, but when the phone is locked and you receive a call I can not get screen appears.

Is it possible to display a screen other than the default one using the kiosk mode when the phone is locked?

Thank you!
 

Beja

Expert
Licensed User
Longtime User
Thinking outside the box!

Kiosk mode is meant to lock the device to a commercial application used by the public, so mainly it
will be on Tablet rather than a phone.. I can hardly imagine one would make his personal phone as
a kiosk!
Therefore,
The solution is to use Erel's example AND you should tape the device menu (home, back... etc) with
a hard plastic stripe when designing the tablet shell.

cheers!
 

leongcc

Member
Licensed User
Longtime User
I have an app (activity + service) running fine in Kiosk mode.
I am trying to make an exception that allows user to run a particular external activity.
This external activity is the WiFi Settings.

The user is confined to my app and when user wants to change WiFi setting, my app starts the system activity for WiFi Settings ( I have no problem coding this). While the WiFi Settings is at the foreground, the Kiosk will leave it as it is and will not switch my app to the foreground. When the user quits the WiFi settings, my app will take over.

For this to work, my app service would need to know WiFi Settings is currently in foreground or not.
Anyone knows how I can monitor what activity or app is at the foreground ?
 

leongcc

Member
Licensed User
Longtime User
Thanks, I got it working. I am sharing the codes below.

In summary, my app is in kiosk mode but makes an exception if the user wants to change WiFi settings (by selecting an option button in the app activity). The service module of the app continuously monitors that the WiFi setting activity is still in the foreground, if not that means the user has exit WiFi settings and the kiosk will do its job to bring the app back to the foreground.

B4X:
'In my service module
If  (Common.ActivityIsForeground("WifiSettingsActivity")) Then
    Log("WiFi Settings is in foreground)
    ' ......
Else
    ' ......
End If

Sub  ActivityIsForeground(activitySearchName As String) As Boolean
    Dim OS As OperatingSystem
    Dim r As Reflector
    Dim Tasks As List    
    Dim activityString As  String 
    Tasks = OS.getRunningTasks(1)    'Get only the 1st task
    If Tasks.Size > 0 Then          
            r.Target = Tasks.Get(0)
            activityString =  r.GetField("topActivity")
            If (activityString.Contains(activitySearchName)) Then
                Return  True
            End If 
    End If
    Return False
End Sub
 

henry1311

Member
Licensed User
Longtime User
Hello.
I have seen and tried the code in the post # 84.
Very good and seems to do for me.
From the first tests everything seems to work correctly in Android 2.3.3 (Smartphone lg), in Android 2.3.5 (samsung s2) and in Android 4.0.4 (tablet Majestic), while in Android 4.0.4 (tablet samsung tab 2 10.1) is not you can make the keyboard available or appears and disappears immediately due to the tick of the timer!
I tried to install several other keyboards 'not samsung', but it remains the same effect.
Any ideas for troubleshooting?

hello
thanks
enrico
 

henry1311

Member
Licensed User
Longtime User
Hello Erel and thank you very much for your reply.
I did a test with the code for the post #84 and the problem stated above.
I tried your code related to post #1 and everything is working correctly, except for the fact that the application running (not kiosk app!) exits after interavllo timer :
B4X:
Timer1.Initialize ("Timer1", 100)

I'm trying to increase the value of the range and still seems everything work properly ...
Now I work on this example.

I do not understand, however, why the samsung galaxy tab 2 10.1" and 7" the virtual keyboard (samsung and others) behave differently from other tablets!

Thank you very much Erel
Hello
Enrico
 

Gianluca Esposito

Member
Licensed User
Longtime User
I have an application with two views. How can I tell the service to control not the main view?
example
view1: Main
# Region Project Attributes
# ApplicationLabel: Sterilization
# VersionCode: 3
# End Region

view2: LetturaTeli
# Region Activity Attributes

# FullScreen: true
# IncludeTitle: false

# End Region

I wish you the attivase view2
In the service I have:
Notification.SetInfo ("Sterilization", "Sterilization", LetturaTeli)

thanks
 
Top