diff --git a/osu.Framework.Android/AndroidGameView.cs b/osu.Framework.Android/AndroidGameView.cs
index a24af49610..949b845341 100644
--- a/osu.Framework.Android/AndroidGameView.cs
+++ b/osu.Framework.Android/AndroidGameView.cs
@@ -64,6 +64,13 @@ public bool PointerCapture
private readonly Game game;
+ private InputMethodManager inputMethodManager;
+
+ ///
+ /// Whether is active.
+ ///
+ private bool textInputActive;
+
public AndroidGameView(AndroidGameActivity activity, Game game)
: base(activity)
{
@@ -97,6 +104,8 @@ private void init()
// disable ugly green border when view is focused via hardware keyboard/mouse.
DefaultFocusHighlightEnabled = false;
+
+ inputMethodManager = Activity.GetSystemService(Context.InputMethodService) as InputMethodManager;
}
protected override void CreateFrameBuffer()
@@ -238,15 +247,43 @@ private void updateSafeArea()
};
}
- public override bool OnCheckIsTextEditor() => true;
+ public override bool OnCheckIsTextEditor() => textInputActive;
+ /// null to disable input methods
public override IInputConnection OnCreateInputConnection(EditorInfo outAttrs)
{
+ // Properly disable native input methods so that the software keyboard doesn't unexpectedly open.
+ // Eg. when pressing keys on a hardware keyboard.
+ if (!textInputActive)
+ return null;
+
outAttrs.ImeOptions = ImeFlags.NoExtractUi | ImeFlags.NoFullscreen;
outAttrs.InputType = InputTypes.TextVariationVisiblePassword | InputTypes.TextFlagNoSuggestions;
return new AndroidInputConnection(this, true);
}
+ internal void StartTextInput()
+ {
+ textInputActive = true;
+ Activity.RunOnUiThread(() =>
+ {
+ inputMethodManager.RestartInput(this); // this syncs the Android input method state with `OnCreateInputConnection()`.
+ RequestFocus();
+ inputMethodManager?.ShowSoftInput(this, 0);
+ });
+ }
+
+ internal void StopTextInput()
+ {
+ textInputActive = false;
+ Activity.RunOnUiThread(() =>
+ {
+ inputMethodManager.RestartInput(this);
+ inputMethodManager?.HideSoftInputFromWindow(WindowToken, HideSoftInputFlags.None);
+ ClearFocus();
+ });
+ }
+
public override void SwapBuffers()
{
try
diff --git a/osu.Framework.Android/Input/AndroidTextInput.cs b/osu.Framework.Android/Input/AndroidTextInput.cs
index 8af000777c..eab5a518d5 100644
--- a/osu.Framework.Android/Input/AndroidTextInput.cs
+++ b/osu.Framework.Android/Input/AndroidTextInput.cs
@@ -1,24 +1,18 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using Android.Content;
using Android.Views;
-using Android.Views.InputMethods;
using osu.Framework.Input;
namespace osu.Framework.Android.Input
{
- public class AndroidTextInput : TextInputSource
+ internal class AndroidTextInput : TextInputSource
{
private readonly AndroidGameView view;
- private readonly InputMethodManager inputMethodManager;
public AndroidTextInput(AndroidGameView view)
{
this.view = view;
- inputMethodManager = view.Activity.GetSystemService(Context.InputMethodService) as InputMethodManager;
}
private void commitText(string text)
@@ -36,33 +30,19 @@ protected override void ActivateTextInput(bool allowIme)
{
view.KeyDown += keyDown;
view.CommitText += commitText;
-
- view.Activity.RunOnUiThread(() =>
- {
- view.RequestFocus();
- inputMethodManager?.ShowSoftInput(view, 0);
- });
+ view.StartTextInput();
}
protected override void EnsureTextInputActivated(bool allowIme)
{
- view.Activity.RunOnUiThread(() =>
- {
- view.RequestFocus();
- inputMethodManager?.ShowSoftInput(view, 0);
- });
+ view.StartTextInput();
}
protected override void DeactivateTextInput()
{
view.KeyDown -= keyDown;
view.CommitText -= commitText;
-
- view.Activity.RunOnUiThread(() =>
- {
- inputMethodManager?.HideSoftInputFromWindow(view.WindowToken, HideSoftInputFlags.None);
- view.ClearFocus();
- });
+ view.StopTextInput();
}
}
}