【问题标题】:Display dialog from Input Method Service in Android 9 (Android Pie)在 Android 9 (Android Pie) 中从输入法服务显示对话框
【发布时间】:2019-01-25 03:46:36
【问题描述】:

我的应用程序包含一个输入法服务,该服务带有一个特殊按钮,可以弹出一个对话框。对于 Android 9 的用户,此对话框无法正确显示,只有 IME 上方的部分可见:

创建对话框的代码是

    AlertDialog dialog = builder.create();
    Window window = dialog.getWindow();
    WindowManager.LayoutParams lp = window.getAttributes();
    LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
    lp.token = inputView.getWindowToken();
    lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
    window.setAttributes(lp);
    window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

    dialog.show();

https://stackoverflow.com/a/13962770/292233中描述的相同

我也按照https://stackoverflow.com/a/3508462/292233 中的建议尝试了TYPE_APPLICATION_PANEL,但这也无济于事。

有什么简单的解决办法吗?

【问题讨论】:

  • 开始一个以对话为主题的活动。
  • @commonsware 我正在考虑这个,但是您将如何将数据返回到 IME 服务?我无法从我的服务中使用 startActivityForResult。
  • 如果活动和服务在同一个进程中,你可以使用任何你想要的。这可能是一个事件总线(例如,LocalBroadcastManager)。这可以通过与单例存储库进行交互来实现。等等。如果活动和服务在不同的进程中,则使用PendingIntent,或Messenger,或ResultReceiver等。
  • @CommonsWare 我已将活动实现为对话框(使用主题=),这在大多数情况下都有效,但用户指出,在 Chrome 上,当对话框弹出时,IME 已关闭,看起来就像我再也无法将文本输入到输入字段一样。我正在使用 getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);在活动的 onCreate 中。有什么想法吗?谢谢。
  • “用户指出,在 Chrome 上,当对话框弹出时,IME 会关闭”——你无法控制它。是否显示 IME 取决于具有触发 IME 的EditText(或其他)的应用程序。在这种情况下,Chrome 可能会在 Chrome 不再具有输入焦点时使用InputMethodManager 隐藏 IME。

标签: android android-9.0-pie


【解决方案1】:

可以通过使用 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG 而不是 TYPE_APPLICATION_ATTACHED_DIALOG 并请求 android.permission.SYSTEM_ALERT_WINDOW 来解决此问题。

详细改动在这里: https://github.com/osfans/trime/commit/d8e9da2dfe2653c94cd4aecba00728b7a910cbb8

【讨论】:

  • 查看此处的详细更改并将 LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG 更改为使用 LayoutParams.TYPE_APPLICATION_OVERLAY 对我有用。但是您必须根据文档将 Manifest.permission.SYSTEM_ALERT_WINDOW 添加到您的清单(以及授予的权限)中。
  • E/AndroidRuntime: FATAL EXCEPTION: IntentService[BTDeviceMaintainerService] 进程: com.unionpay.smartpos.service, PID: 3926 android.view.WindowManager$BadTokenException: Unable to add window -- token null 不是有效的;您的活动正在进行吗?
【解决方案2】:

如果 PopupWindow 和 AlertDialog 都不起作用,我认为我们可以使用浮动视图,如下所示:

  1. 自定义视图,使其看起来像一个对话框。
  2. 使用 WindowManager 添加视图,该视图将显示在任何 android 应用程序的顶部。我从FlowtingExample学到的

我尝试使用它。它适用于 Android P。但是,这种方法在全局键方面存在严重问题:

当从键盘显示“对话框”时,用户按下 Home 键等全局键。

=> 显示主屏幕。但是,“对话框”和键盘仍在显示。

(有没有办法解决这个限制?)。

(我听说谷歌键盘(Gboard)的语言选择对话框在Android P上完美运行。但是我找不到Gboard的源代码。有没有办法得到它?)

对不起,我对 stackoverflow 完全陌生,我想我应该将其发布到评论部分,但我不能这样做,因为我没有足够的 50 名声望。

【讨论】:

  • 这是一个输入法:github.com/BrainBear/LatinIME。它是从 AOSP LatinIME 移植过来的。长按逗号时,AlertDialog 效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多