So, TouchScreenKeyboard.area returns zero rect, anyone has a solution or plugin? Seems like an old issue.
Ok, so this is what I got so far, works atm and it’s enought for now:
using(AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");
using(AndroidJavaObject Rct = new AndroidJavaObject("android.graphics.Rect"))
{
View.Call("getWindowVisibleDisplayFrame", Rct);
return Screen.height - Rct.Call<int>("height");
}
}
I know this is an old thread. But its a life saver. Thanks.
Can anyone elaborate on how to use this thread
public int GetKeyboardSize()
{
using (AndroidJavaClass UnityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject View = UnityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer").Call<AndroidJavaObject>("getView");
using (AndroidJavaObject Rct = new AndroidJavaObject("android.graphics.Rect"))
{
View.Call("getWindowVisibleDisplayFrame", Rct);
return Screen.height - Rct.Call<int>("height");
}
}
}
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?
In complement to this solution, which work fine on Android.
Has anyone found a similiar solution for iOS devices ?
- calling this function when the keyboard is visible but still getting 0 as a result.
Has anyone experienced this?
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?)
bump, I’d love to know this as well
public static float GetKeyboardHeightRatio()
{
if (Application.isEditor)
return 0.4f;
#if UNITY_ANDROID
using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
var view = unityClass.GetStatic<AndroidJavaObject>("currentActivity")
.Get<AndroidJavaObject>("mUnityPlayer")
.Call<AndroidJavaObject>("getView");
var dialog = unityClass.GetStatic<AndroidJavaObject>("currentActivity")
.Get<AndroidJavaObject>("mUnityPlayer")
.Get<AndroidJavaObject>("b");
var decorView = dialog.Call<AndroidJavaObject>("getWindow")
.Call<AndroidJavaObject>("getDecorView");
var height = decorView.Call<int>("getHeight");
using (var rect = new AndroidJavaObject("android.graphics.Rect"))
{
view.Call("getWindowVisibleDisplayFrame", rect);
return (float) (Screen.height - rect.Call<int>("height") + height) / Screen.height;
}
}
#elif UNITY_IOS
return (float) TouchScreenKeyboard.area.height / Screen.height;
#endif
}
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.
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:
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) {
this.a(new Runnable(){
@Override
public final void run() {
UnityPlayer.this.b = new k(UnityPlayer.this.r, this, string2, n2, bl, bl2, bl3, string3, n3, bl5);
UnityPlayer.this.b.show();
}
});
}
You want whichever field is instantiated and accessed here.
Unity devs: can’t you at least exclude that field from obfuscation? XD
Hi
In Unity 2019.1.5 I have a null reference in this line
var decorView = dialog.Call<AndroidJavaObject>("getWindow")
.Call<AndroidJavaObject>("getDecorView");
Edit: dialog is null
I have the same problem. Has anyone solved it
It works fine on Unity 2019.1.7 and Android 9 phone
You should wait next frame or more
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 - ANP/Assets/AndroidGoodies/Scripts/Internal/Utils/AndroidDialogUtils.cs at 9b3b3d9fa1e04152d30ea8b164d902435ea228a8 · kabirules/ANP · GitHub
Our solution -
using UnityEngine;
public static class MobileUtilities
{
/// <summary>
/// Returns the keyboard height ratio.
/// </summary>
public static float GetKeyboardHeightRatio(bool includeInput)
{
return Mathf.Clamp01((float) GetKeyboardHeight(includeInput) / Display.main.systemHeight);
}
/// <summary>
/// Returns the keyboard height in display pixels.
/// </summary>
public static int GetKeyboardHeight(bool includeInput)
{
#if UNITY_ANDROID
using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
var unityPlayer = unityClass.GetStatic<AndroidJavaObject>("currentActivity").Get<AndroidJavaObject>("mUnityPlayer");
var view = unityPlayer.Call<AndroidJavaObject>("getView");
var dialog = unityPlayer.Get<AndroidJavaObject>("mSoftInputDialog");
if (view == null || dialog == null)
return 0;
var decorHeight = 0;
if (includeInput)
{
var decorView = dialog.Call<AndroidJavaObject>("getWindow").Call<AndroidJavaObject>("getDecorView");
if (decorView != null)
decorHeight = decorView.Call<int>("getHeight");
}
using (var rect = new AndroidJavaObject("android.graphics.Rect"))
{
view.Call("getWindowVisibleDisplayFrame", rect);
return Display.main.systemHeight - rect.Call<int>("height") + decorHeight;
}
}
#else
var height = Mathf.RoundToInt(TouchScreenKeyboard.area.height);
return height >= Display.main.systemHeight ? 0 : height;
#endif
}
}
EDIT: Fixed this to work in 2019.3 ![]()
Hey how would I edit this for to work for IOS as well?
Kind regards,
Jesse
Also how do I display the returned value?
thanks
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?