Screenshot_2014-04-26-01-53-06

How to enable “Immersive Mode” for Android Apps in Unity

Supply Drop (Android) pictured above

Immersive Mode was a feature introduced in Android 4.4 (KitKat). It allows apps to hide the navigation buttons (for phones with on-screen navigation buttons, like the latest in the Nexus series, Moto X, LG G2, Sony devices, etc.).

Enabling Immersive Mode in Unity is relatively easy; you need to make your own plugin but it requires very little code.

At the bottom of this post I have posted a unity package that will enable Immersive Mode. I also posted the individual JAR and AndroidManifest files (in a .zip) if you would like to manually inspect/import them.

If you use the .unitypackage, make sure you do not have an existing custom Android Manifest in Plugins\Android folder since it will be overwritten. Or, make a copy of your current manifest, and merge the necessary elements into the new one after importing the plugin.

If you would like to create the plugin on your own, the steps below detail how to do that.

Step 1 – Create new Android Project:

Create a new Android project in Eclipse. You can just leave the default for everything (except your package name, if desired), click ‘Next’ until the project creation dialog closes.

Step 2 – Mark your project as a “Library” and add the classes.jar library to your project:

Right click on your project in the project explorer and click on ‘Properties’. Select ‘Android’ from the left menu and check the “Is Library” box near the bottom. Don’t click ‘OK’ yet, we have one more thing to do in here.

mark_as_library

Now we need to add the classes.jar library that comes with Unity.

java_build_path

Go to ‘Java Build Path’ in the Properties window and click on the ‘Libraries’ tab; click ‘Add External JARs..’ and navigate to your Unity installation folder and go to (example for default Windows Installation) C:\Unity\Editor\Data\PlaybackEngines\androidplayer\bin\

In that folder is a ‘classes.jar’ file.ย Double click it to add to your Eclipse project and then click ‘OK’.

Step 3 – Implementing the Immersive Mode API:

Now the project has all you need to extend the UnityPlayerActivity and add the code for the Immersive Mode API.

First thing is to extend UnityPlayerActivity.

public class MainActivity extends UnityPlayerActivity {

Delete everything that was preloaded between the activity brackets. The code in the PasteBin link below is everything you will need. I will explain what exactly it does afterwards.

Here is the PasteBin link for the entire code needed in your MainActivity (make sure the package name at the top is whatever your package is called).

So, the onResume() method should be somewhat self-explanatory. We limit it to Android API level 19 or higher since that is KitKat, and only KitKat or greater will support Immersive Mode.

Then there is that runnable.

When I first implemented Immersive Mode into my Unity app, I left it at the onResume() code and called it good. What I noticed was, if a user pressed the volume buttons, after the volume slider disappeared, my app would not return to Immersive Mode. The navigation buttons would still be there covering up part of my app!

The onKeyDown() method detects when the volume key is pressed and, after a short delay, calls the runnable which will reset the Immersive Mode flags. Voila!

Step 4 – Export your Eclipse project as a .jar file that you can import into Unity:

Right click on your project in the Eclipse Package Explorer and click ‘Export’. Select the Java folder and then JAR file.

export_jar

Step 5 – Import your JAR into Unity:

In Unity, click Assets->Import New Asset. Browse to your recently exported JAR file and import it. If you don’t have them, create a ‘Plugins’ folder in your Unity project and, inside that, create a folder called ‘Android’. Place your imported JAR file into the Plugins\Android folder.

Step 6 – Create a custom AndroidManifest:

The last step! All you need now is an Android Manifest that tells Unity to use your custom activity that you made in Eclipse as the main activity for your app.

Here is the PasteBin link to the custom AndroidManifest you will need to use.

Save that as AndroidManifest.xml in your Plugins\Android folder in Unity.

Basically this just tells Unity to use your java class as the main activity for your app.

You need to change the Activity name in the <activity> brackets to match the path to MainActivity in the project you created.

manifest

I don’t believe the package name has to be your Unity app’s package name, since when Unity builds the APK, it merges its own created manifest with this custom one. Changing the app version code/name is still done in the Unity inspector. You do not need to update it in the custom manifest.

That should be it! You can now run your game on a phone that supports Immersive Mode and you should see it in action!

Alternatively, I have posted the JAR and AndroidManifest.xml filesย at the bottom of this post. You can download these and add them to your Unity project and be rolling with Immersive mode in minutes. Make sure you put them both in the Plugins\Android folder of your Unity project.

One other thing to note, be careful when importing other Unity plugins. Many will overwrite your AndroidManifest.xml file. The best thing to do is to look at what <activity></activity> and permissions that the plugins are wanting to add, and then just add those manually to your custom manifest. The only thing that matters is that the Immersive Mode activity needs to have the .MAIN and .LAUNCHER intents in the manifest to work.

If you have any questions or issues, please comment below. I made this tutorial retroactively, but I think I covered everything.

DOWNLOAD UNITY IMMERSIVE MODE FILES

DOWNLOAD UNITY PACKAGE FOR EASY IMPORT INTO PROJECT

If you would like to donate to me, click the PayPal donate button below.

35 thoughts on “How to enable “Immersive Mode” for Android Apps in Unity”

  1. Thank Brandon! i successed with hide navigationbar. But oritention Screen mode alway in Portrait, i using in setting android with LandscapeRight mode, help me pls!

  2. Hello Brandon just imported it into my project but once i build and run the app it becomes crippled nothing works on my game any workaround will be appreciated

  3. Hi Bradon,

    I tried in Nexus 7 and Note II but its not working.
    I followed the same procedure and export the same jar but it’s not working then i tried with the your jar file but the same issue is being.

    Immersive mode is not working.
    Let me know if any other code or other things remain to do for it.

    Thanks.

  4. Thank you very much for this explanation! I have one simple question though: I assume that “com.cultureoftech.immersivemode” in both the class and the manifest should be the same as the Bundle Identifier in the Android Player Settings of Unity, is that correct?

    1. The bundle identifier in the Android Player Settings should be the package name for your app; I don’t think you have to change anything in the Immersive Mode manifest. Since the java package that is imported is com.cultureoftech.immersivemode, you can’t change that or the plugin won’t work.

      edit: Unless you are building the plugin yourself. Then the manifest package name just has to be whatever the package is in the plugin you created.

      1. Aha, so the package name of the plugin isn’t that important, I don’t have to rebuild it myself just to give it my own name, right? So it’s totally fine using the unitypackage you made? I’ve been using Unity for quite a while but only now getting into Android development, so still a lot I don’t know, never used Java ^^’

        1. Right! Unity creates a manifest on its own and merges that with the manifest provided by plugins. Whatever package name you have for your app in the Android Settings is what your app will be.

          Keep in mind, if you do use other Android plugins, they will want to replace the manifest that my plugin generates. In those cases, you have to look at the activities in each manifest and merge them, as you can have only one AndroidManifest file in the plugin root folder (this is where Unity looks when merging plugin manifests with its own).

          1. Thanks for the explanation ๐Ÿ™‚ Got it working (Not using any other plugins so didn’t have to do anything extra) but at one moment I opened the app, pressed the home button, then wanted to resume the game by opening the app again (touching the app icon) but it didn’t resume, it just stayed black and after a while stopped working :/ That was on my Nexus 5, I’m sure the crashing has to do with these changes cause it never crashed before. Maybe I’ll just wait till Unity adds Immersive mode as a checkbox in the player settings…

  5. Great! Works really well… but if you edit a text field and return to the game, it doesn’t return to immersive mode.

    1. I know I’ve said this to a lot of replies, but I can try to look into that sometime soon.

      I basically just made this for my game that has no user entered data like that, just touch controls and that’s basically it.

      If I do find time I will try to mess with a few things. You can also do the same with the source code. If anyone finds any fixes I would definitely like to know about it so I can update the tutorial! I’m wondering if I have to build in some sort of method to be called from C# code.

      1. Hi Brandon,

        Thanks for the prompt reply. Here is the solution to the text editing issue:

        In the MainActivity.java file:
        public void manualReset()
        {
        mHandler.postDelayed(resetImmersive, 50);
        }

        The delay is optional, it just makes the animation feel a little better.

        And in your Unity3D C# code, after the edit is complete, run code along these lines:

        if (Application.platform == RuntimePlatform.Android)
        {
        using (AndroidJavaClass cls_UnityPlayer = new AndroidJavaClass(“com.unity3d.player.UnityPlayer”))
        {
        using (AndroidJavaObject obj_Activity = cls_UnityPlayer.GetStatic(“currentActivity”))
        {
        obj_Activity.Call(“manualReset”);
        }
        }
        }

        You can pretty much for a reset here or anywhere else you have this problem.

        1. Great, thank you! I figure that’s about how the paid plugins in the Asset Store handle it, but I have never built a java class call method in C#.

          Thanks again!

  6. Hi Brandon,
    Firstly Thanks for the plugin…. ๐Ÿ™‚

    I am using the plugin in my various apps, now the issue I am facing is ,

    Steps to reproduce
    1. When I launch the game for first time using the plugin and I press home button from any screen the app minimizes in home panel.
    2. When I resume the app say by clicking the Icon on menu screen,
    the app hangs for first two times always and from the third time it behaves normally

    This is happening only after I install the plugin in a fresh app with no other plugins.

    Thanks,
    Amit

    1. I have no idea what would cause that. As you can see from the source code, there is really very little changes made. I can try messing with it, but am not really sure what could be modified.

      Interesting observation though, I’ll try to duplicate on my apps.

    1. I can try to look into it this week.

      Question:
      When this happens, if you hit the multitask button and then go right back into your app does Immersive Mode trigger again?

      On the whole, Immersive Mode is kind of buggy. Even from big time developers I will notice times that the buttons don’t hide once they come up for some reason. Hopefully it gets smoother in later Android updates, but I’m sure there is some sort of workaround we can think up to deal with the issue you’re having.

  7. Hi, I followed your tutorial and it works great for devices with no hardware buttons (nexus 5), although the app doesn’t autostart when building from Unity. But when I try to install on say a Note 3, that has hardware buttons, the app appears to install but won’t start when clicking the icon displaying an error “App isn’t installed.” I have been searching for a solution but haven’t found one yet.

    1. Very weird, I haven’t encountered that. The autostart from Unity not happening is even weirder. I’ve tried it on a Nexus 4, Nexus 5, Nexus 7, Galaxy Nexus and HTC Thunderbolt and never encountered either of those issues. Only thing I can think of is uninstalling the app from the phone and trying again, but I don’t see why that would make a difference.

      I am thinking the problem with your phone saying the app isn’t installed must be some issue with the manifest, but that wouldn’t make much sense if it works on other Android phones.

  8. Hi, I have already a plugin which has an activity with .MAIN and .LAUNCHER intents. So how can I achieve both of these to run together? Thanks.

    1. I’m not at my computer right now so just a quick basic reply…do you have access to the source code for the plugin that requires the .MAIN activity?

        1. Ok, after a quick search I think there is a solution to use two plugins that need the .MAIN intent in the Android Manifest.

          Basically, you would have to modify my tutorial and add a method in Java, then add a few things in Unity in the first scene’s script to call the Immersive Mode Activity from whatever activity the plugin you’re using now is.

          Here is the post I found

          I’ll look around some more and let you know if I find anything, but this seems like the solution.

          This means that you’ll have to follow my tutorial rather than just the the unitypackage I provided. I will think about making another unitypackage that supports this method and detail the steps to implement it in the future.

          1. Hi Brandon,

            when are you going to release this unitypackage?
            I’m using the Google Play Services plugin, which also uses the .MAIN and .LAUNCHER intents.

            I would be really happy if you could release this soon ๐Ÿ™‚

            Regards
            Dennis

          2. Hi Dennis.

            Sorry, I’ve stepped away from Unity/Game development for a bit to concentrate on learning other things. I am still very much a beginner in all areas of programming, so it isn’t something I could whip up in a few minutes (or at least I assume it isn’t).

            You can try reading about what changes you need to make to run two plugins that use the same intents and attempt to merge that information with the tutorial I wrote up.

            It is definitely still something I want to finish and post for everyone to use, but it may be some time before I get to it. I actually switched to a paid plugin that has all Google/Social APIs built in as I was spending too much time trying to make my own plugins. The one I bought is called Android Native Plugin by Stan’s Assets (Link Here). It’s a really good price and he has responded to any questions I’ve had very quickly. That’s an option if you don’t want to try to make the plugin yourself (his includes a one-line code call for Immersive Mode, among many other things).

            Good luck!
            -Brandon

Leave a Reply