valid - Android 1.6: "android.view.WindowManager $ BadTokenException: no se puede agregar la ventana: el token null no es para una aplicación"
unable to add window dialog show (16)
Estoy intentando abrir una ventana de diálogo, pero cada vez que intento abrirla, se produce esta excepción:
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)
Lo estoy creando llamando a showDialog
con el ID de la pantalla. El controlador onCreateDialog
registra bien y puedo recorrerlo sin problemas, pero lo he adjuntado, ya que parece que me falta algo:
@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;
}
¿Hay algo que falta en esto? Algunas preguntas han hablado acerca de tener este problema al crear un diálogo desde onCreate
, lo que sucede porque la actividad aún no se ha creado, pero esto proviene de una llamada de un objeto de menú, y la variable appContext
parece que se ha appContext
correctamente en el depurador
Como se dice, necesita una Actividad como contexto para el cuadro de diálogo, use "YourActivity.this" para un contexto estático o verifique here cómo usar una dinámica en un modo seguro
En lugar de getApplicationContext()
, simplemente use ActivityName.this
En lugar de: Context appContext = this.getApplicationContext();
debe usar un puntero a la actividad en la que se encuentra (probablemente this
).
Me picó esto también hoy, la parte molesta es que getApplicationContext()
es literal de developer.android.com :(
Esto funcionó para mí--
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();
Utilizar
ActivityName.this
Igual que en el tema getApplicationContext.
Los documentos en el sitio de Android dicen que usarlo, pero no funciona ... grrrrr :-P
Solo haz:
dialog = new Dialog(this);
"esto" suele ser tu actividad desde la que inicias el diálogo.
Intenta restablecer el tipo de ventana de dialog
para
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
No olvides usar el permiso android.permission.SYSTEM_ALERT_WINDOW
La mejor y la forma más segura de mostrar un ''ProgressDialog'' en una AsyncTask, evitando el problema de pérdida de memoria, es usar un ''Handler'' con Looper.main ().
private ProgressDialog tProgressDialog;
luego en el ''onCreate''
tProgressDialog = new ProgressDialog(this);
tProgressDialog.setMessage(getString(R.string.loading));
tProgressDialog.setIndeterminate(true);
Ahora que ha terminado con la parte de configuración. Ahora llame a ''showProgress ()'' y ''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);
}
Los documentos de Android sugieren utilizar getApplicationContext ();
pero no funcionará en lugar de utilizar su actividad actual mientras crea una instancia de AlertDialog.Builder o AlertDialog o Dialog ...
Ex:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
o
AlertDialog.Builder builder = new AlertDialog.Builder((Your Activity).this);
No puede mostrar una ventana / diálogo de aplicación a través de un contexto que no sea una actividad. Intenta pasar una referencia de actividad válida
No use getApplicationContext()
al declarar dialouge
Siempre usa this
o tu activity.this
this
Otra solución es establecer el tipo de ventana en un cuadro de diálogo del sistema:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Esto requiere el permiso SYSTEM_ALERT_WINDOW
:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Como dicen los doctores:
Muy pocas aplicaciones deben usar este permiso; estas ventanas están destinadas a la interacción a nivel del sistema con el usuario.
Esta es una solución que solo debe usar si necesita un diálogo que no esté adjunto a una actividad.
Para los diálogos anidados este problema es muy común, funciona cuando
AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);
se utiliza en lugar de
mDialogBuilder = new AlertDialog.Builder(getApplicationContext);
esta alternativa
Solo cambia en
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(YourActivity.this);
En lugar de
AlertDialog.Builder alert_Categoryitem =
new AlertDialog.Builder(getApplicationContext());
También puedes hacer esto
public class Example extends Activity {
final Context context = this;
final Dialog dialog = new Dialog(context);
}
¡Esto funcionó para mí!
Tuve un problema similar en el que tuve otra clase como esta:
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();
}
}
Funcionó bien la mayor parte del tiempo, pero a veces se estrelló con el mismo error. Entonces me doy cuenta de que en MyActivity
tuve ...
public class MyActivity extends Activity {
public static Something something;
public void someMethod() {
if (something==null) {
something=new Something(this);
}
}
}
Debido a que mantenía el objeto como static
, una segunda ejecución del código aún contenía la versión original del objeto y, por lo tanto, seguía refiriéndose a la Activity
original, que ya no existía.
Un error estúpido y tonto, especialmente porque no necesitaba estar sosteniendo el objeto como static
en primer lugar ...
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);
// }
});
}
Texto aqui:-
Use esto para obtener el contexto de la activity
para progressdialog
progressdialog = new ProgressDialog(Splash.this);
o progressdialog = new ProgressDialog(this);
use esto para obtener el contexto de la aplicación para BroadcastListener
no para progressdialog
.
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());