无法添加窗口——令牌空无效; 您的活动正在运行吗?

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

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

这是我的浮动图标代码

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: (

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?

但我没有任何活动?

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

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

175875 次浏览

You need to pass your activity in the constructor

 PopupWindow popupWindow = new PopupWindow(YourActivity.this)

PopupWindow can only be attached to an Activity. In your case you are trying to add PopupWindow to service which is not right.

To solve this problem you can use a blank and transparent Activity. On click of floating icon, launch the Activity and on onCreate of Activity show the PopupWindow.

On dismiss of PopupWindow, you can finish the transparent Activity. Hope this helps you.

I had the same problem as you, it looks like you used the tutorial from http://www.piwai.info/chatheads-basics like I did. The problem is that you cannot reliably pass the current activity to the popup window, because you have no control over the current activity. It looks like there might be a unreliable way to get the current activity, but I don't recommend that.

The way I fixed it for my app was to not use the popup window, but instead make my own through the window manager.

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

If you want this to look like a popup window, just add a transparent gray view as the background and add a onClickListener to it to remove the view from the windowManager object.

I know this isn't as convenient as a popup, but from my experience, it is the most reliable way.

and don't forget to add permission in your manifest file

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

If you're using getApplicationContext() as Context in Activity for the dialog like this

Dialog dialog = new Dialog(getApplicationContext());

then use YourActivityName.this

Dialog dialog = new Dialog(YourActivityName.this);

This error happens when you are trying to show pop-up window too early, to fix it, give Id to the main layout as main_layout and use the below code:

Java:

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

Kotlin:

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

Credit to @kordzik

You should not put the windowManager.addView in onCreate

Try to call the windowManager.addView after onWindowFocusChanged and the status of hasFoucus is 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.
}

I was getting this error while trying to show DatePicker from Fragment.

I changed

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

to

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

and it worked just fine.

In my case, I was inflating a PopupMenu at the very beginning of the activity i.e on onCreate()... I fixed it by putting it in a 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);

If you use another view make sure to use view.getContext() instead of this or getApplicationContext()

  • If you coding on Kotlin and using Viewbinding system.
  • Try so: binding.root.context.
  • It helped me to run AlertDialog.