Search Unity

Question Keyboard height

Discussion in 'Android' started by Edgaras-Randis, Jan 14, 2015.

  1. Edgaras-Randis

    Edgaras-Randis

    Joined:
    Jul 8, 2014
    Posts:
    20
    So, TouchScreenKeyboard.area returns zero rect, anyone has a solution or plugin? Seems like an old issue.
     
  2. Edgaras-Randis

    Edgaras-Randis

    Joined:
    Jul 8, 2014
    Posts:
    20
    Ok, so this is what I got so far, works atm and it's enought for now:


    Code (CSharp):
    1. using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    2.         {
    3.             AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");
    4.          
    5.             using(AndroidJavaObject Rct = new AndroidJavaObject("android.graphics.Rect"))
    6.             {
    7.                 View.Call("getWindowVisibleDisplayFrame", Rct);
    8.              
    9.                 return Screen.height - Rct.Call<int>("height");
    10.             }
    11.         }
     
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I know this is an old thread. But its a life saver. Thanks.
     
  4. rocker182

    rocker182

    Joined:
    Jun 3, 2016
    Posts:
    3
    Can anyone elaborate on how to use this thread
     
  5. Gorlog

    Gorlog

    Joined:
    Jan 20, 2011
    Posts:
    201
    Code (CSharp):
    1.   public int GetKeyboardSize()
    2.     {
    3.         using (AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    4.         {
    5.             AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");
    6.  
    7.             using (AndroidJavaObject Rct = new AndroidJavaObject("android.graphics.Rect"))
    8.             {
    9.                 View.Call("getWindowVisibleDisplayFrame", Rct);
    10.  
    11.                 return Screen.height - Rct.Call<int>("height");
    12.             }
    13.         }
    14.     }
     
  6. aschuetzer

    aschuetzer

    Joined:
    Nov 21, 2016
    Posts:
    3
    The Code above is very helpful, but it returns only the height of keyboard, so if there an input field it will be ignored. Have someone an idea how to get the size of the additional input field?
     
  7. benbenmushi

    benbenmushi

    Joined:
    Jan 29, 2013
    Posts:
    34
    In complement to this solution, which work fine on Android.

    Has anyone found a similiar solution for iOS devices ?
     
  8. moghes

    moghes

    Joined:
    Oct 10, 2012
    Posts:
    14
    1. calling this function when the keyboard is visible but still getting 0 as a result.
      Has anyone experienced this?
     
    anhbnguyen125 and Eater_Games like this.
  9. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    642
    This code is all over the internet, but the returned value doesn't include the height of the text input box.

    Has anyone figured out how to solve that one? (without just adding a hacky constant to make it almost-work?)
     
    andersemil likes this.
  10. QuincyC

    QuincyC

    Joined:
    Jun 5, 2018
    Posts:
    10
    bump, I'd love to know this as well
     
    andersemil likes this.
  11. ProMaXoid

    ProMaXoid

    Joined:
    Jun 22, 2013
    Posts:
    3
    Code (CSharp):
    1. public static float GetKeyboardHeightRatio()
    2.     {
    3.         if (Application.isEditor)
    4.             return 0.4f;
    5.        
    6. #if UNITY_ANDROID
    7.         using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    8.         {
    9.             var view = unityClass.GetStatic<AndroidJavaObject>("currentActivity")
    10.                 .Get<AndroidJavaObject>("mUnityPlayer")
    11.                 .Call<AndroidJavaObject>("getView");
    12.            
    13.             var dialog = unityClass.GetStatic<AndroidJavaObject>("currentActivity")
    14.                 .Get<AndroidJavaObject>("mUnityPlayer")
    15.                 .Get<AndroidJavaObject>("b");
    16.            
    17.             var decorView = dialog.Call<AndroidJavaObject>("getWindow")
    18.                 .Call<AndroidJavaObject>("getDecorView");
    19.            
    20.             var height = decorView.Call<int>("getHeight");
    21.            
    22.             using (var rect = new AndroidJavaObject("android.graphics.Rect"))
    23.             {
    24.                 view.Call("getWindowVisibleDisplayFrame", rect);
    25.                 return (float) (Screen.height - rect.Call<int>("height") + height) / Screen.height;
    26.             }
    27.         }
    28. #elif UNITY_IOS
    29.         return (float) TouchScreenKeyboard.area.height / Screen.height;
    30. #endif
    31.     }
    I get dialog with EditText (in Unity 2018.2.x this is a field "b") and take the height of this dialog. This code may not work in newer versions of Unity.
     
    Last edited: Mar 20, 2019
    jhina likes this.
  12. Arshia001

    Arshia001

    Joined:
    Sep 20, 2011
    Posts:
    7
    I can confirm this still works as of Unity 2019.1.4. If someday it ceases to work (assuming they don't change the android player considerably), to get the name of the field you need to access instead of "b", decompile Unity's android player jar file, and look inside the showSoftInput method. It'll look like this:

    Code (CSharp):
    1.     protected void showSoftInput(final String string2, final int n2, final boolean bl, final boolean bl2, final boolean bl3, final boolean bl4, final String string3, final int n3, final boolean bl5) {
    2.         this.a(new Runnable(){
    3.  
    4.             @Override
    5.             public final void run() {
    6.                 UnityPlayer.this.b = new k(UnityPlayer.this.r, this, string2, n2, bl, bl2, bl3, string3, n3, bl5);
    7.                 UnityPlayer.this.b.show();
    8.             }
    9.         });
    10.     }
    You want whichever field is instantiated and accessed here.

    Unity devs: can't you at least exclude that field from obfuscation? XD
     
    andersemil and Nit_Ram like this.
  13. EdyH

    EdyH

    Joined:
    Jun 20, 2019
    Posts:
    13
    Hi
    In Unity 2019.1.5 I have a null reference in this line
    Code (CSharp):
    1. var decorView = dialog.Call<AndroidJavaObject>("getWindow")
    2.                 .Call<AndroidJavaObject>("getDecorView");
    Edit: dialog is null
     
    Last edited: Jun 22, 2019
  14. XUEMINGNI

    XUEMINGNI

    Joined:
    Mar 28, 2019
    Posts:
    2
    I have the same problem. Has anyone solved it
     
  15. pepeims

    pepeims

    Joined:
    Mar 28, 2016
    Posts:
    1
    It works fine on Unity 2019.1.7 and Android 9 phone
     
  16. EdyH

    EdyH

    Joined:
    Jun 20, 2019
    Posts:
    13
    You should wait next frame or more
     
  17. PandaArcade

    PandaArcade

    Joined:
    Jan 2, 2017
    Posts:
    129
    With some help from a script on GitHub and this thread here is our solution that allows you to get the height including the native keyboards input area. We had trouble with other solutions because they didn't consider the input area and because we're using Resolution Scaling Mode -> Fixed DPI which means Screen.height returns the height Unity is rendering in rather than the pixel height of the device's display which was messing up the calculations.

    This is the script from GitHub - https://github.com/kabirules/ANP/bl.../Scripts/Internal/Utils/AndroidDialogUtils.cs

    Our solution -
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public static class MobileUtilities
    4. {
    5.     /// <summary>
    6.     /// Returns the keyboard height ratio.
    7.     /// </summary>
    8.     public static float GetKeyboardHeightRatio(bool includeInput)
    9.     {
    10.         return Mathf.Clamp01((float) GetKeyboardHeight(includeInput) / Display.main.systemHeight);
    11.     }
    12.  
    13.     /// <summary>
    14.     /// Returns the keyboard height in display pixels.
    15.     /// </summary>
    16.     public static int GetKeyboardHeight(bool includeInput)
    17.     {
    18. #if UNITY_ANDROID
    19.         using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    20.         {
    21.             var unityPlayer = unityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer");
    22.             var view = unityPlayer.Call<AndroidJavaObject>("getView");
    23.             var dialog = unityPlayer.Get<AndroidJavaObject>("mSoftInputDialog");
    24.  
    25.             if (view == null || dialog == null)
    26.                 return 0;
    27.  
    28.             var decorHeight = 0;
    29.  
    30.             if (includeInput)
    31.             {
    32.                 var decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
    33.  
    34.                 if (decorView != null)
    35.                     decorHeight = decorView.Call<int>("getHeight");
    36.             }
    37.  
    38.             using (var rect = new AndroidJavaObject("android.graphics.Rect"))
    39.             {
    40.                 view.Call("getWindowVisibleDisplayFrame", rect);
    41.                 return Display.main.systemHeight - rect.Call<int>("height") + decorHeight;
    42.             }
    43.         }
    44. #else
    45.         var height = Mathf.RoundToInt(TouchScreenKeyboard.area.height);
    46.         return height >= Display.main.systemHeight ? 0 : height;
    47. #endif
    48.     }
    49. }
    EDIT: Fixed this to work in 2019.3 :)
     
    Last edited: Jun 3, 2020
    vaskoa, Bvenjamin, khaled24 and 6 others like this.
  18. TheReview

    TheReview

    Joined:
    Nov 6, 2018
    Posts:
    2

    Hey how would I edit this for to work for IOS as well?

    Kind regards,

    Jesse
     
  19. TheReview

    TheReview

    Joined:
    Nov 6, 2018
    Posts:
    2

    Also how do I display the returned value?

    thanks
     
  20. PandaArcade

    PandaArcade

    Joined:
    Jan 2, 2017
    Posts:
    129
    What makes you think it doesn't work on iOS? Did you try it? It's working on iOS for us.

    Your question is very vague. What exactly do you want to do?
     
  21. AlexRinggaardCP

    AlexRinggaardCP

    Joined:
    Jan 20, 2020
    Posts:
    8
    This stopped working for us when upgrading to 2019.3. I decompiled the jar and it looks like this field is now called "mSoftInputDialog" instead of "b"
    Code (CSharp):
    1.  
    2. protected void showSoftInput(final String s, final int n, final boolean b, final boolean b2, final boolean b3, final boolean b4, final String s2, final int n2, final boolean b5) {
    3.         this.runOnUiThread(new Runnable() {
    4.             @Override
    5.             public final void run() {
    6.                 (UnityPlayer.this.mSoftInputDialog = new k(UnityPlayer.this.mContext, UnityPlayer.this, s, n, b, b2, b3, s2, n2, b5)).show();
    7.                 UnityPlayer.this.nativeReportKeyboardConfigChanged();
    8.             }
    9.         });
    10.     }
    11.  
    Sadly changing this didn't fix it :( ...Get<AndroidJavaObject>("mSoftInputDialog") still fails to find something. Has anybody else had some luck getting the height of an Android keyboard (without the input line) in 2019.3 ?
     
  22. MichaelFil

    MichaelFil

    Joined:
    Dec 15, 2015
    Posts:
    4
    It's strange. All works fine when I use 'mSoftInputDialog' instead of 'b'. Here is my code. Also, don't forget that this method returns a non-zero value after the keyboard finished appearing animation.

    Code (CSharp):
    1.  
    2.         public static int GetKeyboardHeight(bool includeInput)
    3.         {
    4. #if UNITY_ANDROID
    5.             using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
    6.                 var unityPlayer = unityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer");
    7.                 var view = unityPlayer.Call<AndroidJavaObject>("getView");
    8.  
    9.                 var result = 0;
    10.                
    11.                 if (view != null) {
    12.                     using (var rect = new AndroidJavaObject("android.graphics.Rect"))
    13.                     {
    14.                         view.Call("getWindowVisibleDisplayFrame", rect);
    15.                         result = Display.main.systemHeight - rect.Call<int>("height");
    16.                     }
    17.  
    18.                     if (includeInput) {
    19.                         var dialog = unityPlayer.Get<AndroidJavaObject>("mSoftInputDialog");
    20.                         var decorView = dialog?.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
    21.  
    22.                         if (decorView != null) {
    23.                             var decorHeight = decorView.Call<int>("getHeight");
    24.                             result += decorHeight;
    25.                         }
    26.                     }
    27.                 }
    28.                
    29.                 return result;
    30.             }
    31. #else
    32.             var height = Mathf.RoundToInt(TouchScreenKeyboard.area.height);
    33.             return height >= Display.main.systemHeight ? 0 : height;
    34. #endif
    35.         }
     
  23. shweta-unity

    shweta-unity

    Joined:
    Nov 23, 2016
    Posts:
    7
    I want to scroll/resize my scrollview object when keyboard is on screen.
    So I tried using this, and it gives me height of soft keyboard
    In some device it returns proper and my scrollview is resized properly but in some device but in some device it isn't working fine.

    Any suggestions? Is it returning proper height in all different sized android devices?

     
  24. JJunior

    JJunior

    Joined:
    May 22, 2019
    Posts:
    53
    I got this to work relative to the canvas size, here is the code... All you need is to call it with the canvas RectTransform reference.

    Code (CSharp):
    1. public static int GetRelativeKeyboardHeight(RectTransform rectTransform, bool includeInput)
    2.     {
    3.         int keyboardHeight = GetKeyboardHeight(includeInput);
    4.         float screenToRectRatio = Screen.height / rectTransform.rect.height;
    5.         float keyboardHeightRelativeToRect = keyboardHeight / screenToRectRatio;
    6.  
    7.         return (int) keyboardHeightRelativeToRect;
    8.     }
    9.  
    10.     private static int GetKeyboardHeight(bool includeInput)
    11.     {
    12. #if UNITY_EDITOR
    13.         return 0;
    14. #elif UNITY_ANDROID
    15.         using (AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    16.         {
    17.             AndroidJavaObject unityPlayer = unityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer");
    18.             AndroidJavaObject view = unityPlayer.Call<AndroidJavaObject>("getView");
    19.             AndroidJavaObject dialog = unityPlayer.Get<AndroidJavaObject>("mSoftInputDialog");
    20.             if (view == null || dialog == null)
    21.                 return 0;
    22.             var decorHeight = 0;
    23.             if (includeInput)
    24.             {
    25.                 AndroidJavaObject decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
    26.                 if (decorView != null)
    27.                     decorHeight = decorView.Call<int>("getHeight");
    28.             }
    29.             using (AndroidJavaObject rect = new AndroidJavaObject("android.graphics.Rect"))
    30.             {
    31.                 view.Call("getWindowVisibleDisplayFrame", rect);
    32.                 return Screen.height - rect.Call<int>("height") + decorHeight;
    33.             }
    34.         }
    35. #elif UNITY_IOS
    36.         return (int)TouchScreenKeyboard.area.height;
    37. #endif
    38.     }
     
    manoenbadua and d2tz like this.
  25. paperplane87

    paperplane87

    Joined:
    Nov 6, 2018
    Posts:
    3
    Thanks, It works perfectly.
     
    JJunior likes this.
  26. d2tz

    d2tz

    Joined:
    Oct 11, 2018
    Posts:
    3
    Solved an issue I had where the keyboard height was returning the wrong values on other screen resolutions.

    Thanks so much :)
     
  27. JRock2424

    JRock2424

    Joined:
    Apr 24, 2020
    Posts:
    8
    Sadly this returns 0 for me on a Samsung A20 ¯\_(ツ)_/¯
     
    ROBYER1 likes this.
  28. RageEye

    RageEye

    Joined:
    Aug 2, 2018
    Posts:
    1
    this returns 0 for me on unity 2020.1.4f1 on android 10
     
    luoweihong likes this.
  29. madfu

    madfu

    Joined:
    Aug 9, 2018
    Posts:
    19
    due to my dependency on this thread and the others like it in this forum for getting something working, i decided i'd offer my current workaround solution.

    after a number of failed tests over a day-and-a-half, where the code above would only work the first time i called it, and return zero (0) thereafter, i ended up making changes to GetKeyboardHeight() to make it more consistent in its output. the primary reason was that the original code failed to address the numerous timing issues i've found in using AndroidJava classes within Unity (written a few native Android apps; been using Unity for 24 months or so).

    in this case, because TouchScreenKeyboard.visible lies about the keyboard being completely visible when 'true', it's necessary to write the code that touches Android with this in mind. the code:

    Code (CSharp):
    1.    
    2.  
    3.     // some Android-specific constants (some have changed over time)
    4.     private const string _playerClass = "com.unity3d.player.UnityPlayer";
    5.     private const string _playerActivity = "currentActivity";
    6.     private const string _playerObject = "mUnityPlayer";
    7.     private const string _keyboardDialog = "mSoftInputDialog";
    8.     private const string _keyboardRect = "android.graphics.Rect";
    9.  
    10.     private static int GetKeyboardHeight(bool includeInputField)
    11.     {
    12.         using (AndroidJavaObject unityActivity = new AndroidJavaClass(_playerClass).GetStatic<AndroidJavaObject>(_playerActivity))
    13.         {
    14.             AndroidJavaObject unityPlayer = unityActivity.Get<AndroidJavaObject>(_playerObject);
    15.             AndroidJavaObject view = unityPlayer.Call<AndroidJavaObject>("getView");
    16.  
    17.             if (view == null)
    18.             {
    19.                 return 0;
    20.             }
    21.  
    22.             AndroidJavaObject dialog = unityPlayer.Get<AndroidJavaObject>(_keyboardDialog);
    23.             while (dialog == null)
    24.             {
    25.                 dialog = unityPlayer.Get<AndroidJavaObject>(_keyboardDialog);
    26.             }
    27.  
    28.             int decorHeight = 0;
    29.             if (includeInputField)
    30.             {
    31.                 AndroidJavaObject decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
    32.                 while (decorView == null)
    33.                 {
    34.                     decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
    35.                 }
    36.                 decorHeight = decorView.Call<int>("getHeight");
    37.                 while (decorHeight == 0)
    38.                 {
    39.                     decorHeight = decorView.Call<int>("getHeight");
    40.                 }
    41.                 // Debug.Log("decorHeight ==> [ " + decorHeight + " ] ");
    42.             }
    43.  
    44.             using (AndroidJavaObject rect = new AndroidJavaObject(_keyboardRect))
    45.             {
    46.                 view.Call("getWindowVisibleDisplayFrame", rect);
    47.                 int frameHeight = rect.Call<int>("height");
    48.                 // Debug.Log("frameHeight ==> [ " + frameHeight + " ] ");
    49.  
    50.                 int returnVal = Screen.height - frameHeight + decorHeight;
    51.                 // Debug.Log("returnVal ==> [ " + returnVal + " ] ");
    52.                 return returnVal;
    53.             }
    54.         }
    mostly, this code just waits until dependent variables are either not 'NULL' or non-zero. i left in the debug, 'cause that's the way it appears in my code.

    FYI, i didn't just alter GetKeyboardHeight(). i made other changes for the sake of robustness and removing ambiguity for Android. i haven't seen this info elsewhere, and your mileage may vary.
    1. i added :
      Code (CSharp):
      1. android:windowSoftInputMode="stateUnspecified|adjustNothing"
      to my AndroidManifest.xml file to make sure that the OS didn't help me while my code was making adjustments. if you're unsure where to add that line check here : https://developer.android.com/guide/topics/manifest/activity-element
    2. i added :
      Code (CSharp):
      1. inputField.shouldHideMobileInput = false;
      to each InputField instance that was going to be subject to my adjustments.
    3. i didn't depend solely on :
      Code (CSharp):
      1. TouchScreenKeyboard.visible
      to determine when to make the call to GetRelativeKeyboardHeight(). i also added a dependency on :
      Code (CSharp):
      1. inputField.touchScreenKeyboard.status == TouchScreenKeyboard.Status.Visible
    4. last thing, i waited until the last possible minute to make the call to GetRelativeKeyboardHeight(), so that i could be reasonably certain the keyboard would be visible. it was the last call i made after ensuring that TouchScreenKeyboard.visible and touchScreenKeyboard.status indicated keyboard visibility.
    context : Unity 2019.4.17f1 on OS X, tested on a Pixel XL running Android 8.1.0 (Oreo)

    ...END-OF-LINE...
     
    GubaPeter and JJunior like this.
  30. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    Tried this out on Android 10 with an Xperia XZ3 and it just freezes my app
     
  31. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
  32. madfu

    madfu

    Joined:
    Aug 9, 2018
    Posts:
    19
    sorry to hear that.

    still working fine for me (now on Unity 2019.4.19f1), but as i said, your mileage may vary.

    glad you found another workaround.
     
  33. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    Yeah my main issue was it doesn't work when using Fixed DPI set in player settings - Resolution ~ which I was using for app performance reasons, however I found some workarounds to not need fixed DPI set for my app. Just wanted to post to let other users know if they try to read onscreen keyboard height while using Fixed DPI, the results are inconsistent and on android I had crashes, turning off Fixed DPI fixed it for me
     
  34. hugogfadams

    hugogfadams

    Joined:
    Jul 27, 2020
    Posts:
    6
    I've been using the code in this thread for Android and have been getting weird results. I'm using Unity 2020.3.6 and a Google Pixel 2 with Android 11. The phone has a screen height of 1920. My problem is the rect's height from getWindowVisibleDisplayFrame returns 1794 saying the keyboard is only 126 tall. The keyboard covers at least 40% of the screen so these numbers are way off.

    The only reason I think this could happen is I'm using AR in the same scene which could be altering the resolution so it may be a similar problem to ROBYER1 but I don't have Fixed DPI enabled.

    If anyone has any insight or help It would be much appreciated, thanks.
     
    ROBYER1 likes this.
  35. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,454
    I also had inconsistent results on android, we ended up using the Asset store asset Advanced Input field 2 which has its own Keyboard height callback and even a simulated input field in the editor. I would advise to use that asset and also use this fix so the caret doesn't break while in AR (a bug I reported too)
    https://github.com/support-fennecx/advancedinputfield2/issues/35#issuecomment-830827577
     
  36. Anh-Pham

    Anh-Pham

    Joined:
    Feb 7, 2012
    Posts:
    35
    This work for me but not perfect. I have to wait 1.5 seconds (for the keyboard showing animation finish), to get it's height exactly. But in some cases, 1.5s is not enough. Anyone know how to handle the keyboard animation finish event?
     
    hugogfadams likes this.
  37. hugogfadams

    hugogfadams

    Joined:
    Jul 27, 2020
    Posts:
    6
    Thank you for posting this, it looks like I am getting the right values if I wait for a second or two. I had a similar experience with getting WebCamTexture size. For that I kept checking the size until it was above a certain value.
    I don't think there is an event for keyboard animation finish, I think I will keep checking the value in a while the keyboard is open and update my screen if the value changes.
     
    ROBYER1 likes this.
  38. Sneha_Pallewar

    Sneha_Pallewar

    Joined:
    Feb 18, 2019
    Posts:
    7


    We are trying to get keyboard height in android device. we have tried the above solutions, but we are not getting exact keyboard height. In some of the android devices we are getting 0 height. We also want the height of includeInput (inputfield), and for this we tried the solution of decorHeight but that is also not working.

    unity version 2020.3.11
    Android Api level- 24 and above

    Can you/anyone please help on this.
     
  39. madfu

    madfu

    Joined:
    Aug 9, 2018
    Posts:
    19
    sorry that you're not having success with the code fragment.

    as i said, your mileage may vary.

    i'm currently running it successfully with no changes (last i checked) on Unity 2020.3.22f1 on OS X, tested on both a Pixel XL running Android 8.1.0 (Oreo) and a Samsung Galaxy S8+ running Android 9 (Pie).

    while i can't suggest a fix without knowing specifically what you're doing or how you've coded everything up, i can offer
    that the main point of the code fragment is to try to wait in while-loops for the various components of the Android keyboard to become visible to the Unity code. if you're not getting some kind of height value, you're probably not waiting long enough. it's also important to wait to call GetKeyboardHeight() until the last possible moment in your Update() loop.

    for me this meant not calling that function until:
    1. the input field had focus, AND
    2. the inputField.touchScreenKeyboard.status was equal to TouchScreenKeyboard.Status.Visible.
    in my code, i have a couple of variable assignments and a one-line mathematical calculation between 1 & 2. together, that may affect the timing a little, but i don't think this is germane here. this is mostly all i can tell you.

    one last thought:

    having tried the code above on multiple phones now, with varying levels of success, i think the next time i'll try to attack this problem, i'll completely remove any dependency on Unity code and just write the code in Android-Java as a plugin. i essence, i'll be creating my own event from Java to tell Unity that the keyboard is visible and that it has a height of 'X'. this way, i'll be talking directly with the platform and can confirm at that level that the keyboard is visible, and measure then the height thereafter. not sure when i'll get around to that.

    good luck!...END-OF-LINE...
     
  40. amonraduyev

    amonraduyev

    Joined:
    Apr 12, 2020
    Posts:
    10
    There is a weird issue that TouchScreenKeyboard.area.height returns device height instead of keyboard height. Tested on Iphone 6s. Unity 2021.3.3f1 Silicon. I double checked but keyboard height always returns device height of Iphone 6s which is 1334px. What can possible reason of that?
     
  41. madfu

    madfu

    Joined:
    Aug 9, 2018
    Posts:
    19
    so, i have this now on my list of stuff to do sometime in the next couple of our sprints. presuming it works, that other people still need it, and someone else hasn't already solved it by then, i'll share what i have. again, ymmv, but it'll be an option.

    ...END-OF-LINE...
     
  42. r4rahmat789

    r4rahmat789

    Joined:
    Jul 29, 2022
    Posts:
    3
    Have you Found the Proper Solution for this Issue trying to Fix this but it didn't Work For me.
     
  43. madfu

    madfu

    Joined:
    Aug 9, 2018
    Posts:
    19
    assuming something else doesn't get in the way (and it might), i should start on this next week. no idea how long it will take or how portable it will be, but it will be a plugin intended to create "my own event from Java to tell Unity that the keyboard is visible and that it has a height of 'X'."

    when i have it working, i'll post code here or github or somewhere.
     
  44. cnsjjj

    cnsjjj

    Joined:
    Aug 13, 2022
    Posts:
    35
    Any update? Thanks in advance!
     
  45. Zaiyue

    Zaiyue

    Joined:
    Jun 8, 2022
    Posts:
    1
    When using the provided code above, if you can retrieve a value but it is incorrect, it may be due to this reason. Open the AndroidManifest file in your project and check if the Activity tag has the "android:windowSoftInputMode" attribute. Its value should be "adjustResize" or "adjustPan". If its value is "adjustNothing," it is highly likely that this issue is causing the incorrect value return.
     
  46. AndyBlock

    AndyBlock

    Joined:
    Oct 12, 2016
    Posts:
    35
    We were using the following code for some time, which was based I think on one of the suggestions in this thread:

    Code (CSharp):
    1.                 var view = currentActivity
    2.                     .Get<AndroidJavaObject>( "mUnityPlayer" )
    3.                     .Call<AndroidJavaObject>( "getView" )
    4.                 ;
    5.  
    6.                 using ( var rect = new AndroidJavaObject( "android.graphics.Rect" ) )
    7.                 {
    8.                     view.Call( "getWindowVisibleDisplayFrame", rect );
    9.  
    10.                     return Screen.height - rect.Call<int>( "height" );
    11.                 }
    However we recently noticed a crash, which we tracked down to this code; basically, it is leaking references and because we were calling it every frame on a particular screen, it would eventually overflow some table of references leading to a crash. We fixed it by adjusting the code as follows:

    Code (CSharp):
    1.                 using (var mUnityPlayer = currentActivity.Get<AndroidJavaObject>( "mUnityPlayer" ))
    2.                 {
    3.                     using (var view = mUnityPlayer.Call<AndroidJavaObject>( "getView" ))
    4.                     {
    5.                         using ( var rect = new AndroidJavaObject( "android.graphics.Rect" ) )
    6.                         {
    7.                             view.Call( "getWindowVisibleDisplayFrame", rect );
    8.  
    9.                             return Screen.height - rect.Call<int>( "height" );
    10.                         }
    11.                     }
    12.                 }

    The crash details in case it helps someone find this issue:


    12-20 16:06:49.230 27891 27974 F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 27974 (UnityMain), pid 27891 (and.xxx.xxx)
    12-20 16:06:49.763 4440 4440 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    12-20 16:06:49.763 4440 4440 F DEBUG : Build fingerprint: 'Nothing/PongEEA/Pong:13/TKQ1.221220.001/2310242214:user/release-keys'
    12-20 16:06:49.763 4440 4440 F DEBUG : Revision: '0'
    12-20 16:06:49.763 4440 4440 F DEBUG : ABI: 'arm'
    12-20 16:06:49.764 4440 4440 F DEBUG : Timestamp: 2023-12-20 16:06:49.369337539+0100
    12-20 16:06:49.764 4440 4440 F DEBUG : Process uptime: 3352s
    12-20 16:06:49.764 4440 4440 F DEBUG : Cmdline: xxx.xxx
    12-20 16:06:49.764 4440 4440 F DEBUG : pid: 27891, tid: 27974, name: UnityMain >>> xxx.xxx <<<
    12-20 16:06:49.764 4440 4440 F DEBUG : uid: 10376
    12-20 16:06:49.764 4440 4440 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
    Abort message: 'JNI ERROR (app bug): global reference table overflow (max=51200)global reference table dump:
    Last 10 entries (of 51200):
    51199: 0x70fea5a0 java.lang.Class<android.graphics.Rect>
    51198: 0x13fdbcf8 java.lang.Class<com.unity3d.player.UnityPlayer>
    51197: 0x13fdb9b8 com.unity3d.player.UnityPlayer
    51196: 0x13fd73c0 android.view.MotionEvent
    51195: 0x13fdb9b8 com.unity3d.player.UnityPlayer
    51194: 0x13fdbcf8 java.lang.Class<com.unity3d.player.UnityPlayer>
    51193: 0x13fdbcf8 java.lang.Class<com.unity3d.player.UnityPlayer>
    51192: 0x13fdb9b8 com.unity3d.player.UnityPlayer
    51191: 0x13fdbcf8 java.lang.Class<com.unity3d.player.UnityPlayer>
    51190: 0x13fdb9b8 com.unity3d.player.UnityPlayer
    12-20 16:06:49.764 4440 4440 F DEBUG : Summary:
    12-20 16:06:49.764 4440 4440 F DEBUG : 25778 of java.lang.Class (395 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 25167 of com.unity3d.player.UnityPlayer (1 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 23 of java.lang.String (22 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 21 of java.util.ArrayList (21 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 19 of com.android.billingclient.api.BillingResult (3 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 18 of java.lang.ref.WeakReference (18 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 14 of android.database.ContentObserver$Transport (14 unique instances)
    12-20 16:06:49.764 4440 4440 F DEBUG : 11 of android.view.ViewRootImpl$W (11 unique instances)
    ...
    12-20 16:06:49.764 4440 4440 F DEBUG : backtrace:
    12-20 16:06:49.764 4440 4440 F DEBUG : #00 pc 00039baa /apex/com.android.runtime/lib/bionic/libc.so (abort+138) (BuildId: b25d939cf297d12a048279f5c9ec411e)
    12-20 16:06:49.764 4440 4440 F DEBUG : #01 pc 005364b1 /apex/com.android.art/lib/libart.so (art::Runtime::Abort(char const*)+1360) (BuildId: 6dc72c2cbe2cf0489266cd603215f081)
    12-20 16:06:49.764 4440 4440 F DEBUG : #02 pc 00023837 /apex/com.google.mainline.primary.libs@340941000/lib/libbase.so/2baee144307110a2b9a7fffc26bfdca189fe29b8266623afb93ed899028350f0708609923037edb06ca3f04aad0e2a06ef79abe9df8628423a3f13dfbde5f670/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_0::__invoke(char const*)+46) (BuildId: 959b00e687b93fff2e345580c1584040)
    12-20 16:06:49.764 4440 4440 F DEBUG : #03 pc 000230d7 /apex/com.google.mainline.primary.libs@340941000/lib/libbase.so/2baee144307110a2b9a7fffc26bfdca189fe29b8266623afb93ed899028350f0708609923037edb06ca3f04aad0e2a06ef79abe9df8628423a3f13dfbde5f670/libbase.so (android::base::LogMessage::~LogMessage()+226) (BuildId: 959b00e687b93fff2e345580c1584040)
    12-20 16:06:49.764 4440 4440 F DEBUG : #04 pc 001dde43 /apex/com.android.art/lib/libart.so (art::JavaVMExt::AddGlobalRef(art::Thread*, art::ObjPtr<art::mirror::Object>)+234) (BuildId: 6dc72c2cbe2cf0489266cd603215f081)
    12-20 16:06:49.764 4440 4440 F DEBUG : #05 pc 00470853 /apex/com.android.art/lib/libart.so (art::JNI<true>::NewGlobalRef(_JNIEnv*, _jobject*)+530) (BuildId: 6dc72c2cbe2cf0489266cd603215f081)
    12-20 16:06:49.764 4440 4440 F DEBUG : #06 pc 0041729d /apex/com.android.art/lib/libart.so (art::(anonymous namespace)::CheckJNI::NewRef(char const*, _JNIEnv*, _jobject*, art::IndirectRefKind) (.__uniq.99033978352804627313491551960229047428)+588) (BuildId: 6dc72c2cbe2cf0489266cd603215f081)
    12-20 16:06:49.764 4440 4440 F DEBUG : #07 pc 00002f6a <anonymous:d83c0000>


    Hope this helps someone! Kind regards,

    Andy
     
  47. Uaxx

    Uaxx

    Joined:
    Apr 27, 2018
    Posts:
    3
    Code (CSharp):
    1. _view.Call("getWindowVisibleDisplayFrame", rect);
    2. int visibleHeight = rect.Call<int>("height");
    Does this still work? On Realme visibleHeight equals always 200000