corona
corona copied to clipboard
display.safeAreaInsets does not detect soft navigation bar on Android 10+
A typical business app on Android sits above the software defined navigation bar at the bottom of the screen.
Actual result: When running Android 10+ on the Google Pixel 3, display.safeAreaInsets does not take into account the bottom soft navigation bar. As a result, the app UI is blocked by the navigation bar.
Expected result: display.safeAreaInsets should account for the bottom soft navigation bar because it is NOT a safe area to place UI elements.
This issue is only evident when testing on the device itself and cannot be reproduce in the Corona simulator.
Is this still an issue after release 2020.3619?
Is this still an issue after release 2020.3619?
I think, unfortunately, it is. This needs fixing. I thing currently safe area apis only try to account for screen bezels. Software elements on android are ignored. This is not how it supposed to be.
Under the hood, Solar2d uses DisplayCutouts Android class to compute safe area, this class is merely about notches in display, thats why it works correctly for top camera notch but not for bottom inset where it returns 0 always. No notch there, no display cutouts.
displayCutout() is only about display cut outs , it, by definition, doesn't take into account navigation or status bar. Currently Solar2d uses DisplayCutout class to determine safe area for android.
Instead, the intended way to get system bars insets is using WindowInsets.
This gives a tuple with the insets:
Insets insets = WindowInsets.getInsets(Type.systemBars ())
insets.bottom will be the nav bar and insets.top will be top status bar
if additionally we want a new stand-alone API for navigation bar height only then:
Insets insets = WindowInsets.getInsets(Type.navigationBars ())
return insets.bottom
References:
Something new: https://forums.solar2d.com/t/height-of-android-navigation-bar-solved/353073
The next step is to understand when this navbar is on and when not. We need some kind of flag in order to determine the presence of a software navigation panel.
As I said, instead of this work around, the official way ( According to Google engineer ) is using this:
Insets insets = WindowInsets.getInsets(Type.navigationBars ())
return insets.bottom
it covers all cases: nav bar keys, nav gesture bar, all according to whatever user chose in his device settings as navigation mechanism, or even no bar at all and just physical keys.
Hey guys. So I made a build and trying to test this stuff... Android system ui visibility/status bar/safety insets are stupid topic, because you touch one everything crumbles.
So I made some changes, and it seems rather OK from the first glance, I would really appreciate help in testing.
Here is my main.lua I'm testing with. And to test replace contents of Native/Corona/android/lib/gradle
with this aar.
P.S. WindowInsets.getInsets(Type.navigationBars ())
is all good and fine, but starts to work only in Android 11 (we are not there yet)
Thanks Vlad,
True getInsets(Type.navigationBars ())
is from API 30,
from API 20 to 30 it's getSystemWindowInsetBottom()
Also regarding "touch one everything crumbles", that's why I suggested maybe adding a new API that merely returns the value of getSystemWindowInsetBottom()
, those who want to take the bottom software bars into account call it.
#220
We already have apis for this: display.getSafeAreaInsets() And convenience APIs to make usage easier: display.safeScreenOriginX display.safeScreenOriginY display.safeActualContentWidth display.safeActualContentHeight I think everything should work at this point. Please test and tell me if something isn't working out.
Please
I know we have this API display.getSafeAreaInsets()
, but it relies on a native android API that counts for physical notches only and not software bars.
Of course the best solution is to make it add software bars into account too.
But since this, as you suggested, breaks other thing. I suggested an additional API that directly maps to Android API that returns navbars hieght, to keep backward API display.getSafeAreaInsets compatible.
but if u decided to fix getSafeAreaInsets() then it's better.
does it now use getSystemWindowInsetBottom
inside getSafeAreaInsets
Update: I tried the version you uploaded
Unfortunately, it still doesn't work.
display.setStatusBar( display.HiddenStatusBar )
local sceneGroup = self.view
local CENTER = { x = display.contentWidth/2, y = display.contentHeight/2 }
local H = display.contentHeight
local W = display.contentWidth
local greenBG = display.newRect(sceneGroup,CENTER.x,CENTER.y,W,H)
greenBG:setFillColor(0,0.4,0)
local topInset, leftInset, bottomInset, rightInset = display.getSafeAreaInsets()
local blueSafeArea = display.newRect(sceneGroup,CENTER.x,CENTER.y,W,H-topInset-bottomInset)
blueSafeArea:setFillColor(0,0,0,0)
blueSafeArea:setStrokeColor(0,0,1)
blueSafeArea.strokeWidth=8
local info = display.newText{
parent = sceneGroup,
x = CENTER.x,
y = CENTER.y,
fontSize=50,
text=
"topInset = ".. math.floor(topInset)
.."\nbottomInset = "..math.floor(bottomInset)
.."\ncontentHeight="..math.floor(display.contentHeight)
.."\nActualContentHeight="..math.floor(display.actualContentHeight)
.."\nsafeActualContentHeight="..math.floor(display.safeActualContentHeight)
}
The problem remains that bottomInset
is zero
Hey, @Earnes-Tg, may I ask you to run the project I provided here: https://gist.githubusercontent.com/Shchvova/28c8e067bb80555cd2db433a07bb4d95/raw/6d909ae78e75c24bc72eaee9fea4181995c4b4e6/main.lua
Run
@Shchvova , sure
02-05 10:52:05.775 27273 13481 I Corona : -0 -0 400 888
02-05 10:52:05.795 27273 13481 I Corona : 0 25 400 863
02-05 10:52:05.798 27273 13481 I Corona : 25 0 0 0
As you can see, it shows "bottom inset" is zero , and safeActualContentHeight is just hieght minus notch are at top.
Did you utilize getSystemWindowInsetBottom
inside getSafeAreaInsets
?
Yes. Here's code which retrieves insets: https://github.com/Shchvova/corona/blob/fe67e75af2a6f340123c769496990e667beaf701/platform/android/sdk/src/com/ansca/corona/NativeToJavaBridge.java#L1567-L1576 You can try without stable insets here.
Would you like to do some debugging? It is not that complicated how to do it, if you want I can guide you through it, in Discord with voice chat and screen sharing if you want to.
EDIT: also, try changing system UI visibility, those texts are buttons.
-
Yeah no problem, let's arrange that, Monday ?
-
I looked at the code thanks. seem the one without stable insets to be the way to go but still it doesn't work.
I did "git clone" and have Corona in local directory. is there a command that generates Corona.aar to test something real quick
I created a demo Android App to make sure I understood how Android handles this. I've managed to get it report bottom inset correctly.
Here's what I concluded, and might help us get close to the the solution.
When in default mode visiblity ( not the immersive ) we have to use two flags that will make it return bottom inset correctly, without them bottom inset always returns zero.
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
I set this in OnCreate()
Now for Corona: Maybe you can set them in file:
corona/platform/android/sdk/src/com/ansca/corona/Controller.java
inside function
void setSystemUiVisibility(final String visibility)
replace this:
} else if (visibility.equals("default")) {
// Clear all flags
vis = 0x00000000;
with this:
} else if (visibility.equals("default")) {
// Clear all flags
vis = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
if you can, build an aar for me with this change ( without the stable you mentioned above ! )
If you have android studio it is rather easy to do it yourself. It is described here: https://github.com/coronalabs/corona/tree/master/platform/android#how-to-build-coronas-android-software But in short, you can do it in severals steps:
- Clone with recursive flag:
git clone --recursive https://github.com/coronalabs/corona.git
- Put your project into new
platform/test/assets2
directory, so you'll haveplatform/test/assets2/main.lua
<- this would be a launch project - Drag&Drop
platform/android
directory onto Android Studio to open it, and press Play button to build. Do not update plugin as Studio suggests, but do install NDK 18, it is required to build the AAR. Build can take 5-20 minutes depending on your hardware. Incremental build take seconds. First time is a long one though. - That's that. You can debug stuff by putting breakpoints and pressing Debug button 🐞.
Using the version Vlad sent me, I've got this in Solar2d, It meets my requirements.
https://user-images.githubusercontent.com/4797458/108200723-88ef9d00-7127-11eb-8022-852029f646b3.mp4
You can see it works for:
- soft keys mode
- gesture mode
- immersive mode. for my various apps/uses cases it works.
is that already available in the latest solar2d build?
When it will be available in general build?
The changes weren't accepted by Vlad. I've researched this at the time and provided my insight. it worked for soft keys and gesture mode and immersive mode where bottom inset was 90,15,0 respectively I placed admob banner with y=bottomInset and looked great
Hello. Any updates on getting this fix into a general build @Shchvova ?
I'm also building a general purpose app, and am facing the same issue with the bottom navigation bar. Thank you.
Hi, any update on that?
This is fixed with 2022.3681+
Awesome!!! Thanks. I will check it out.
Regarda
W dniu niedz., 16.10.2022 o 04:35 Scott Harrison @.***> napisał(a):
Closed #46 https://github.com/coronalabs/corona/issues/46 as completed.
— Reply to this email directly, view it on GitHub https://github.com/coronalabs/corona/issues/46#event-7595767954, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABODERNDWIPKG3KWQ67DWNLWDNSWTANCNFSM4LWAAV7A . You are receiving this because you commented.Message ID: @.***>
-- Pozdrawiam Maciej Czekała