Kiosk Mode App for the Oculus Quest and Oculus Go in Unity

by SlideFactory

“If you are a Unity developer looking for a free option to create an app using Kiosk Mode for Oculus Quest or Oculus go, we’re here to point you in the right direction.”

Overview

If you are an Oculus Quest or Oculus go developer creating VR applications for retail or just looking for a free option to create an app emulating Kiosk Mode for Oculus Oculus Quest or Oculus go, we’re here to point you in the right direction.

In this article, we’ll show you how to modify your application to enable a Quest or Go app to load a specific app on restart (or at boot) by modifying a few manifest settings and creating a custom Broadcast receiver class in Java to launch your app.

Developers implementing this process could, in theory, also disable settings such as prohibiting the user from being able to exit to Oculus Home as well, but we’ll leave that for later article. Once completed, you’ll have an app that can run on start-up and emulate Kiosk Mode for Oculus Quest or Oculus Go.

What is kiosk mode? 

In this article, Kiosk Mode for Oculus Quest refers to a specific way to create an application or modify your VR headset to bypass the standard Oculus home screen on Boot or restart and launch a specific application instead. In this way, a business can create a headset with their own version of a start screen that would allow them to brand the experience, launch other applications, and gain more control of the device experience than is generally granted by Oculus.

While there are other solutions to this, such as paid apps and / or utilizing the upcoming $999 Oculus Quest Enterprise Edition, this article will walk you through a method that is relatively easy to implement and has been tested on both the Oculus Go and the Oculus Quest.

What will we be changing?

In general, a Oculus VR app on the Go or Quest is just an android application running on an Android device. Because of this, and Unity’s ability to allow developers to modify the Android Manifest file as well as export  their Unity projects to an editable Android project, modifying your app to tell the system to load in a certain way only required 2 modifications to be made.

  • Adding a line to your Manifest to trigger a custom intent on boot or restart
  • Adding a receiver to your Unity project to capture this intent and launch your project.

Setting things up in Unity

First, let’s open Unity Hub and create a new project. We’re building this version in 2019.2.9f1 but we’ve tested it with 2018 as well so feel free to try it out with an older project.

New Application in Unity

We’re going to be building for the Quest in our version so let’s ensure we’re on the Android Platform and switch everything over.

Switch Platform to Android

Next, because we’re lazy and don’t want to create anything complicated for this example, let’s drop a sphere into our scene. If you’d like to make something more complicated, feel free! In this step, we just want something recognizable so we can ensure everything worked correctly. 

Create a Sphere in the Scene

Once you’ve made your changes to the scene. Save it and let’s add it to the building our Build Settings.

Prepare scene for Export to Android Studio

Now, click on “Player settings” and lets make sure we have everything set-up to build to the quest. You’ll need to check “XR Settings” and make sure you have “Oculus” added to the Virtual Reality SDK. Because we’re going to be making changes to the manifest, don’t check “V2 Signing Quest” at this point. We have another article that explains why. For now, just trust me.

Add VR Support

While we have the Player settings open, we’re also going to jump over to “Other settings” and change our minimum API level to 19 to avoid any build errors later. We’ll also remove “Vulkan” from the Graphics API settings.

Other settings for Android build
Remove Vulkan

Once that’s all done. We’ll export the Application for Android. Make sure you select the “Export option, select a location to built too, and export your app.

Export Project to Android Studio
Export Project to Android Studio - 2

Android Studio

Now that your app is exported, we’ll open up Android Studio. At this point, we’re going to assume you already have your Quest set-up in Developer mode. We’ll also assume you know the basics of Android Studio and can follow along. 

Aside: If you aren't already set-up in Developer mode for Quest, make sure you check-out this article on getting set-up in Developer Mode. 


Once you’re in Android Studio, lets make make sure to sync the build, just to ensure everything is set-up correctly. 

Sync Project

CustomReciever.java

If that all worked, go ahead and open up you’re Java folder and find your project folder. Once there, right click on the Project folder and create a new class called “CustomReciever.java” within it.

Create Class

Now, open up the class you just created and enter the code below. Make sure to change the package names to whatever your project package names were set too.

package com.DefaultCompany.KioskMode;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

 public class CustomReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent){
        Intent i = new Intent(context, UnityPlayerActivity.class);
        if(i !=null){
            context.startActivity(i);
        }
    }
 }

As you can see, this code extends BroadcastReceiver, which Android runs at certain points during an application lifespan. We’re going to modify the Unity Manifest to trigger this block of code when certain events occur. We’ll also pass it some information when this happens and tell it to play our application.

AndroidManifest.xml

Now that we have our class in place, let’s jump over to our Manifest and make some modifications. Find your AndroidManifest.xml file and open it up. We’re going to add a few lines to the file, shown below:

Change one:

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

This tag is going to tell our application that we’re allowed to receive Boot events. It’ll be important for kiosk mode and will let our application know when the device is booted and / or restarted.

Change Two:

<receiver android:name="com.DefaultCompany.KioskMode.CustomReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" android:enabled="true" android:exported="true">
 <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>

Along with receiving the event, the change above will allow our application to act on an event. When recieved, it will call out to the CustomReciever class. In this case, when the devices is booted, we’re capturing the event and telling our application to launch our file.

Completed File:

The complete manifest file should look like the below example with the “package” names being swapped out with your own:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.DefaultCompany.KioskMode" xmlns:tools="http://schemas.android.com/tools" android:installLocation="auto">
 <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 <application android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name">
   <activity android:label="@string/app_name" android:screenOrientation="landscape" android:launchMode="singleTask" android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|uiMode" android:hardwareAccelerated="false" android:name="com.DefaultCompany.KioskMode.UnityPlayerActivity" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
     <intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
     <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
     <meta-data android:name="android.notch_support" android:value="true" />
   </activity>
   <receiver android:name="com.DefaultCompany.KioskMode.CustomReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" android:enabled="true" android:exported="true">
     <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>
   <meta-data android:name="unity.build-id" android:value="e70d6a74-6eeb-4581-ba7f-e669e6d90476" />
   <meta-data android:name="unity.splash-mode" android:value="0" />
   <meta-data android:name="unity.splash-enable" android:value="False" />
   <meta-data android:name="notch.config" android:value="portrait|landscape" />
   <meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only" />
 </application>
 <uses-feature android:glEsVersion="0x00030000" />
 <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
 <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
 <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
</manifest>

If you’ve been following to this point. You’re almost there! Now, resync your project, just to make sure you don’t have any errors, just as we did before.

Sync Project Again

Assuming everything is good, make your quest is plugged in and Android Studio is pointing to your Quest. 

At this point, you’re ready to build. Hit the run button and you should have the app installed on your quest in a matter of seconds.

Let’s test it out.

Put on your quest and you should see the sphere floating in front of you. When you hold down the power button on the side of the device and hit “restart” your quest should reboot. After choosing your guardian preferences, drop you right back into your application.

And that’s it!

You’ve now created a Kiosk App for the Oculus Quest. In our example, we’ve left the ability for the user to exit out of the app by holding down the menu button. In the future, you’re welcome to create any number of other intents and change the features you give your app users.

Happy building!

Share this article:

You might also like: