I am making an application,and have access to system permissions.
I want to make the navigation bar hide permanently,
It should not appear even on user interaction.
Now i'm using this piece of code,
it hides the bar but when user touches the screen it showing again. is there any way to hide it permanently until activity onStop();
protected void hideBottomUIMenu() {
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
Window _window = getWindow();
WindowManager.LayoutParams params = _window.getAttributes();
params.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE;
_window.setAttributes(params);
}
}
Any technical advice or comments/suggestions on the best implementation would be hugely appreciated.
I hope this might be helpful for you. Also look at this
Related
Goal
I'm trying to hide status bar and make content appear behind it.
What I have tried
On the phone I'm currently developing (Samsung Galaxy S9+), I managed to make it work with this function
public static void removeAndroidNavBar(View view){
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
view.setSystemUiVisibility(uiOptions);
}
which is called on the OnCreate() method after SetContentView() like this
removeAndroidNavBar(getWindow().getDecorView());
Problem
HOWEVER, I run the code on a OnePlus Nord 2 which is on OxygenOs, and this doesn't work. The status bar is not displayed (there is a black space instead), but I can't figure out how to make it disappear completely, and make content appear behind it.
The doc
As the documentation says HERE,
On Android 4.1 and higher, you can set your application's content to appear behind the status bar, so that the content doesn't resize as the status bar hides and shows. To do this, use SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. You may also need to use SYSTEM_UI_FLAG_LAYOUT_STABLE to help your app maintain a stable layout.
which is what I'm doing, and I'm encountering the problem only on the One Plus Nord 2 device
What am I doing wrong?
If you wants to achieve some thing like this
try like this:-
fun Activity.makeStatusBarTransparent() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
// addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(hasImmersive(context)){
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
}else {
// decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
// View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
// View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
// View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
if (Build.VERSION.SDK_INT >= 21) {
var window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// window.setStatusBarColor(context.getResources().getColor(color));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
var decor = getWindow().getDecorView();
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
/* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val controller = getWindow().insetsController
controller?.systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
controller?.hide(WindowInsets.Type.statusBars())
}*/
}
} else {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
statusBarColor = Color.TRANSPARENT
}
}
Log.d("Has onscreen Navigation"," "+hasImmersive(context))
} catch (e: Exception) {
}
}
In an activity I can hide the titlebar using the following code, but when the Activity is started freeform multiwindow mode the title bar appears with x and multiwindow icon. How to hide the titlebar in freeform multiwindow mode ?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
final WindowInsetsController insetsController = getWindow().getInsetsController();
if (insetsController != null) {
insetsController.hide(WindowInsets.Type.statusBars());
}
} else {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
);
}
i have an activity which contains a Video View from YouTube and we want that when someone rotate phone , toolbar should hide . actually we have rotation lock in our app , so no activity can get rotate except this video containing activity . and i am rotating screen using onConfigurationChange .
i have implmented custom toolbar in that activity and when configuration change and code changes position of screen it should get hide or show , but it is not working .
i am using this code to hide toolbar
getSupportActionbar.hide()
well , i have some doubts about this that why does it is not working :
1 . first when configuration changes , activity creates from the scratch so command for hide toolbar gets overwrite and shoes
2 . i saw somewhere that getSupportActionbar.hide() should come before , setContentView()
here is the code snippet of onConfigurationChange
#Override
public void onConfigurationChanged(Configuration newConfig) {
try {
super.onConfigurationChanged(newConfig);
int accelometerState = android.provider.Settings.System.getInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0);
if (accelometerState == 1) {
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// toolbar.setVisibility(View.GONE);
// getSupportActionBar().hide();
isRotate = true;
}
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// toolbar.setVisibility(View.VISIBLE);
// getSupportActionBar().show();
isRotate = false;
}
} else {
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
} catch (Exception ex) {
Log.e("home", "something went wrong in the VideoViewFullScreen.java");
}
}
i am trying to figure out what is the problem here ,
if anyone has some solution or suggestion i appreciate them .
Thank You in advance
Well in this case you can define a separate layout for the landscape mode using orientation qualifiers in the layout resource files. Learn more.
I cannot find a way to disable quick settings tile in Android programmatically that is a requirement for our enterprise launcher.
Are there any clues beyond the How to disable the notification bar pull-down in Android? and https://e2e.ti.com/support/embedded/android/f/509/t/283260
Is it possible to do? Thanks!
May you start your app in the full screen mode?
like explained here: https://stackoverflow.com/a/8470893/2801860
<activity
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
....
>
Yes you can do it. I had used the following snippet to disable quick settings.
public static void preventStatusBarExpansion(Context context) {
WindowManager manager = ((WindowManager) context.getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE));
Activity activity = (Activity)context;
WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
int result = 0;
if (resId > 0) {
result = activity.getResources().getDimensionPixelSize(resId);
}
localLayoutParams.height = result;
localLayoutParams.format = PixelFormat.TRANSPARENT;
customViewGroup view = new customViewGroup(context);
manager.addView(view, localLayoutParams);
}
Call this method where ever you need. Before calling this method make sure you has screen overlay permission.
However this permission is deprecated in Oreo.
It seems is impossible to do at all.
That is the answer.
No, not impossible. Use ACTION_CLOSE_SYSTEM_DIALOGS to prevent it be pulled down when the screen is locked.
I'm using Immersive Mode in my app when it's running on Android 4.4+. (http://developer.android.com/training/system-ui/immersive.html)
My activity indeed shows in full screen, and I work around the volume key pressing by using setOnSystemUiVisibilityChangeListener. I also have similar code for putting dialogs into immersive mode.
However, when a dialog is shown, the nav. bars jump on the screen and then retreat immediately. When the dialog is dismissed it's even worse - the nav. bars jump and resize the activity behind.
The following is my class for supporting immersive mode. It is simply called on each Activity's onResume and also a separate function is called when building each dialog.
Did I miss any flag or callback, or is it a known Android issue?
public class ImmersiveModeHelper {
public ImmersiveModeHelper(Activity activity)
{
mActivity = activity;
}
#SuppressLint("NewApi")
public void supportFullScreenImmersiveMode()
{
MyLog.d("ImmersiveModeHelper: supportFullScreenImmersiveMode: ");
// Support full-screen immersive mode on Android 4.4 and up
if (Build.VERSION.SDK_INT >= 19)
{
// Get the needed flags by reflection and use them
try
{
final int immersiveFlag = View.class.getField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY")
.getInt(null);
final int hideNavigationFlag = View.class
.getField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
final int fullScreenFlag = View.class.getField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(
null);
// Set the flags to the window decor view
mActivity.getWindow().getDecorView()
.setSystemUiVisibility(immersiveFlag | hideNavigationFlag | fullScreenFlag);
// Set a callback to be called when visibility changes
// (workaround
// for volume keys)
mActivity
.getWindow()
.getDecorView()
.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener()
{
#Override
public void onSystemUiVisibilityChange(int visibility)
{
MyLog.d("ImmersiveModeHelper.supportFullScreenImmersiveMode().new OnSystemUiVisibilityChangeListener() {...}: onSystemUiVisibilityChange: " +
"");
if ((visibility & (immersiveFlag | hideNavigationFlag)) == 0)
{
Handler uiHandler = UiThreadUtils.getUiHandler();
uiHandler.removeCallbacks(mHideSystemUiCallback);
uiHandler.postDelayed(mHideSystemUiCallback,
HIDE_SYSTEM_UI_DELAY_MILLI);
}
}
});
} catch (Exception e)
{
e.printStackTrace();
MyLog.e("ImmersiveModeHelper: supportFullScreenImmersiveMode: couldn't support immersive mode by reflection");
}
} else
{
MyLog.i("ImmersiveModeHelper: supportFullScreenImmersiveMode: not supported on this platform version");
}
}
public static void supportFullScreenImmersiveModeForDialog(final Dialog dlg)
{
MyLog.d("ImmersiveModeHelper: supportFullScreenImmersiveModeForDialog: ");
// Support full-screen immersive mode on Android 4.4 and up
if (Build.VERSION.SDK_INT >= 19)
{
final Window dlgWindow = dlg.getWindow();
// Get the needed flags by reflection and use them
try
{
final int immersiveFlag = View.class.getField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY")
.getInt(null);
final int hideNavigationFlag = View.class
.getField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
final int fullScreenFlag = View.class.getField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(
null);
// Set the flags to the window decor view
int flags = dlgWindow.getDecorView().getSystemUiVisibility();
flags |= (immersiveFlag | hideNavigationFlag | fullScreenFlag);
dlgWindow.getDecorView().setSystemUiVisibility(flags);
// Set a callback to be called when visibility changes
// (workaround for volume keys)
dlgWindow.getDecorView().setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener()
{
#Override
public void onSystemUiVisibilityChange(int visibility)
{
MyLog.d("ImmersiveModeHelper.supportFullScreenImmersiveModeForDialog(...).new OnSystemUiVisibilityChangeListener() {...}: onSystemUiVisibilityChange: ");
if ((visibility & (immersiveFlag | hideNavigationFlag)) == 0)
{
Runnable hideSystemUiCallback = new Runnable()
{
#Override
public void run()
{
supportFullScreenImmersiveModeForDialog(dlg);
}
};
Handler uiHandler = UiThreadUtils.getUiHandler();
uiHandler.removeCallbacks(hideSystemUiCallback);
uiHandler.postDelayed(hideSystemUiCallback,
HIDE_SYSTEM_UI_DELAY_MILLI);
}
}
});
} catch (Exception e)
{
e.printStackTrace();
MyLog.e("ImmersiveModeHelper: supportFullScreenImmersiveMode: couldn't support immersive mode by reflection");
}
} else
{
MyLog.i("ImmersiveModeHelper: supportFullScreenImmersiveMode: not supported on this platform version");
}
}
private Activity mActivity;
private Runnable mHideSystemUiCallback = new Runnable()
{
#Override
public void run()
{
supportFullScreenImmersiveMode();
}
};
private static final int HIDE_SYSTEM_UI_DELAY_MILLI = 0;
}
From the Google API:
It's good practice to include other system UI flags (such as SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION and SYSTEM_UI_FLAG_LAYOUT_STABLE) to keep the content from resizing when the system bars hide and show.
You should also make sure that the action bar and other UI controls are hidden at the same time. This snippet demonstrates how to hide and show the status and navigation bars, without resizing the content:
// This snippet hides the system bars.
private void hideSystemUI() {
// Set the IMMERSIVE flag.
// Set the content to appear under the system bars so that the content
// doesn't resize when the system bars hide and show.
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
// This snippet shows the system bars. It does this by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
Hope this helps.
In Dialog or BottomSheetDialogFragment you have to implement this solution which is work for me.
Step 1:
In your dialog or BottomSheetDialog, write this code in onActivityCreated method,
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var viewParent = view
while (viewParent is View) {
viewParent.fitsSystemWindows = false
viewParent.setOnApplyWindowInsetsListener { _, insets -> insets }
viewParent = viewParent.parent as View?
}
}
Step 2:
Also, override the below method :
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
dialog?.window?.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
Now see the magic :)
What worked for me was adding the following to the parent layout xml:
android:fitsSystemWindows="true"
I fixed this by setting my flags on onWindowFocusChanged() rather than onResume() as per https://developer.android.com/training/system-ui/navigation.
The problem is the full screen popup resets the SYSTEM_UI flags. Tested and works.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// Before setting full screen flags, we must wait a bit to let UI settle; otherwise, we may
// be trying to set app to immersive mode before it's ready and the flags do not stick
long IMMERSIVE_FLAG_TIMEOUT = 500L;
int FLAGS_FULLSCREEN = (View.SYSTEM_UI_FLAG_LOW_PROFILE |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
mFullView.postDelayed(() -> mFrameLayout.setSystemUiVisibility(FLAGS_FULLSCREEN),
IMMERSIVE_FLAG_TIMEOUT);
}
I think you can also follow the new guidelines in https://developer.android.com/training/system-ui/immersive. I have not tested it though.
private fun hideSystemBars() {
val windowInsetsController =
ViewCompat.getWindowInsetsController(window.decorView) ?: return
// Configure the behavior of the hidden system bars
windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide both the status bar and the navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
}