Detecting android softkeyboard show/hide events
Asked Answered
T

2

15

I am trying to detect showKeyboard and hidekeyboard events on phonegap. For that purpose, on deviceready event I placed following code:

  bindEvents: function() {
    document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
    document.addEventListener("menubutton",app.onMenuKeyPress,false);
    document.addEventListener("backbutton",navigateBack,false);
    document.addEventListener("hidekeyboard", onKeyboardHide, false);
    document.addEventListener("showkeyboard", onKeyboardShow, false);
},

Here backbuttonevent is being fired and working fine but hidekeyboard and showkeyboard events are never fired.

Also to detect it I tried to use window.onresize event, that worked in browser. Following is its code:

window.onresize = function(){
    var screenHeight = $(window).height();
    alert(screenHeight);
    var diff = screenInitialHeight - screenHeight;
    var newHeight = screenInitialHeight-diff;
    alert(newHeight);
    $('#mainpage').height(newHeight);
    $('#nav_container').height(newHeight);
}

But this code also didn't executed on show or hide keyboard. This function is only executing when first time app. is started. I saw at some places that for some people these events are working so I think there is some thing wrong from my side, probably in some config file etc. So following is androidmanifest.xml code:

    <?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="1.0.0" android:windowSoftInputMode="adjustPan" package="com.phonegap.move_custom" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name" android:largeHeap="true">
        <activity android:configChanges="keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="move_custom" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>

Please let me know if anything need to be chagned. Also if these events are working in someone's app, then please share your app. so that I can try to check configuration and code that why it isn't working in my app. All good efforts will be appreciated. Seems like I am already near but missing something. So anything you can tell will probably be helpful.

    @Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    
    if (getResources().getConfiguration().orientation == 2) {
        super.setIntegerProperty("splashscreen", R.drawable.splash);
    }
    else {
        super.setIntegerProperty("splashscreen", R.drawable.splashportrait);
    }
    
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

    super.loadUrl(Config.getStartUrl(), 3000);
}
Ternion answered 19/11, 2013 at 21:1 Comment(6)
There are no such events as hide and show keyboard (docs.phonegap.com/en/edge/cordova_events_events.md.html#Events)Maretz
if you want to detect the status of the keyboard, you need to write a custom phonegap plugin then using Java detect if the keyboard is up or down then pass it to your JavascriptMaretz
@Ard then will I need to do write similar plugin for iOS too?Ternion
@Ard isn't there any such plugin already available for that?Ternion
Also keyboard is not changing screen height, it is just overlapping it. If it will change screen height then I may be able to detect and do something accordingly. So is there any such config in android manifest so that keyboard resize window instead of just overlapping it?Ternion
Are you sure your onKeyboardShow and onKeyboardHide functions don't break your code somewhere? Could you add them to your question? I just tested on android 4.3 and it works like a charm.Grantland
G
15

Apparently showkeyboard / hidekeyboard events WILL NOT fire when you are running your app in a full-screen mode (eg. no status bar at the top) because the screen size doesn't change when the keyboard pops-up.
https://issues.apache.org/jira/browse/CB-392

If you do not want your app to run in fullscreen :

Try this first let's see if it narrows down your problem to the event firing or the function it tries to call when the event fires.

function onDeviceReady() {
    alert("Device Ready");
    document.addEventListener("showkeyboard", function(){ alert("Keyboard is ON");}, false);
    document.addEventListener("hidekeyboard", function(){ alert("Keyboard is OFF");}, false);
}

I have tested this on Android 4.2 and 4.3 worked fine on both.

Note:

To turn fullscreen off:
Remove NoTitleBar from your AndroidManifest.xml:

android:theme="@android:style/Theme.Black.NoTitleBar

And / or add these lines to the onCreate method in your MainActivity.java:

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
Grantland answered 27/11, 2013 at 15:18 Comment(5)
This is correct; fullscreen means fullscreen on Android. Your window will not shrink for the statusbar and it will not shrink for the keyboard. Phonegap relies on its window to shrink in order to detect the presence of the keyboard, so that detection will not work in fullscreen. Note also that even though the vast majority of keyboards do cause the Phonegap window to shrink when not in fullscreen, if your user employs a more unorthodox keyboard app you may still be unable to detect it. This is not something you should depend on.Paba
This isn't showing title bar of mobile device. Did both things told above.Ternion
@Ternion do you use Phonegap splashscreen? In my experience it messes with fullscreen settings. So these flags to avoid fullscreen has to be set after splashscreen shows.Grantland
Already added set after splashscreen. Also I have added my oncreate method code in question now, please check code there.Ternion
Put all the flag stuff after super.loadUrl(Config.getStartUrl(), 3000);Grantland
C
0

Using ionic-plugin-keyboard, the events native.keyboardshowand native.keyboardhide are fired, even in fullscreen / immersive Mode:

Example Code:

document.addEventListener('deviceready', 
  function(){
    // disable immersive mode  on Android when keyboard is shown
        try {
      if (cordova.platformId == 'android') {
        AndroidFullScreen.immersiveMode(false, false);
        window.addEventListener('native.keyboardshow', function (e) {
          AndroidFullScreen.showSystemUI(false, false);

        });
        window.addEventListener('native.keyboardhide', function (e) {
          AndroidFullScreen.immersiveMode(false, false);
        });
      }
    } catch (error) {
      console.log('deviceready - ' + error);
    }
}, false);
Chlorohydrin answered 21/2, 2017 at 12:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.