6

I'm playing around with some keyboard development and try to show a pop-up dialog when a certain key is pressed

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

However, the problem is the CONTEXT part. In a normal application it would just be this. I also tried getApplicationContext() and getBaseContext(), but neither of those works -> keyboard crashes.

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

So I'm wondering if I have to do something with InputConnection:

The InputConnection interface is the communication channel from an InputMethod back to the application that is receiving its input. It is used to perform such things as reading text around the cursor, committing text to the text box, and sending raw key events to the application.

So far I wasn't able to figure out how. I definitely know it's possible, since I have seen it before. I someone could point me in the right direction that would definitely be appreciated.


Update:

To provide a better picture of what I try to achieve I uploaded a screenshot of the Swype keyboard, which does exactly that: showing a pop-up dialog when a special key gets pressed on the keyboard.

Swype pop-up dialog

znq
  • 44,613
  • 41
  • 116
  • 144

6 Answers6

5

Peace be upon those who follow the guidance,

solution :

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();

good luck.

Maher Abuthraa
  • 17,493
  • 11
  • 81
  • 103
  • if soft keyboard is open and try to open alert dialog box, Softkeyboard display under the alertdialog box not allow to add text inside the edittext of the alertdialog box – Faizal Abbas Mar 20 '18 at 09:42
  • First of all thank you! For some reason sometimes after I press the positive button, onFinishInputView is being called. Do you have any idea why? – Amit Klein Nov 06 '20 at 18:19
  • It is not working for me anymore. Can anyone please help me to open dialog from an ime service? @AmitKlein – Chirag Prajapati Sep 05 '21 at 15:17
4

An IME does not run in an application context, so you can not use normal application windows. You can use a Dialog, but you will need to modify its window so that the window type is this type:

http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_APPLICATION_PANEL

And set WindowManager.LayoutParams.token to be the token of the IME window (via View.getWindowToken()).

Note that the dialog will not be able to display pop-up windows, because in this case it is itself effectively a pop-up window. Also the coordinate space will be relative to your IME unless you use the window flags to change it.

hackbod
  • 90,665
  • 16
  • 140
  • 154
  • Thanks for pointing me in the right direction. Additionally looking at the Android's default keyboard source code answered all my questions. – znq Aug 26 '10 at 11:42
  • @hackbod I have tried your suggestion, but it's not working on Android 9. Can you please have a look at https://stackoverflow.com/questions/51906586/display-dialog-from-input-method-service-in-android-9-android-pie? – Philipp Aug 18 '18 at 08:05
2

Make an activity and in the manifest file give that activity the attribute

android:theme="@android:style/Theme.Dialog"
Nathan Schwermann
  • 31,285
  • 16
  • 80
  • 91
0

You have to get a reference to your activity context. Anyway, you should use the showDialog method of the Activity.

fedj
  • 3,452
  • 1
  • 22
  • 21
  • Two problems: 1) I'm developing a IME (keyboard), thus it's not my activity 2) How do I get the reference to the current activity? (That's actually my question above) – znq Aug 16 '10 at 16:12
  • One thing is sure, you cannot display any Dialog from the ApplicationContext. Why don't you take a context reference in your constructor of the view ? – fedj Aug 16 '10 at 16:32
  • Because it's keyboard service which talks to any text input field of other (not my) applications: http://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html – znq Aug 16 '10 at 20:31
  • @znq Can you please help me to open dialog from an ime service? – Chirag Prajapati Sep 05 '21 at 15:18
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()
Lucas
  • 1,224
  • 1
  • 14
  • 21
0

its very simple, just create activity like here (with out any view), write code of dialog in it

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();

}
}

now go to Android manifest file and add activity like,

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

its all, enjoy