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,763
Last edited:

GaNdAlF89

Active Member
Licensed User
Longtime User
I thought to do it like this way:

in every activity

'activity that lost the focus
B4X:
Sub Activity_Pause (UserClosed As Boolean)
    CancelScheduledService(KioskService)
    StopService(KioskService)
End Sub

'activity that got the focus
B4X:
Sub Activity_Resume
     'set the value of the new target activity
     'start the kiosk service for new actitivy
End Sub

but I have a problem!
How I can differentiate preceding Activity_Pause with this?

B4X:
Sub Activity_Pause (UserClosed As Boolean)
    If kiosk Then StartServiceAt(KioskService, DateTime.Now + 1 * DateTime.TicksPerSecond, False)    
End Sub

namely, my problem is to differentiate the pause sub from exit app (Home button or back pressed, in this case kiosk service must be activate), and the pause sub from start another activity (in this case kiosk service must be "switched")
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Not sure that I understand the problem. Did you add a process global variable to KioskService with the target module? Add a variable of type Object.

In that case you can use this code:
B4X:
Sub Activity_Pause (UserClosed As Boolean)
    KioskService.TargetModule = Me
    If kiosk Then StartServiceAt(KioskService, DateTime.Now + 1 * DateTime.TicksPerSecond, False)    
End Sub
 

GaNdAlF89

Active Member
Licensed User
Longtime User
The problem is that I want to activate kiosk service only when user "exits" from app, not when starts another activity. Cause this, I must differentiate the activity pause sub between "user exits" and "user starts" another activity.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
While I usually recommend to use multiple activities, in this case it might be easier to implement it with a single activity with multiple panels.

You know when a user starts another activity. Before calling StartActivity you can set a global flag. In activity_pause event check this flag value and only start the service if it is false.
 

GaNdAlF89

Active Member
Licensed User
Longtime User
I found the way to use kiosk with multiples activities (with our help!).
But, when I start another app, this remove the "focus" to my app...
How I can restore the focus to my app?
 

GaNdAlF89

Active Member
Licensed User
Longtime User
ok It works...but I've another problem...I can kill my app from the "Activity manager"..There is any way to disable it? or to disable the bar where it is in?
otherwise, when this happens, how I can modify kiosk code to re-start my app from kiosk service?
 
Last edited:

GaNdAlF89

Active Member
Licensed User
Longtime User
Ok, got it sorted out. Just needed to add like this in the Manifest Editor.

B4X:
'Kiosk Mode
AddActivityText("main",
   <intent-filter>
   <action android:name="android.intent.action.MAIN" />
   <category android:name="android.intent.category.HOME" />
   <category android:name="android.intent.category.DEFAULT" />
   <category android:name="android.intent.category.MONKEY"/>
   </intent-filter>
)
'End Kiosk Mode

Absolutely great!

Rolf

thanks!! It works!!
for curiosity, what does it do this code?
 

rbsoft

Active Member
Licensed User
Longtime User
With this code it is possible to set your application as the HomeScreen. If you combine this with a service module that is set to run at boot then you can make your application to run exclusively and block other applications to be used.

You can combine this with other methods like...
Catch the BackKey
Allow terminating the app only with password
etc.

Rolf
 

colboy

Member
Licensed User
Longtime User
I've been playing with the Kiosk mode and it seems to be just what I need for a project. The only think I can't figure out is how to disable it. I want to build in a back door that will disable the Kiosk mode. I can do this fine until I add the lines to the manifest as defined earlier, which basically force the hardware buttons to reload the app. How can I disable this in code.

Thanks, Colin
 

colboy

Member
Licensed User
Longtime User
See the btnStop_Click code. It exits kiosk mode.

I tried that. Although the app no longer comes to the forground, the buttons still seem to be mapped. So when I press the back button, the application relaunches. I'm using a Nexus S.
 

colboy

Member
Licensed User
Longtime User
And by extra lines I mean these added to the manifest

B4X:
'Kiosk Mode
AddActivityText("main",
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.HOME" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.MONKEY"/>
    </intent-filter>
)
'End Kiosk Mode

Also what does the line
B4X:
    <category android:name="android.intent.category.MONKEY"/>
refer to?

Thanks, Colin
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can try this code (requires Reflection library):
B4X:
Sub Activity_Resume
   KioskService.limitNumberOfTicks = 0
   Log(Activity.GetStartingIntent)
   If kiosk = False Then
      Dim r As Reflector
      r.Target = Activity.GetStartingIntent
      If r.RunMethod2("hasCategory", "android.intent.category.HOME", "java.lang.String") Then
         Activity.Finish
      End If
   End If
End Sub

It seems to work here.
 

mvarela

New Member
Licensed User
Longtime User
I can not answer or making calls

I'm testing Kiosk Service and works great! but... when I try to answer a entry call, my app reestarts and I can't anwer it.

I can't making outgoing call either

I'm using a touch screen telephone
 
Top