Android setSystemUiVisibility consecutive calls don't work - android

In my app, the user can go into fullscreen mode. In that mode, whenever the user touches the screen it will toggle the system ui visibility.
If the ui is hidden then two touches occur within about 1 second of each other (a long time in the real world), the ui is shown properly, but the navigation bar is not hidden again. This is despite view.setSystemUiVisibility() being called with the correct flags to hide it.
The view in question is activity.getWindow().getDecorView().
Waiting 1.5 seconds or more before the second touch correctly hides the system ui.
Flags:
private static final int STATIC_LAYOUT_FLAGS =
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
private static final int HIDDEN_FLAGS =
STATIC_LAYOUT_FLAGS |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
Again, to clarify, this is the expected behaviour:
Status bar and navigation bar are hidden to begin with
A screen touch shows the status bar and navigation bar
A second screen touch hides the status bar and navigation bar
If the time in between steps (2) and (3) is less than about 1 second, the navigation bar does not correctly hide (but the status bar does). In this case, the flag SYSTEM_UI_FLAG_HIDE_NAVIGATION is not set, despite it being part of the arguments sent to setSystemUiVisibility().
Adding debug statements causes enough delay that the bad behaviour does not manifest anymore.
Why? How can I fix this?

I've faced the same problem: https://stackoverflow.com/a/32800094/4449456 and found the root cause. It's protection against application that could lock device in the fullscreen mode. So navigation bar will be shown every time user clicks on screen and the system will skip your setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) for a 1000 ms.

Related

When Android automatically exits Immersive Sticky it does not resize views so they are blocked

I have an activity which can go to Immersive Sticky Full Screen on the click of the button. This button does the following code in order to get into Immersive Sticky Full Screen.
getActivity().getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
Note: I specifically do NOT include the following tag as if I do, it breaks the layout of my screen when I exit Immersive Sticky Full Screen.See my other question: Android closing full screen view at the bottom is shunted off the screen
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
When Android is in Immersive Sticky Full Screen when another view is displayed, such as a DialogFragment, a AlertDialog, keyboard comes up, Android automatically takes you out of Immersive Sticky Full Screen by showing the Status Bar and on screen navigation bar. However it does NOT resize the views in my application, so now my views are underneath the navigation bar and I can not get to any of the buttons at the bottom of my screen. I have tested with the "View.SYSTEM_UI_FLAG_LAYOUT_STABLE" flag and it makes no difference, the views are still not resized.
This seems a massive flaw in Android's behavior and surely I am doing something wrong. How can I get it to resize my views when it displays the status bar and Navigation bar?
I can work around some cases, such as Dialogs popping up by using the code in the following SO question, https://stackoverflow.com/a/24549869/2663916 but I have lots of possible things that could popup on my full screen view and I don't want to have to put that hack in every single place to keep it in immersive full screen. Furthermore, when the keyboard comes up I DO want the navigation bar to appear.
Surely Android should adjust the on screen views when it is displaying the on screen bars.
Re-reading Google docs made it obvious that the cause was the inclusion of the following two flags
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // this STOPS Android resizing my view to be below the status bar when it is displayed
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION // this STOPS Android resizing my view to be above the nav bar when it is displayed
https://developer.android.com/training/system-ui/immersive.html
"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. "

full screen app: stuck navigation bar

I wrote an app that is composed by a full screen webkit object. So, as soon as the activity starts, i set these flags:
SYSTEM_UI_FLAG_LAYOUT_STABLE
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
SYSTEM_UI_FLAG_HIDE_NAVIGATION
SYSTEM_UI_FLAG_FULLSCREEN
SYSTEM_UI_FLAG_IMMERSIVE
Problem is that when i swap down from the top border of the screen, status bar and navigation bar becomes visible (and this is ok, so you can close the app if you need it). Problem is that, after a few seconds, status bar goes away while navigation bar doesn't. It stucks there. Is there a flag I am missing? Or is there any hook I can use to detect when the status bar hides and then set back the flags?

Android hide action bar, status bar and navigation controls

I am trying to make an activity that is completely fullscreen in landscape, and have the status bar and navigation buttons visible in portrait.
I have to be able to do this programatically.
This is how I tried make the app go fullscreen.
private void hideNavigationAndStatusBars(){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); // these work only on API 21 and above
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
The problems are the following :
On some devices, I get a blank portion on the top of the screen, that is equal to the height of the status bar, even though the status bar is not showing
On other devices, the activity fills the whole screen, but when I click anything, the status bar and navigation bar appear, they resize the layout and it looks very ugly
What I am trying to achieve:
The activity should fill the whole screen in landscape, positioned behind the status bar and navigation bar, if they appear
When the user clicks on the screen, he/she should interact with the screen. Instead the first click displays the status and navigation bars and the interaction is possible only after this
The status bar should only appear when the user drags from the top
to hide action bar call getActionBar().hide() method.
And to make activity full screen call
this method
requestFeature(Window.FeatureNo_Title)
Use immersive mode and system ui stable flag to achieve this. For more information please refer the document in developer site.

Overlay status bar and system button bar in full screen mode

I want to write an app with overlay status bar and system button bar like below picture. I tried
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_FULLSCREEN;
but it when status bar and system button bar appear, they come with two black bars. Can anyone help me?
Image
Documentation:
The figure below illustrates the different "immersive mode" states:
Situation 4 - Sticky flag This is the UI you see if you use the IMMERSIVE_STICKY flag, and the user swipes to display the system bars. Semi-transparent
bars temporarily appear and then hide again. The act of swiping
doesn't clear any flags, nor does it trigger your system UI visibility
change listeners, because the transient appearance of the system bars
isn't considered a UI visibility change.
https://developer.android.com/training/system-ui/immersive.html

Android Tablet - hiding/displaying of status bar on touch

I have been searching high and low how to hide the status bar on the Android tablet.
I know it is not possible to do so unless you root the tablet.
The main pain I have is when I write on my App, the wi-fi section pops-up.
I know of the flags View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or SYSTEM_UI_FLAG_LOW_PROFILE
that hide navigation / dim navigation.
What I need is :
There is a feature in the the Gallery Application (in-built in android) that lets you traverse through the images and only pops the navigation on single touch and hides on single touch. No other gesture triggers this bar.
I need some way to implement something similar.
I'd be much obliged if someone can point me in the right direction.
Details :
Tablet :Samsung Galaxy Note 10.1
Android Version : 4.1.2
Actually in the Tablets with 4+ Android versions there is not possible to hide it, but you can try to do it like this:
The SYSTEM_UI_FLAG_LOW_PROFILE flag replaces the STATUS_BAR_HIDDEN flag. When set, this flag enables “low profile" mode for the system bar or navigation bar. Navigation buttons dim and other elements in the system bar also hide. Enabling this is useful for creating more immersive games without distraction for the system navigation buttons.
The SYSTEM_UI_FLAG_VISIBLE flag replaces the STATUS_BAR_VISIBLE flag to request the system bar or navigation bar be visible.
The SYSTEM_UI_FLAG_HIDE_NAVIGATION is a new flag that requests the
navigation bar hide completely. Be aware that this works only for the
navigation bar used by some handsets (it does not hide the system bar
on tablets). The navigation bar returns to view as soon as the system
receives user input. As such, this mode is useful primarily for video
playback or other cases in which the whole screen is needed but user
input is not required. You can set each of these flags for the system
bar and navigation bar by calling setSystemUiVisibility() on any view
in your activity. The window manager combines (OR-together) all flags
from all views in your window and apply them to the system UI as long
as your window has input focus. When your window loses input focus
(the user navigates away from your app, or a dialog appears), your
flags cease to have effect. Similarly, if you remove those views from
the view hierarchy their flags no longer apply.
Another solution that I found was to ser the view of your layout like this:
yourView.setSystemUiVisibility(8);
They say it works on tablets but I haven't really try it on.
Another one is adding this method and just pass a True or False according to what you want to show:
void setNavVisibility(boolean visible) {
int newVis = mBaseSystemUiVisibility;
if (!visible) {
newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN;
}
final boolean changed = newVis == getSystemUiVisibility();
// Unschedule any pending event to hide navigation if we are
// changing the visibility, or making the UI visible.
if (changed || visible) {
Handler h = getHandler();
if (h != null) {
h.removeCallbacks(mNavHider);
}
}
// Set the new desired visibility.
setSystemUiVisibility(newVis);
mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
}

Categories

Resources