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

Android 无法添加窗口--令牌null无效;你的活动正在进行吗?,android,Android,我想在用户点击浮动图标时显示一个自定义弹出菜单 使用服务创建浮动图标,我没有活动 这是我的浮动图标代码 public class copy_actions_service extends Service { ImageView copy_ImageView; WindowManager windowManager; WindowManager.LayoutParams layoutParams; @Override public IBinder onBi

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

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

这是我的浮动图标代码

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);             
    }
}
一切正常,但当我点击浮动按钮时,应用程序停止,此错误显示在logcat上:(

但我没有活动

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


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

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

 PopupWindow popupWindow = new PopupWindow(YourActivity.this)

PopupWindow
只能附加到
活动
。在您的情况下,您试图将
PopupWindow
添加到
服务
,这是不对的

要解决此问题,您可以使用一个空白且透明的
活动
。单击浮动图标,启动
活动
,并在
活动
onCreate
上显示
弹出窗口

关闭
弹出窗口时
,您可以
完成透明的
活动

希望这对您有所帮助。

我和您有同样的问题,看起来您像我一样使用了教程。问题是您无法可靠地将当前活动传递到弹出窗口,因为您无法控制当前活动。看起来获取当前活动的方法可能不可靠,但我不推荐我知道

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

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"/>

如果您在活动中使用
getApplicationContext()
作为
上下文

Dialog dialog = new Dialog(getApplicationContext());
然后使用您的ActivityName.this

Dialog dialog = new Dialog(YourActivityName.this);

当您试图过早地显示popUpWindow时,会发生此错误。若要修复此错误,请将主布局的Id指定为
main\u 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)
    }
Kotlin:

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

要归功于

您不应该将windowManager.addView放在onCreate中

尝试在WindowFocusChanged
之后调用
windowManager.addView
,并且
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.
}

我在试图从
片段
显示
日期选择器
时遇到此错误

我变了

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


它工作得很好。

在我的例子中,我在活动的一开始就打开了一个弹出菜单,即onCreate()…我通过将其放入处理程序来修复它

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

如果使用另一个
视图
请确保使用
view.getContext()
而不是
this
getApplicationContext()

我没有活动可以执行此操作;此代码在服务上运行不是活动我希望在单击浮动图标后显示弹出菜单;我可以执行此操作,但弹出菜单只显示文本而不显示图标;如何创建带有图标的自定义弹出菜单?当用户单击此视图之外时如何关闭此windowmanager?@nidhi使用
windowmanager 2.removeViewImmediate(视图);
但将膨胀视图设置为全局变量
私有视图;
此错误发生在
windowManager.addView(视图,参数)
也是-
由android.view.WindowManager$BadTokenException导致无法添加窗口--token null无效;您的活动正在运行吗?
上述解决方案不相关。我们在没有活动的情况下查找上下文。此解决方案需要一个活动,这肯定不是我们要查找的活动。如果我正在使用它呢g一个碎片工作完美!@Flash然后你可以使用在FragmentThank中,保存了我的一天。bettor在onlick listeners中膨胀了弹出菜单。我把它放在onCreate的末尾,在我第一次启动时有一个教程弹出窗口对我很有效。谢谢!这个解决方案几乎对我有效,从某种意义上说,它不会使应用程序崩溃,但问题是,当你关闭window再次调用
onWindowFocusChanged
,从而重复显示窗口