Android - Kiosk Mode - Single App Mode


#1

I want to have a single app on my device which will start on device start and can’t be exited without a pin. Can this be done with nativescript? If it’s possible, can you provide me an example?
Note: It’s an App for an mounted Android Product Scanner Device.


#2

@MichaelB
Try using the native API mentioned in the docs here, that should work
https://developer.android.com/work/cosu.html


#3

Hi Michael,

Did you managed to make your kiosk app ?
And if so, would you mind sharing your experience, and even pieces of code ?

Thk


#4

Hello. I’m sorry for my late answer. I managed to create a single app Mode. My Device has following properties:

  • only one Hardware-Button, which is a Home-Button
  • Android 5.1

I managed to prevent the user from exiting by using an Overlay, Immersive Mode and set the App as Home App.
To create the overlay and start the Immersive Mode i wrote a Plugin based on the following Sites:

To prevent the Home-Button, i set the App as Home App.

Example Code:

Draw Overlay:

    private void preventStatusBarExpansion(Context context, Activity activity) {
        WindowManager manager = ((WindowManager) context.getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE));
        WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
        localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
        localLayoutParams.gravity = Gravity.TOP;
        localLayoutParams.flags =
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | // this is to enable the notification to recieve touch events
                        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; // Draws over status bar

        localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        localLayoutParams.height = (int) (25 * context.getResources()
                .getDisplayMetrics().scaledDensity);
        localLayoutParams.format = PixelFormat.RGBX_8888;
        bottom = new CustomViewGroup(context);
        manager.addView(bottom, localLayoutParams);
    }

    private static class CustomViewGroup extends ViewGroup {
        public CustomViewGroup(Context context) {
            super(context);
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            // Intercepted touch!
            return true;
        }
    }

Activate Immersive Mode

    activateKioskMode: function() {
		// set immersive mode
		var flags = android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE
		| android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
		| android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
		| android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
		| android.view.View.SYSTEM_UI_FLAG_FULLSCREEN
		| android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
		
		var window = application.android.startActivity.getWindow();
		var decorView = window.getDecorView();
		decorView.setSystemUiVisibility(flags);
		
		// diable user to leave immersive mode
		var context = utils.ad.getApplicationContext();
        var kiosk = new de.hh.iap.kioskmode.KioskMode();  // This is my Android Class
        kiosk.activateKioskMode(context, application.android.foregroundActivity, false);
    },