Achieve 100% Kiosk Mode On Android Wear

Sanat Shukla
2 min readJun 7, 2018

--

Android Wear OS doesn’t support kiosk mode officially. I have used workaround in which I am able to restart the activity in onStop() of the activity. But, when I tried it, it takes around 5 seconds to re-open the same activity.

By re-opening the same app is not the good solution because it takes some delays. Then what is the solution?

The solution works on only Wear OS 2.X. In Wear OS 2.X we can apply REORDER_TASKS in which we can move the app to the front. In activity’s onPause() just reorder the task:

@Override
protected void onPause() {
super.onPause();

ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);

activityManager.moveTaskToFront(getTaskId(), 0);
}

Add permission to Manifest:

<uses-permission android:name="android.permission.REORDER_TASKS" />

Set categories to Manifest:

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

Override button’s functionality:

public boolean onKeyDown(int keyCode, KeyEvent event){
if (event.getRepeatCount() == 0) {
if (keyCode == KeyEvent.KEYCODE_STEM_1) {
// Do stuff
return true;
} else if (keyCode == KeyEvent.KEYCODE_STEM_2) {
// Do stuff
return true;
} else if (keyCode == KeyEvent.KEYCODE_STEM_3) {
// Do stuff
return true;
}
}
return super.onKeyDown(keyCode, event);
}

Disable swipe functionality by applying theme:

<style name="AppTheme" parent="@android:style/Theme.DeviceDefault">
<item name="android:windowSwipeToDismiss">false</item>
</style>

Relaunch App on Boot:

Add receiver to Manifest:

<receiver
android:enabled="true"
android:exported="true"
android:name=".StartMyServiceAtBootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">

<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

</receiver>

BroadcastReceiver:

public class StartMyServiceAtBootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent intentOpen = new Intent(context, MainActivity.class);
intentOpen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentOpen);
}
}
}

Handle Call During Kiosk:

If you want to manage the call functionality then you have to disable Kiosk during ringing and re-apply the same logic:

@Override
public void onPause() {
Log.d(TAG, "onPause()");
super.onPause();
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (telephonyManager.getCallState() != 1) {
ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(getTaskId(), 0);
}
}
@Override
public void onStop() {
super.onStop();
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(telephonyManager.getCallState() != 1 && isLocationPermissionsGranted()) {
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
}
}

What About Wear OS 1.X?

For Wear OS 1.X we can not achieve fully Kiosk but partially(90%) by using reopening the app on onPause() which takes delay of 5 seconds.

Note :

This functionality is not user friendly and Android Play Store wouldn’t approve of these unless you have a very strong reason (Source).

--

--

Sanat Shukla

Lead Engineer - Android @Simform. Passionate about innovation, mobile and IT. Loves to build apps with Java and Kotlin.