├── .gitignore ├── java └── android-immersive │ └── src │ └── org │ └── haxe │ └── extension │ ├── AndroidImmersiveFull.java │ ├── AndroidImmersiveLowProfile.java │ ├── AndroidImmersiveStatusColorBar.java │ └── AndroidImmersive.java ├── haxelib.json ├── include.xml ├── extension └── androidImmersive │ └── AndroidImmersive.hx ├── LICENSE.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | project/obj 2 | *.zip 3 | *.sublime-project 4 | *.sublime-workspace 5 | *.DS_Store -------------------------------------------------------------------------------- /java/android-immersive/src/org/haxe/extension/AndroidImmersiveFull.java: -------------------------------------------------------------------------------- 1 | package org.haxe.extension; 2 | 3 | import android.os.Bundle; 4 | 5 | public class AndroidImmersiveFull extends AndroidImmersive { 6 | 7 | @Override public void onCreate (Bundle savedInstanceState) { 8 | if(AndroidImmersive.currentMode == null){ 9 | AndroidImmersive.currentMode = "immersive"; 10 | } 11 | super.onCreate(savedInstanceState); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /java/android-immersive/src/org/haxe/extension/AndroidImmersiveLowProfile.java: -------------------------------------------------------------------------------- 1 | package org.haxe.extension; 2 | 3 | import android.os.Bundle; 4 | 5 | public class AndroidImmersiveLowProfile extends AndroidImmersive { 6 | 7 | @Override public void onCreate (Bundle savedInstanceState) { 8 | if(AndroidImmersive.currentMode == null){ 9 | AndroidImmersive.currentMode = "lowProfile"; 10 | } 11 | super.onCreate(savedInstanceState); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "extension-android-immersive", 3 | "url": "https://github.com/sempaigames/extension-android-immersive", 4 | "license": "MIT", 5 | "tags": ["android","immersive","lime","openfl","immersive mode"], 6 | "description": "Lime extension for enabling immersive mode on most android versions.", 7 | "version": "1.1.0", 8 | "releasenote": "Support for low profile", 9 | "contributors": ["fbricker"], 10 | "dependencies": { } 11 | } 12 | -------------------------------------------------------------------------------- /java/android-immersive/src/org/haxe/extension/AndroidImmersiveStatusColorBar.java: -------------------------------------------------------------------------------- 1 | package org.haxe.extension; 2 | 3 | import android.os.Bundle; 4 | 5 | public class AndroidImmersiveStatusColorBar extends AndroidImmersive { 6 | 7 | @Override public void onCreate (Bundle savedInstanceState) { 8 | if(AndroidImmersive.currentMode == null){ 9 | // AndroidImmersive.currentMode = "statusBarColor"; 10 | } 11 | super.onCreate(savedInstanceState); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /include.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /extension/androidImmersive/AndroidImmersive.hx: -------------------------------------------------------------------------------- 1 | package extension.androidImmersive; 2 | 3 | #if android 4 | #if (openfl < "4.0.0") 5 | import openfl.utils.JNI; 6 | #else 7 | import lime.system.JNI; 8 | #end 9 | #end 10 | 11 | class AndroidImmersive { 12 | 13 | #if (android) 14 | public static var setStatusBarColor:Int->Void = JNI.createStaticMethod("org/haxe/extension/AndroidImmersive", "setStatusBarColor", "(I)V"); 15 | public static var setLowProfile:Void->Void = JNI.createStaticMethod("org/haxe/extension/AndroidImmersive", "setLowProfile", "()V"); 16 | public static var setImmersive:Void->Void = JNI.createStaticMethod("org/haxe/extension/AndroidImmersive", "setImmersive", "()V"); 17 | #else 18 | public static var setStatusBarColor:Int->Void = function(i:Int){}; 19 | public static var setLowProfile:Void->Void = function(){}; 20 | public static var setImmersive:Void->Void = function(){}; 21 | #end 22 | 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | The MIT License (MIT) 5 | 6 | Copyright (c) 2015 SempaiGames (http://www.sempaigames.com) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # extension-android-immersive 2 | 3 | Lime extension for enabling immersive mode on most Android devices. 4 | 5 | ### Main Features 6 | 7 | * Immersive mode for Android ICS and later 8 | * Hiding of status bar and soft navigation keys 9 | * Low profile mode for devices with soft keys hiding disabled 10 | * Setting of status bar color 11 | 12 | ### How to Install 13 | 14 | To install this library, you can simply get the library from haxelib like this: 15 | ```bash 16 | haxelib install extension-android-immersive 17 | ``` 18 | 19 | ### How to Use 20 | 21 | To use this extension, simply add the next line in the project.xml 22 | ```xml 23 | 24 | ``` 25 | And target the sdk version to at least 19, by adding the following lines in the project.xml 26 | ```xml 27 |
28 | 29 |
30 | ``` 31 | For immersive mode full, low profile or display a colored bar, add one of the following lines in the project.xml (only one) 32 | ```xml 33 | 34 | 35 | 36 | ``` 37 | 38 | To set the status bar color, or change the immersive mode in runtime, call this: 39 | 40 | ```Haxe 41 | StatusBarColor.setStatusBarColor(color); // color must be in 0xaarrggbb format; -1 leaves the default 42 | StatusBarColor.setLowProfile(); // sets low profile mode 43 | StatusBarColor.setImmersive(); // sets the most immersive mode available 44 | ``` 45 | 46 | 47 | ### License 48 | 49 | The MIT License (MIT) - [LICENSE.md](LICENSE.md) 50 | 51 | Copyright © 2015 SempaiGames (http://www.sempaigames.com) 52 | 53 | Author: Joacko Bengochea & Federico Bricker 54 | -------------------------------------------------------------------------------- /java/android-immersive/src/org/haxe/extension/AndroidImmersive.java: -------------------------------------------------------------------------------- 1 | package org.haxe.extension; 2 | 3 | import java.io.IOException; 4 | import java.util.Map; 5 | import java.lang.Runnable; 6 | import android.content.Intent; 7 | import android.graphics.Color; 8 | import android.os.Bundle; 9 | import android.os.Build; 10 | import android.os.Handler; 11 | import android.view.Gravity; 12 | import android.view.ViewGroup.LayoutParams; 13 | import android.view.View; 14 | import android.view.Window; 15 | import android.view.WindowManager; 16 | import android.view.KeyEvent; 17 | import android.view.KeyCharacterMap; 18 | import android.widget.FrameLayout; 19 | import android.widget.VideoView; 20 | import android.util.Log; 21 | import android.content.res.AssetFileDescriptor; 22 | 23 | 24 | 25 | public class AndroidImmersive extends Extension { 26 | 27 | protected static String currentMode = null; 28 | private static final int DELAY_TIME = 500; 29 | 30 | /** 31 | * Called when an activity you launched exits, giving you the requestCode 32 | * you started it with, the resultCode it returned, and any additional data 33 | * from it. 34 | */ 35 | @Override public boolean onActivityResult (int requestCode, int resultCode, Intent data) { 36 | return true; 37 | } 38 | 39 | /** 40 | * Called when the activity is starting. 41 | */ 42 | @Override public void onCreate (Bundle savedInstanceState) { 43 | View decorView = mainActivity.getWindow().getDecorView(); 44 | decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() { 45 | @Override 46 | public void onSystemUiVisibilityChange(int visibility) { 47 | if(Build.VERSION.SDK_INT < 16 || Build.VERSION.SDK_INT >= 19){ 48 | return; 49 | } 50 | resetSystemUiVisibility(); 51 | } 52 | }); 53 | } 54 | 55 | /** 56 | * Perform any final cleanup before an activity is destroyed. 57 | */ 58 | @Override public void onDestroy () { } 59 | 60 | 61 | /** 62 | * Called as part of the activity lifecycle when an activity is going into 63 | * the background, but has not (yet) been killed. 64 | */ 65 | @Override public void onPause () { } 66 | 67 | /** 68 | * Called after {@link #onStop} when the current activity is being 69 | * re-displayed to the user (the user has navigated back to it). 70 | */ 71 | @Override public void onRestart () { } 72 | 73 | 74 | /** 75 | * Called after {@link #onRestart}, or {@link #onPause}, for your activity 76 | * to start interacting with the user. 77 | */ 78 | @Override public void onResume () { 79 | resetSystemUiVisibility(); 80 | } 81 | 82 | 83 | /** 84 | * Called after {@link #onCreate} — or after {@link #onRestart} when 85 | * the activity had been stopped, but is now again being displayed to the 86 | * user. 87 | */ 88 | @Override public void onStart () { 89 | resetSystemUiVisibility(); 90 | } 91 | 92 | /** 93 | * Called when the activity is no longer visible to the user, because 94 | * another activity has been resumed and is covering this one. 95 | */ 96 | @Override public void onStop () { } 97 | 98 | public static void resetSystemUiVisibility(){ 99 | Handler handler = new Handler(); 100 | Runnable runnable = new Runnable(){ 101 | public void run() { 102 | if(currentMode == null) return; 103 | if(currentMode.equals("lowProfile")) { 104 | _setLowProfile(); 105 | } else if(currentMode.equals("immersive")) { 106 | _setImmersive(); 107 | } else if(currentMode.equals("statusBarColor")) { 108 | _setStatusBarColor(-1); 109 | } 110 | } 111 | }; 112 | handler.postDelayed(runnable, DELAY_TIME); 113 | } 114 | 115 | /////////////////////////////////////////////////////////////////////////// 116 | // Immersive Modes Available 117 | /////////////////////////////////////////////////////////////////////////// 118 | 119 | private static void _setLowProfile(){ 120 | ::if (ANDROID_TARGET_SDK_VERSION >= 19):: 121 | if(Build.VERSION.SDK_INT >= 15) { 122 | // enable low profile in api 15 devices 123 | View decorView = mainActivity.getWindow().getDecorView(); 124 | decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 125 | } 126 | ::end:: 127 | } 128 | 129 | /////////////////////////////////////////////////////////////////////////// 130 | 131 | private static void _setImmersive(){ 132 | ::if (ANDROID_TARGET_SDK_VERSION >= 19):: 133 | boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); 134 | boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME); 135 | if(Build.VERSION.SDK_INT >= 19) { 136 | // devices with immersive mode 137 | View decorView = mainActivity.getWindow().getDecorView(); 138 | decorView.setSystemUiVisibility( 139 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 140 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 141 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 142 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 143 | | View.SYSTEM_UI_FLAG_FULLSCREEN 144 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 145 | } 146 | else if (hasBackKey && hasHomeKey && Build.VERSION.SDK_INT >= 16) { 147 | // no navigation soft keys, unless it is enabled in the settings 148 | View decorView = mainActivity.getWindow().getDecorView(); 149 | decorView.setSystemUiVisibility( 150 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 151 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 152 | | View.SYSTEM_UI_FLAG_FULLSCREEN 153 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 154 | | View.SYSTEM_UI_FLAG_LOW_PROFILE); 155 | } 156 | else if(Build.VERSION.SDK_INT >= 15) { 157 | // enable low profile in api 15 devices 158 | View decorView = mainActivity.getWindow().getDecorView(); 159 | decorView.setSystemUiVisibility( 160 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 161 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 162 | | View.SYSTEM_UI_FLAG_FULLSCREEN 163 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 164 | | View.SYSTEM_UI_FLAG_LOW_PROFILE); 165 | } 166 | ::end:: 167 | } 168 | 169 | /////////////////////////////////////////////////////////////////////////// 170 | 171 | private static void _setStatusBarColor(final int color){ 172 | ::if (ANDROID_TARGET_SDK_VERSION >= 21):: 173 | if(Build.VERSION.SDK_INT >= 21) { 174 | try{ 175 | Window window = Extension.mainActivity.getWindow(); 176 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 177 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 178 | if(color!=-1) window.setStatusBarColor(color); 179 | }catch(Exception e) { 180 | Log.i("EXTENSION-ANDROID-IMMERSIVE", "Exception: "+e.toString()); 181 | } 182 | } 183 | ::end:: 184 | } 185 | 186 | /////////////////////////////////////////////////////////////////////////// 187 | // PUBLIC INTERFACE 188 | /////////////////////////////////////////////////////////////////////////// 189 | 190 | public static void setLowProfile(){ 191 | currentMode = "lowProfile"; 192 | Extension.mainActivity.runOnUiThread(new Runnable() { 193 | public void run() { 194 | _setLowProfile(); 195 | } 196 | }); 197 | } 198 | 199 | /////////////////////////////////////////////////////////////////////////// 200 | 201 | public static void setImmersive(){ 202 | currentMode = "immersive"; 203 | Extension.mainActivity.runOnUiThread(new Runnable() { 204 | public void run() { 205 | _setImmersive(); 206 | } 207 | }); 208 | } 209 | 210 | /////////////////////////////////////////////////////////////////////////// 211 | 212 | public static void setStatusBarColor(final int color){ 213 | currentMode = "statusBarColor"; 214 | Extension.mainActivity.runOnUiThread(new Runnable() { 215 | public void run() { 216 | _setStatusBarColor(color); 217 | } 218 | }); 219 | } 220 | 221 | /////////////////////////////////////////////////////////////////////////// 222 | 223 | } 224 | --------------------------------------------------------------------------------