android - studio - unable to add window-- token null is not valid




Android 1.6: «android.view.WindowManager $ BadTokenException: Невозможно добавить окно-токен null не для приложения» (11)

Я пытаюсь открыть диалоговое окно, но каждый раз, когда я пытаюсь открыть его, это исключает это исключение:

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)

Я создаю его, вызывая showDialog с идентификатором дисплея. Обработчик onCreateDialog нормально, и я могу пройти через него без проблем, но я привязал его, поскольку кажется, что я что-то пропустил:

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

Что-то не хватает в этом? Некоторые вопросы говорили об этой проблеме при создании диалога из onCreate , что происходит из-за того, что активность еще не создана, но это происходит из вызова из объекта меню, и переменная appContext кажется, что она правильно заполнена в отладчик.


В документах на Android предлагается использовать getApplicationContext ();

но он не будет работать вместо того, чтобы использовать вашу текущую активность при создании AlertDialog.Builder или AlertDialog или Dialog ...

Пример:

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

или же

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

Вместо getApplicationContext() просто используйте ActivityName.this


Вы не можете отобразить окно / диалог приложения через контекст, который не является активностью. Попробуйте передать действительную ссылку на действительность


Вы также можете сделать это

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

Это сработало для меня!


Еще одно решение - установить тип окна в системный диалог:

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

Для этого требуется разрешение SYSTEM_ALERT_WINDOW :

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

Как говорят документы:

Очень мало приложений должно использовать это разрешение; эти окна предназначены для взаимодействия на уровне системы с пользователем.

Это решение, которое вы должны использовать, только если вам требуется диалоговое окно, которое не привязано к действию.


Как сказано, для контекста требуется контекст активности, используйте «YourActivity.this» для статического контекста или проверьте here как использовать динамический в безопасном режиме


Не используйте getApplicationContext() при объявлении dialouge

Всегда используйте this или свою activity.this


Попробуйте сбросить тип dialog окна, чтобы

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

Не забудьте использовать разрешение android.permission.SYSTEM_ALERT_WINDOW


То же самое в случае getApplicationContext.

Документы на сайте android говорят, чтобы использовать его, но он не работает ... grrrrr :-P

Просто делать:

dialog = new Dialog(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();
  }
}

Работал отлично в большинстве случаев, но иногда он разбивался с той же ошибкой. Тогда я понимаю, что в MyActivity меня было ...

public class MyActivity extends Activity {
  public static Something something;

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

Поскольку я удерживал объект как static , второй запуск кода по-прежнему содержал исходную версию объекта и, следовательно, все еще имел в виду исходную Activity , которая долгое время не существовала.

Глупая глупая ошибка, тем более, что мне действительно не нужно было держать объект static в первую очередь ...


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

Текст здесь: -
используйте это для получения контекста activity для progressdialog

 progressdialog = new ProgressDialog(Splash.this);

или progressdialog = new ProgressDialog(this);

используйте это для получения контекста приложения для BroadcastListener не для progressdialog .

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());




android-windowmanager