web-dev-qa-db-fra.com

Android 1.6: "Android.view.WindowManager $ BadTokenException: impossible d'ajouter une fenêtre - le jeton null n'est pas pour une application"

J'essaie d'ouvrir une fenêtre de dialogue, mais chaque fois que j'essaie de l'ouvrir, cette exception lève cette 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)

Je le crée en appelant showDialog avec l'identifiant de l'écran. Le gestionnaire onCreateDialog se connecte bien et je peux le parcourir sans problème, mais je l’ai attaché car il semble que je manque quelque chose:

@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;      
}

Est-ce qu'il manque quelque chose? Certaines questions ont évoqué ce problème lors de la création d’une boîte de dialogue à partir de onCreate, ce qui est dû au fait que l’activité n’a pas encore été créée, mais provient d’un appel d’un objet de menu et que la variable appContext semble remplie correctement. débogueur.

296
Dan Monego

Au lieu de: Context appContext = this.getApplicationContext();vous devriez utiliser un pointeur sur l’activité dans laquelle vous vous trouvez (probablement this).

Je me suis fait mordre par cela aujourd'hui aussi, la partie ennuyante est la getApplicationContext() est textuelle de developer.Android.com :(

608
Torp

Vous ne pouvez pas afficher une fenêtre/une boîte de dialogue d'application à travers un contexte qui n'est pas une activité. Essayez de passer une référence d'activité valide

78
Samuh

Idem sur la chose getApplicationContext.

Les documents sur le site Android dit de l'utiliser, mais cela ne fonctionne pas ... grrrrr :-P

Il suffit de faire:

dialog = new Dialog(this); 

"ceci" est généralement votre activité à partir de laquelle vous lancez le dialogue.

45
kenyee

Les documents Android suggèrent d'utiliser getApplicationContext ();

mais cela ne fonctionnera pas au lieu de cela, utilisez votre activité actuelle lors de l'instanciation de AlertDialog.Builder ou AlertDialog ou Dialog ... 

Ex: 

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

ou

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);
43
Pradeep

Au lieu de getApplicationContext(), utilisez simplement ActivityName.this

17
mahbub_siddique

J'ai eu un problème similaire où j'ai eu une autre classe quelque chose comme ça:

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

La plupart du temps, je me suis bien débrouillé, mais il a parfois eu un problème grave. Puis je me rends compte que dans MyActivity j'avais ...

public class MyActivity extends Activity {
  public static Something something;

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

Parce que je tenais l'objet comme static, une deuxième exécution du code contenait toujours la version d'origine de l'objet et faisait donc toujours référence à la Activity originale, qui n'existait plus.

Erreur stupide et stupide, d'autant plus que je n'avais pas vraiment besoin de tenir l'objet en tant que static en premier lieu ...

13
T.Hawk

Il suffit de le changer en

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

Au lieu de

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(getApplicationContext());
12
Satheesh

Une autre solution consiste à définir le type de fenêtre sur une boîte de dialogue système:

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

Cela nécessite la permission SYSTEM_ALERT_WINDOW :

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

Comme le dit la documentation:

Très peu d'applications devraient utiliser cette permission. ces fenêtres sont conçues pour une interaction au niveau du système avec l'utilisateur.

C'est une solution que vous ne devriez utiliser que si vous avez besoin d'une boîte de dialogue qui n'est pas attachée à une activité.

9
Anubian Noob

N'utilisez pas getApplicationContext() pour déclarer dialouge

Toujours utiliser this ou votre activity.this 

4
Jinu

Cela a fonctionné pour moi--

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

Utilisation 

ActivityName.this
3
Suyog Gunjal

Pour les dialogues imbriqués, ce problème est très courant. Il fonctionne lorsque 

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

est utilisé à la place de 

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

cette alternative.

2
mifthi

Vous pouvez aussi faire ça 

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

Cela a fonctionné pour moi !! 

1
Metalhead1247
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);
//                          }
        });
    }

Texte ici:-
utilisez ceci pour obtenir le contexte activity pour progressdialog

 progressdialog = new ProgressDialog(Splash.this);

ou progressdialog = new ProgressDialog(this); 

utilisez-le pour obtenir le contexte d'application pour BroadcastListener pas pour progressdialog.

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
0
Faisal Ashraf

Essayez de réinitialiser le type de fenêtre dialog à

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

N'oubliez pas d'utiliser la permission Android.permission.SYSTEM_ALERT_WINDOW

0
hopetribe

Comme il est dit, vous avez besoin d’une activité en tant que contexte pour la boîte de dialogue, utilisez "YourActivity.this" pour un contexte statique ou cochez ici pour savoir comment utiliser une activité dynamique en mode sans échec.

0
Hugo

Le moyen le plus sûr et le plus sûr d'afficher un 'ProgressDialog' dans une tâche asynchrone, en évitant les problèmes de fuite de mémoire, consiste à utiliser un 'gestionnaire' avec Looper.main ().

    private ProgressDialog tProgressDialog;

puis dans le 'onCreate'

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

Maintenant, vous avez terminé avec la partie configuration. Maintenant, appelez 'showProgress ()' et 'hideProgress ()' en 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);
    }
0
Sankar Behera