305

I'm trying to open a dialog window, but every time I try to open it it throws this exception:

Uncaught handler: thread main exiting due to uncaught exception
android.view.WindowManager$BadTokenException: 
     Unable to add window -- token null is not for an application
  at android.view.ViewRoot.setView(ViewRoot.java:460)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
  at android.app.Dialog.show(Dialog.java:238)
  at android.app.Activity.showDialog(Activity.java:2413)

I'm creating it by calling showDialog with the display's id. The onCreateDialog handler logs fine and I can step through it without an issue, but I've attached it since it seems like I'm missing something:

@Override
public Dialog onCreateDialog(int id)
{
    Dialog dialog;
    Context appContext = this.getApplicationContext();
    switch(id)
    {
        case RENAME_DIALOG_ID:
            Log.i("Edit", "Creating rename dialog...");
            dialog = new Dialog(appContext);
            dialog.setContentView(R.layout.rename);
            dialog.setTitle("Rename " + noteName);
            break;
        default:
            dialog = null;
            break;
    }
    return dialog;      
}

Is there something missing from this? Some questions have talked about having this problem when creating a dialog from onCreate, which happens because the activity isn't created yet, but this is coming from a call from a menu object, and the appContext variable seems like it is correctly populated in the debugger.

JJD
  • 44,755
  • 49
  • 183
  • 309
Dan Monego
  • 7,638
  • 6
  • 31
  • 64

16 Answers16

610

Instead of : Context appContext = this.getApplicationContext(); you should use a pointer to the activity you're in (probably this).

I got bitten by this today too, the annoying part is the getApplicationContext() is verbatim from developer.android.com :(

CopsOnRoad
  • 109,635
  • 30
  • 367
  • 257
Torp
  • 7,894
  • 1
  • 18
  • 18
  • 2
    It's also reported as a bug (although it wasn't when the user posted the question): http://code.google.com/p/android/issues/detail?id=11199 – Raymond Martineau Sep 30 '11 at 00:45
  • 63
    Just in case this helps anyone - use myActivity.this as your context in a dialog. – Rab Ross Dec 05 '11 at 15:55
  • 13
    This question and answer turns 3 years old in 2 days. I'm still getting reputation, so i guess Google still haven't fixed their docs... – Torp Apr 12 '13 at 17:50
  • 2
    This has been fixed in (http://developer.android.com/guide/topics/ui/dialogs.html) – Martin Marconcini May 03 '13 at 17:48
  • Great, guess this question can go away and finally die of old age then. – Torp May 04 '13 at 14:01
  • 1
    Replaced getApplicationContext() with this , its works fine. Thanx – Rana Ranvijay Singh Dec 27 '13 at 05:52
  • 1
    @Torp Nope. Not gonna die soon. Take an upvote from a user you helped. – PNDA Jul 13 '15 at 15:31
  • 1
    No, it's still a problem, especially since people will randomly advice you to use `getApplicationContext()`. – Kitalda Aug 11 '15 at 06:54
  • So as a clarification, you should use the Activity Context to launch a Dialog rather than some other one. – toidiu Feb 18 '16 at 04:53
  • 6
    This is April of 2016 , and still this exception making application crash on dialog initiation. – Yogesh Seralia Apr 05 '16 at 13:21
  • 2
    August '16 here, still got it after trying [this](http://stackoverflow.com/questions/17944061/how-to-use-number-picker-with-dialog#comment65243784_17944168) answer. – Jezor Aug 14 '16 at 17:02
  • Saved my day !. Thank you – jafarmlp Nov 22 '17 at 17:13
  • This is definitely what solved my problem, though I used the `getApplicationContext();` for the reason that it is recommended to reduced JAVA Heap Memory, and i learned that it is not recommended to use as an instance when it is used for UI/Widgets... – Ric17101 Dec 29 '17 at 06:35
78

You cannot display an application window/dialog through a Context that is not an Activity. Try passing a valid activity reference

Samuh
  • 35,513
  • 26
  • 104
  • 116
45

Ditto on the getApplicationContext thing.

The documents on the android site says to use it, but it doesn't work...grrrrr :-P

Just do:

dialog = new Dialog(this); 

"this" is usually your Activity from which you start the dialog.

dakshbhatt21
  • 3,318
  • 3
  • 27
  • 37
kenyee
  • 1,989
  • 21
  • 30
43

Android documents suggests to use getApplicationContext();

but it will not work instead of that use your current activity while instantiating AlertDialog.Builder or AlertDialog or Dialog...

Ex:

AlertDialog.Builder builder = new  AlertDialog.Builder(this);

or

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);
dakshbhatt21
  • 3,318
  • 3
  • 27
  • 37
Pradeep
  • 2,439
  • 24
  • 37
  • This helped me out massively. I was trying to create a dialog from within another dialog and just having "AlertDialog.Builder(this);" was giving an error. Thanks! – EHarpham Oct 20 '12 at 12:16
  • (ActivityName.this) is especially useful when trying to create a dialog inside onClick of a button – RmK Dec 16 '14 at 11:51
  • My problem is that I'm building a ProgressDialog inside an AlertDialog inside of an Adapter... I can't get it to work. – Martin Erlic Jul 06 '17 at 19:22
17

Instead of getApplicationContext(), just use ActivityName.this

mahbub_siddique
  • 1,677
  • 18
  • 21
13

I had a similar issue where I had another class something like this:

public class Something {
  MyActivity myActivity;

  public Something(MyActivity myActivity) {
    this.myActivity=myActivity;
  }

  public void someMethod() {
   .
   .
   AlertDialog.Builder builder = new AlertDialog.Builder(myActivity);
   .
   AlertDialog alert = builder.create();
   alert.show();
  }
}

Worked fine most of the time, but sometimes it crashed with the same error. Then I realise that in MyActivity I had...

public class MyActivity extends Activity {
  public static Something something;

  public void someMethod() {
    if (something==null) {
      something=new Something(this);
    }
  }
}

Because I was holding the object as static, a second run of the code was still holding the original version of the object, and thus was still referring to the original Activity, which no long existed.

Silly stupid mistake, especially as I really didn't need to be holding the object as static in the first place...

T.Hawk
  • 131
  • 1
  • 2
12

Just change it into

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(YourActivity.this);

Instead of

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(getApplicationContext());
JJD
  • 44,755
  • 49
  • 183
  • 309
Satheesh
  • 1,712
  • 25
  • 34
9

Another solution is to set the window type to a system dialog:

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

This requires the SYSTEM_ALERT_WINDOW permission:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

As the docs say:

Very few applications should use this permission; these windows are intended for system-level interaction with the user.

This is a solution you should only use if you require a dialog that's not attached to an activity.

Anubian Noob
  • 12,897
  • 5
  • 47
  • 69
  • This is now deprecated flag from API level 26. Because it allows the developer to play with system window which is not good from user perspective. – CopsOnRoad Jan 19 '18 at 06:51
4

Don't use getApplicationContext() on declaring dialouge

Always use this or your activity.this

Jinu
  • 8,605
  • 4
  • 30
  • 37
2

For nested dialogs this issue is very common, It works when

AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);

is used instead of

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

this alternative.

mifthi
  • 131
  • 8
2

This Worked for me--

new AlertDialog.Builder(MainActivity.this)
        .setMessage(Html.fromHtml("<b><i><u>Spread Knowledge Unto The Last</u></i></b>"))
        .setCancelable(false)
        .setPositiveButton("Dismiss",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                    }
                }).show();

Use

ActivityName.this
Suyog Gunjal
  • 287
  • 4
  • 7
0

You can also do this

public class Example extends Activity {
    final Context context = this;
    final Dialog dialog = new Dialog(context);
}

This worked for me !!

JJD
  • 44,755
  • 49
  • 183
  • 309
Metalhead1247
  • 1,933
  • 1
  • 15
  • 27
0
public class Splash extends Activity {

    Location location;
    LocationManager locationManager;
    LocationListener locationlistener;
    ImageView image_view;
    ublic static ProgressDialog progressdialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        progressdialog = new ProgressDialog(Splash.this);
           image_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                        locationManager.requestLocationUpdates("gps", 100000, 1, locationlistener);
                        Toast.makeText(getApplicationContext(), "Getting Location plz wait...", Toast.LENGTH_SHORT).show();

                            progressdialog.setMessage("getting Location");
                            progressdialog.show();
                            Intent intent = new Intent(Splash.this,Show_LatLng.class);
//                          }
        });
    }

Text here:-
use this for getting activity context for progressdialog

 progressdialog = new ProgressDialog(Splash.this);

or progressdialog = new ProgressDialog(this);

use this for getting application context for BroadcastListener not for progressdialog.

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
rafsanahmad007
  • 23,062
  • 6
  • 43
  • 58
Faisal Ashraf
  • 1,336
  • 1
  • 10
  • 11
0

As it's said, you need an Activity as context for the dialog, use "YourActivity.this" for a static context or check here for how to use a dynamic one in a safe mode

Community
  • 1
  • 1
Hugo
  • 1,572
  • 15
  • 32
0

Try to reset dialog window's type to

WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Don't forget to use the permission android.permission.SYSTEM_ALERT_WINDOW

Uwe
  • 34,565
  • 10
  • 75
  • 109
hopetribe
  • 91
  • 1
  • 4
0

The best and the safest way to show a 'ProgressDialog' in an AsyncTask, avoiding memory leak problem is to use a 'Handler' with Looper.main().

    private ProgressDialog tProgressDialog;

then in the 'onCreate'

    tProgressDialog = new ProgressDialog(this);
    tProgressDialog.setMessage(getString(R.string.loading));
    tProgressDialog.setIndeterminate(true);

Now you r done with the setup part. Now call 'showProgress()' and 'hideProgress()' in AsyncTask.

    private void showProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.show();
            }
        }.sendEmptyMessage(1);
    }

    private void hideProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.dismiss();
            }
        }.sendEmptyMessage(1);
    }
Sankar Behera
  • 753
  • 9
  • 10