Neat tricks when implementing a kiosk app

[Android] Sep 25, 2012

Introduction  

This article presents a few neat methods to prevent a user performing a particular action on the device when an application is running. The methods can be useful if you develop an app which is intended to be run on a device, temporarily given to a user. For instance, you may want to share a device to let the user find some information on a particular website, product or service. Kiosk style applications allow you to control the user experience and maintain the security of the device.

Web browser

Let’s start with creating a simple web browser with a locked down start page. In order to do so, implement a WebView with your own WebViewClient. The WebViewClient is an object which defines actions performed when a particular situation occurs in a WebView. These actions are related to typical web browsing activities. Using it will open hyperlinks in the WebView. To provide such a feature, use the shouldOverrideUrlLoading callback. You can also disallow opening hyperlinks from undefined domains, but to do this, you have to check if a url contains the given domain.

private class KioskWebViewClient extends WebViewClient {
final String mDomain = "android.com";

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
	if(url.contains(mDomain)) {
		view.loadUrl(url);
	}
	return true;
}
}

At this point you can use this client in your WebView. Let’s put it in the layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent" >

	<WebView
		android:id="@+id/webView"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent" />

</RelativeLayout>

The next step is to initialize the WebView in the Activity. Don’t forget to add INTERNET permission to your app’s manifest.

 private WebView mWebView;
private final String mHomepageUrl = "http://developer.android.com";

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	mWebView = (WebView) findViewById(R.id.webView);
	mWebView.setWebViewClient(new KioskWebViewClient());
	mWebView.loadUrl(mHomepageUrl);
}

You can also determine more browser properties using the WebSettings object -

 WebSettings ws = mWebView.getSettings();

It is possible, for example, to enable zoom and JavaScript support, or disable the saving of form data by using the proper methods of this object. Please refer to the documentation for more details:

http://developer.android.com/reference/android/webkit/WebSettings.html

Screenshot 1 – A simple web browser

Screenshot 1 – A simple web browser

Removing the title bar and status bar

Another action you may want to perform is to remove the app title bar and the system status bar, which will make an app full-screen. Please note that some devices (like the Galaxy Nexus or Galaxy Tab tablets) have another bar with buttons which are represented by hardware buttons in other devices. That bar cannot be covered by any app. In order to remove those bars, use the code below before calling the setContentView method in your Activity. It will request the extended feature (to remove the title bar) and set the proper flag to the window (to cover the status bar).

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
Screenshot 2 – Web browser in full screen mode

Screenshot 2 – Web browser in full screen mode

Prevent exiting the app via the back button

Since the kiosk app shouldn’t be closed, you can handle pushing the back button and assign another action to it. For instance, you may want to go to the homepage when user tries to exit the app. To do so, override one of the Activity methods, which is called every time the back button is pressed.

@Override
		public void onBackPressed() {
		mWebView.loadUrl(mHomepageUrl);
	}

Disable the home button

In general, disabling the home button is not a good practice, but it can be very useful when developing a kiosk app. Since Android 4.0 there is no effective method to do so, so you may need to use another solution, e.g. setting your app as a home screen, which is described further. However, for older OS versions you may switch the window type to keyguard, which will prevent from handling home button pressing.


@Override
		public void onAttachedToWindow() {
		getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
		super.onAttachedToWindow();
	}

Disable the volume buttons

Another restriction you may want to implement is disabling the volume control. It can be reached quite easily, by intercepting a key event in Activity, checking its code and consuming it if it comes from pushing the volume down or volume up button.

private final List mBlockedKeys = new ArrayList(Arrays.asList(KeyEvent.KEYCODE_VOLUME_DOWN, 
KeyEvent.KEYCODE_VOLUME_UP));

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
	if (mBlockedKeys.contains(event.getKeyCode())) {
		return true;
	} else {
		return super.dispatchKeyEvent(event);
	}
}

Set an app as a default home screen

Another trick can be setting your kiosk app as a home screen. In order to do so, you have to register your app for filtering the proper intent, and then set it manually to be the default one for handling this intent. The intent is sent every time a user presses the home button. Therefore, you can prevent from going to the launcher, when the app is running. Add the following filter to the Activity in your manifest:

<intent-filter>
	<action android:name="android.intent.action.MAIN" />
	<category android:name="android.intent.category.HOME" />
	<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Since now your app will be ready to handle pressing the home button. You can choose it to be the default choice, so the system will not ask again. However, pressing the home button will create a new instance of Activity every time. You can protect from that by running your Activity in singleTask mode. This parameter is also declared in a manifest, in tag.

<activity
	android:name=".MainActivity"
	android:launchMode="singleTask" >

Prevent screen dimming

There is another window flag which can help you to keep your app visible, preventing automatic turning off of the device’s screen, keeping the screen bright as long as the window is visible. As before, set the flag in your Activity.

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Now the screen will only be locked after pressing the power button.

Set an app to cover the lock screen

If you want your app to be visible all the time, setting it to be on top of the lock screen may be useful. This is quite simple to achieve, you only need to set few additional flags for your Activity window.

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

Now pushing the power button will cause screen dimming, but after pushing it again the window will still be visible. For more information on developing your Kiosk apps, check out Samsung Developers


COPY URL twitter facebook