Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Allegro 5, Android, Immersive mode, keyboard

This thread is locked; no one can reply to it. rss feed Print
Allegro 5, Android, Immersive mode, keyboard
Ian Lewis
Member #15,817
December 2014

I have an A5 game which runs under Android. It makes occasional use of the Android 'soft' keyboard, which I pop up and down using the code from here:

https://wiki.allegro.cc/index.php?title=Running_Allegro_applications_on_Android#Show_the_keyboard_programmatically

This works fine, except when combined with 'Immersive mode' (where the navigation and status bars are hidden) In this case, the nav bar reappears when the keyboard pops up, but doesn't disappear again when the keyboard is closed.

Googling this suggests it's not an Allegro-specific problem, but the suggested solutions generally involve adding code, or at least a function call to OnCreate(), which I don't seem to have access to. (e.g. https://stackoverflow.com/questions/21164836/immersive-mode-navigation-becomes-sticky-after-volume-press-or-minimise-restore/21278040#21278040 )

The code I use to enable immersive mode is this:

#SelectExpand
1 @Override 2 public void onWindowFocusChanged(boolean hasFocus) { 3 View decorView = this.getWindow().getDecorView(); 4 super.onWindowFocusChanged(hasFocus); 5 if (hasFocus) { 6 decorView.setSystemUiVisibility( 7 View.SYSTEM_UI_FLAG_LAYOUT_STABLE 8 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 9 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 10 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 11 | View.SYSTEM_UI_FLAG_FULLSCREEN 12 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 13 } 14 }

which enables immersive mode when the focus changes, so if after I close the keyboard, I then switch to the home screen and back to my app, then the nav bar is gone. If I try to call a similar function, either from the keyboard closing function, or from my C code using the same process as I use for the keyboard, then the app crashes with either a SIGSEGV or SIGABRT signal.

So, does anyone have a good solution to this? Any bright ideas? Any idea why decorView.setSystemUiVisibility() works in onWindowFocusChanged(), but crashes in my function?

Cheers,

Ian.

Elias
Member #358
May 2000

What if you call it from your CloseKeyBoard() method?

--
"Either help out or stop whining" - Evert

beoran
Member #12,636
March 2011

If immersive mode isn't already in Allegro5 proper, it should be. I think there is an issue on github about it. Displaying an on screen keyboard sound also like something Allegro should do for you. I suggest we incorporate it somehow.

Ian Lewis
Member #15,817
December 2014

Elias said:

What if you call it from your CloseKeyBoard() method?

Tried that. It crashes :-( In fact, any time I call setSystemUiVisibility() from 'my' code, it crashes. The only way I could get Immersive Mode to work was to use the functionmethod above, which (if I understand right) replaces an existing method (part of allegro, or android, I don't know which) and which I never call - it's called automagically when the window focus changes.

I don't know if that's the difference, or if it is, what I can do about it.

I do know that if I breakpoint on 'my' onWindowFocusChanged() and on my HideNavBar() method (with identical code in) then 'this' and 'decorView' have the same values, but as soon as I step over setSystemUiVisibility() in one case it hides the bars, in the other case it crashes. I have looked in logcat, but it didn't make much sense to me. Maybe I'll have another go at figuring it out.

In case it's not clear from the above, I don't know much about android, or Java...

beoran: sounds good to me. Happy to help test it, but I'm not sure I can contribute much to creating it.

Cheers,

Ian.

Elias
Member #358
May 2000

I just tried it and it's quite simple - you can only modify the View from the main thread. So add this to the end of your CloseKeyboard method:

#SelectExpand
1 new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { 2 @Override 3 public void run() { 4 5 6 View decorView = getWindow().getDecorView(); 7 decorView.setSystemUiVisibility( 8 View.SYSTEM_UI_FLAG_LAYOUT_STABLE 9 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 10 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 11 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 12 | View.SYSTEM_UI_FLAG_FULLSCREEN 13 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 14 15 }}, 100);

Basically use postDelayed() which will execute on the main thread instead of executing it directly.

--
"Either help out or stop whining" - Evert

Ian Lewis
Member #15,817
December 2014

Ah, thank you so much! Works perfectly now :-)

For the benefit of anyone else trying this with as little android knowledge as me, I needed to add:

import android.os.Handler;
import android.os.Looper;

at the top of MainActivity.java as well.

Thanks again,

Ian.

Go to: