无法添加窗口 - 令牌null无效;你的活动在运行吗?

时间:2014-11-23 10:32:44

标签: android

我想在用户点击浮动图标时显示自定义弹出菜单

使用服务创建浮动图标,我没有活动

这是我的浮动图标代码

public class copy_actions_service extends Service
{
    ImageView copy_ImageView;
    WindowManager windowManager;
    WindowManager.LayoutParams layoutParams;

    @Override
    public IBinder onBind(Intent arg0)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override

    public void onCreate()
    {
        windowManager=(WindowManager)getSystemService(WINDOW_SERVICE);

        copy_ImageView=new ImageView(this);
        copy_ImageView.setImageResource(R.drawable.ic_launcher);
        copy_ImageView.setAlpha(245);
        copy_ImageView.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View arg0)
            {
                showCustomPopupMenu();
            }
        });

        layoutParams=new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        layoutParams.gravity=Gravity.TOP|Gravity.CENTER;
        layoutParams.x=0;
        layoutParams.y=100;

        windowManager.addView(copy_ImageView, layoutParams);

    }

    private void showCustomPopupMenu()
    {
        LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view=layoutInflater.inflate(R.layout.xxact_copy_popupmenu, null);

        PopupWindow popupWindow=new PopupWindow();
        popupWindow.setContentView(view);
        popupWindow.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
        popupWindow.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
        popupWindow.setFocusable(true);

        popupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);             
    }
}

每件事情都很好但是当我点击浮动按钮app停止并且这个错误显示在logcat上:(

11-23 02:18:58.217: E/AndroidRuntime(3231): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

但我没有活动?!

我想在用户点击浮动图标后弹出菜单显示;但弹出菜单只能显示文字;

如何显示带图标的弹出菜单?

14 个答案:

答案 0 :(得分:26)

如果您正在使用Context作为Dialog dialog = new Dialog(getApplicationContext()); 来进行此类对话

Dialog dialog = new Dialog(YourActivityName.this);

然后使用YourActivityName.this

_

答案 1 :(得分:9)

我遇到了和你一样的问题,看起来你像我一样使用了http://www.piwai.info/chatheads-basics的教程。问题是您无法将当前活动可靠地传递到弹出窗口,因为您无法控制当前活动。看起来可能有一种不可靠的方式来获取当前活动,但我不建议这样做。

我为我的应用程序修复它的方法是不使用弹出窗口,而是通过窗口管理器自行创建。

private void showCustomPopupMenu()
    {
                windowManager2 = (WindowManager)getSystemService(WINDOW_SERVICE);
                LayoutInflater layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                View view=layoutInflater.inflate(R.layout.xxact_copy_popupmenu, null);
                params=new WindowManager.LayoutParams(
                        WindowManager.LayoutParams.WRAP_CONTENT,
                        WindowManager.LayoutParams.WRAP_CONTENT,
                        WindowManager.LayoutParams.TYPE_PHONE,
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                        PixelFormat.TRANSLUCENT);

                params.gravity=Gravity.CENTER|Gravity.CENTER;
                params.x=0;
                params.y=0;
                windowManager2.addView(view, params);  
    }

如果您希望它看起来像一个弹出窗口,只需添加一个透明的灰色视图作为背景,并向其添加一个onClickListener以从windowManager对象中删除该视图。

我知道这不像弹出窗口那么方便,但根据我的经验,这是最可靠的方式。

并且不要忘记在清单文件中添加权限

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

答案 2 :(得分:6)

当您尝试过早显示popUpWindow来解决此问题时,会发生此错误,要对其进行修复,请将ID设置为main_layout并使用下面的代码

Java:

 findViewById(R.id.main_layout).post(new Runnable() {
   public void run() {
       popupWindow.showAtLocation(findViewById(R.id.main_layout), Gravity.CENTER, 0, 0);
   }
});

科特琳:

 main_layout.post {
      popupWindow?.showAtLocation(main_layout, Gravity.CENTER, 0, 0)
    }

贷记@kordzik

答案 3 :(得分:5)

您需要在构造函数中传递您的活动

 PopupWindow popupWindow = new PopupWindow(YourActivity.this)

答案 4 :(得分:4)

如果您使用另一个 view,请确保使用 view.getContext() 而不是 thisgetApplicationContext()

答案 5 :(得分:3)

使用此Dialog dialog = new Dialog(theActivity.this); 代替Dialog dialog = new Dialog(getApplicationContext);Dialog dialog = new Dialog(context);

答案 6 :(得分:1)

PopupWindow只能附加到Activity。在您的情况下,您尝试将PopupWindow添加到service,这是不对的。

要解决此问题,您可以使用空白且透明的Activity。点击浮动图标,启动ActivityonCreate Activity显示PopupWindow

在解雇PopupWindow时,您可以finish透明Activity。 希望这会对你有所帮助。

答案 7 :(得分:1)

您不应将windowManager.addView放在onCreate中

尝试在windowManager.addView之后调用onWindowFocusChanged,并且hasFoucus的状态为true。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    //code here
    //that you can add a flag that you can call windowManager.addView now.
}

答案 8 :(得分:1)

尝试显示DatePicker中的Fragment时出现此错误。

我改变了

val datePickerDialog = DatePickerDialog(activity!!.applicationContext, ...)

val datePickerDialog = DatePickerDialog(requireContext(), ...)

效果很好

答案 9 :(得分:1)

在我的情况下,我在活动开始时就对PopupMenu进行了膨胀,即在onCreate()上...通过将其放入 Handler

  new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                PopupMenu popuMenu=new PopupMenu(SplashScreen.this,binding.progressBar);
                popuMenu.inflate(R.menu.bottom_nav_menu);
                popuMenu.show();
            }
        },100);

答案 10 :(得分:0)

我遇到了同样的问题,我已经通过@Redman的解决方案和其他一些方法解决了这个问题,

这就是我所做的。

 findViewById(R.id.main_layout).post(new Runnable() {
 public void run() {
   popupWindow.showAtLocation(findViewById(R.id.main_layout), Gravity.CENTER, 0, 0);
}
 });

添加了Runnable方法,并在onDestroy方法中检查了popuwindow是否显示为空。

 @Override
protected void onDestroy() {
    super.onDestroy();

    if (popupWindow.isShowing())
    {
        popupWindow.dismiss();
        popupWindow=null;
    }
    }

答案 11 :(得分:0)

使用YOURACTIVITY.this代替getApplicationContext()

答案 12 :(得分:0)

此错误是由于传递了错误的上下文引起的。

您必须将“活动”作为上下文传递,getApplicationContext()不起作用。

因此,将您的上下文投射到“活动”。

在科特林,

context as HomeActivity

答案 13 :(得分:0)

如果您将getBaseContext()或getApplicationContext()用作此类对话框的上下文

Dialog dialog = new Dialog(getBaseContext()); 

Dialog dialog = new Dialog(getApplicationContext());

然后使用YourActivityName.this

  

对话框对话框=新对话框(YourActivityName.this);