Android Popupwindow no se abrirá correctamente
Pregunta
Estoy tratando de hacer lo siguiente:
Crear servicio de fondo cuando se recibe un mensaje en InputQueue del Broker MQTT Show a PopUp
Así que tengo la suscripción al corredor MQTT que funciona bien. Cuando llega un mensaje, se inicia una intención a mostrar la ventana emergente, sin embargo, se muestra el siguiente error:
01-06 19:26:58.412: WARN/WindowManager(989): Failed looking up window
01-06 19:26:58.412: WARN/WindowManager(989): java.lang.IllegalArgumentException: Requested window null does not exist
01-06 19:26:58.412: WARN/WindowManager(989): at com.android.server.WindowManagerService.windowForClientLocked(WindowManagerService.java:9408)
01-06 19:26:58.412: WARN/WindowManager(989): at com.android.server.WindowManagerService.addWindow(WindowManagerService.java:1934)
01-06 19:26:58.412: WARN/WindowManager(989): at com.android.server.WindowManagerService$Session.add(WindowManagerService.java:6886)
01-06 19:26:58.412: WARN/WindowManager(989): at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:66)
01-06 19:26:58.412: WARN/WindowManager(989): at com.android.server.WindowManagerService$Session.onTransact(WindowManagerService.java:6858)
01-06 19:26:58.412: WARN/WindowManager(989): at android.os.Binder.execTransact(Binder.java:288)
01-06 19:26:58.412: WARN/WindowManager(989): at dalvik.system.NativeStart.run(Native Method)
01-06 19:26:58.412: DEBUG/AndroidRuntime(5364): Shutting down VM
01-06 19:26:58.412: WARN/dalvikvm(5364): threadid=1: thread exiting with uncaught exception (group=0x4001d878)
01-06 19:26:58.412: WARN/WindowManager(989): Attempted to add window with token that is not a window: null. Aborting.
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): FATAL EXCEPTION: main
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.andy.tabletsms.tablet/com.andy.tabletsms.work.SMSPopup}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.os.Looper.loop(Looper.java:123)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at java.lang.reflect.Method.invoke(Method.java:521)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at dalvik.system.NativeStart.main(Native Method)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.view.ViewRoot.setView(ViewRoot.java:505)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.view.Window$LocalWindowManager.addView(Window.java:424)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.widget.PopupWindow.invokePopup(PopupWindow.java:828)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.widget.PopupWindow.showAtLocation(PopupWindow.java:688)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at com.andy.tabletsms.work.SMSPopup.onCreate(SMSPopup.java:58)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
01-06 19:26:58.422: ERROR/AndroidRuntime(5364): ... 11 more
01-06 19:26:58.432: WARN/ActivityManager(989): Force finishing activity com.andy.tabletsms.tablet/com.andy.tabletsms.work.SMSPopup
01-06 19:26:58.432: WARN/ActivityManager(989): Force finishing activity com.andy.tabletsms.tablet/.main
01-06 19:26:58.932: WARN/ActivityManager(989): Activity pause timeout for HistoryRecord{444da2b8 com.andy.tabletsms.tablet/com.andy.tabletsms.work.SMSPopup}
La cola se verifica cada 5 segundos y emite una actividad de inicio para la ventana emergente si hay un elemento de la siguiente manera
SMSPopup.msg = main.msgs.get(0);
Intent testActivityIntent = new Intent(context.getApplicationContext(), com.andy.tabletsms.work.SMSPopup.class);
testActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(testActivityIntent);
La clase SMSPOPUP se ve de la siguiente manera:
package com.andy.tabletsms.work;
import com.andy.tabletsms.tablet.R;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.Toast;
public class SMSPopup extends Activity{
public static String msg;
private PopupWindow pw;
@Override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
LayoutInflater inflater = LayoutInflater.from(this);
// inflate our view from the corresponding XML file
View layout = inflater.inflate(R.layout.popup, (ViewGroup)findViewById(R.id.popup_menu_root));
// create a 100px width and 200px height popup window
pw = new PopupWindow(layout, 100, 200, true);
// set actions to buttons we have in our popup
Button button1 = (Button)layout.findViewById(R.id.popup_menu_button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View vv) {
// close the popup
pw.dismiss();
}
});
Button button2 = (Button)layout.findViewById(R.id.popup_menu_button2);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View vv) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
Button button3 = (Button)layout.findViewById(R.id.popup_menu_button3);
button3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View vv) {
finish();
}
});
// finally show the popup in the center of the window
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
}
}
Solución
Otras publicaciones han señalado el problema de intentar emitir apartamento demasiado temprano. Sin embargo, también creo que realmente no deberías estar haciendo esto:
public static String msg;
y
SMSPopup.msg = main.msgs.get(0);
Esta no es la forma correcta de pasar datos a otro Activity
. Debe configurar los datos como un Extra
sobre el Intent
, como esto:
Intent testActivityIntent = new Intent(context.getApplicationContext(), com.andy.tabletsms.work.SMSPopup.class);
testActivityIntent.putExtra("com.andy.tabletsms.message", main.msgs.get(0));
testActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(testActivityIntent);
Luego puede recuperar el mensaje en su objetivo Activity
:
private String msg;
...
Intent intent = getIntent();
if (intent != null){
Bundle bundle = intent.getExtras();
if (bundle != null){
msg = bundle.getString("com.andy.tabletsms.message");
}
}
Otros consejos
Está mostrando su ventana emergente demasiado temprano, solo se puede mostrar después de que se muestra la ventana de la actividad. Simplemente podría publicar una ejecución para mostrar la ventana emergente.