Android输入法:如何显示弹出对话框?

6

我正在进行一些键盘开发,尝试在按下某个特定的键时显示弹出对话框。

if (primaryCode == -301) {
            AlertDialog mDialog = new AlertDialog.Builder(CONTEXT)
            .setTitle("My dialog")
            .setMessage("Lets do it.")
            .setPositiveButton("ok", null).create();
             mDialog.show();
}

然而,问题在于CONTEXT部分。在正常应用程序中,它只是this。我也尝试了getApplicationContext()getBaseContext(),但两者都不起作用->键盘崩溃。

android.view.WindowManager$BadTokenException:无法添加窗口--令牌null不是应用程序

所以我想知道是否需要对InputConnection做些什么:

InputConnection接口是从InputMethod返回到接收其输入的应用程序的通信通道。它用于执行诸如在光标周围读取文本,提交文本到文本框以及将原始按键事件发送到应用程序等操作。

到目前为止,我还没能弄清楚该怎么做。我绝对知道这是可能的,因为我以前见过。如果有人能指点我正确的方向,那肯定会感激不尽。
更新: 为了更好地说明我的目标,我上传了Swype键盘的屏幕截图,它正是这样做的:当键盘上按下特殊键时,显示一个弹出对话框。

Swype pop-up dialog

6个回答

5

祝愿遵循指引的人们平安无事,

解决方案:

AlertDialog dialog;
//add this to your code
       dialog = builder.create();
        Window window = dialog.getWindow(); 
        WindowManager.LayoutParams lp = window.getAttributes();
            lp.token = mInputView.getWindowToken();
            lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
            window.setAttributes(lp);
            window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
//end addons
alert.show();

祝你好运。


如果软键盘已打开并尝试打开警告对话框,则软键盘将显示在警告对话框下方,不允许在警告对话框的EditText中添加文本。 - Faizal Abbas
首先感谢您!由于某种原因,有时在我按下正按钮后,会调用onFinishInputView。您有任何想法吗? - Amit Klein
它对我不再起作用了。有人可以帮我从输入法服务中打开对话框吗?@AmitKlein - Chirag Prajapati

4
一个IME不在应用程序上下文中运行,因此您不能使用普通的应用程序窗口。您可以使用对话框,但需要修改其窗口,使窗口类型为此类型:http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_APPLICATION_PANEL,并将WindowManager.LayoutParams.token设置为IME窗口的令牌(通过View.getWindowToken())。
请注意,对话框将无法显示弹出窗口,因为在这种情况下,它本身实际上是一个弹出窗口。此外,坐标空间将相对于您的IME,除非您使用窗口标志来更改它。

感谢指引我正确的方向。此外,查看Android默认键盘源代码回答了我所有的问题。 - znq
@hackbod,我已经尝试了您的建议,但在Android 9上无法正常工作。您能否请看一下https://stackoverflow.com/questions/51906586/display-dialog-from-input-method-service-in-android-9-android-pie? - Philipp

2
创建一个活动,并在清单文件中为该活动设置属性。
android:theme="@android:style/Theme.Dialog"

0
// 1. CREATE THE DIALOG
val builder: AlertDialog.Builder = AlertDialog.Builder(this, R.style.Theme_AppCompat_Light)
builder.setTitle("Title").setMessage("This is the message for the user. ")
val mDialog = builder.create()

// 2. SET THE IME WINDOW TOKEN ATTRIBUTE WITH THE TOKEN OF THE KEYBOARD VIEW 
mDialog.window?.attributes?.token = this.mTblView.windowToken

// 3. SET THE TYPE OF THE DIALOG TO TYPE_APPLICATION_ATTACHED_DIALOG
mDialog.window?.setType(WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG)

// 4. SHOW THE DIALOG 
mDialog.show()

0

非常简单,只需创建一个活动(不带任何视图),在其中编写对话框代码即可。

public class dialog extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Are you sure you want to Delete All Contacts?");
    builder.setCancelable(false);

    builder.setPositiveButton("Yes",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            //deleteAllContacts();
                        }//
                    });

            builder.setNegativeButton("No",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                        }
                    });

    AlertDialog alert = builder.create();
    alert.show();

}
}

现在打开 Android Manifest 文件并添加活动,例如:

<activity android:name=".dialog" android:theme="@android:style/Theme.NoDisplay">        </activity>

就这些了,享受吧


0
你需要获取到你的活动上下文的引用。 无论如何,你应该使用Activity的showDialog方法。

两个问题:1)我正在开发一个IME(键盘),因此它不是我的活动;2)如何获取当前活动的引用?(这实际上是我上面的问题) - znq
有一件事是肯定的,你不能从ApplicationContext显示任何对话框。为什么不在视图的构造函数中获取一个上下文引用呢? - fedj
因为它是一个键盘服务,可以与其他应用程序的任何文本输入字段进行交互:http://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html - znq
@znq,请问你可以帮我从输入法服务中打开对话框吗? - Chirag Prajapati

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接