Невозможно добавить нулевой токен окна; работает ли ваша деятельность?
Я хочу показать пользовательское всплывающее меню, когда пользователь нажимает на плавающий значок
значок float создается с помощью службы, и у меня нет активности
это мой плавающий код значка
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?
но у меня нет активности?!
я хочу, чтобы всплывающее меню отображалось после щелчка пользователем по значку float; но всплывающее меню может показывать только текст;
как я могу показать всплывающее меню с иконками?
Ответы
Ответ 1
У меня была такая же проблема, как и у вас, похоже, вы использовали учебник с 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
Если вы используете getApplicationContext()
в качестве Context
в Activity для такого диалога, как этот
Dialog dialog = new Dialog(getApplicationContext());
затем используйте YourActivityName.this
Dialog dialog = new Dialog(YourActivityName.this);
Ответ 3
Вам нужно передать свою активность в конструкторе
PopupWindow popupWindow = new PopupWindow(YourActivity.this)
Ответ 4
Эта ошибка возникает, когда вы пытаетесь показать popUpWindow слишком рано, чтобы исправить это, присвоить идентификатор основной раскладке как main_layout
и использовать приведенный ниже код
Джава:
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
Ответ 5
Используйте этот Dialog dialog = new Dialog(theActivity.this);
Вместо Dialog dialog = new Dialog(getApplicationContext);
или Dialog dialog = new Dialog(context);
Ответ 6
PopupWindow
может быть привязан только к Activity
. В вашем случае вы пытаетесь добавить PopupWindow
в service
, что неверно.
Чтобы решить эту проблему, вы можете использовать пустой и прозрачный Activity
. При щелчке значка с плавающей точкой запустите Activity
и onCreate
Activity
, покажите PopupWindow
.
При увольнении PopupWindow
вы можете finish
прозрачный Activity
.
Надеюсь, это поможет вам.
Ответ 7
У меня была та же проблема, я исправил это с помощью решения @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 я проверил, показывает ли всплывающее окно, ноль или нет.
@Override
protected void onDestroy() {
super.onDestroy();
if (popupWindow.isShowing())
{
popupWindow.dismiss();
popupWindow=null;
}
}
Ответ 8
используйте YOURACTIVITY.this вместо getApplicationContext()
Ответ 9
Эта ошибка вызвана передачей неверного контекста.
Вы должны передать свою активность как контекст, getApplicationContext()
не будет работать.
Следовательно, приведите ваш контекст к деятельности.
В Котлине
context as HomeActivity
Ответ 10
Если вы используете getBaseContext() или getApplicationContext() в качестве контекста для диалога, как это
Dialog dialog = new Dialog(getBaseContext());
или же
Dialog dialog = new Dialog(getApplicationContext());
затем используйте YourActivityName.this
Диалог диалога = новый диалог (YourActivityName.this);
Ответ 11
Вы не должны помещать windowManager.addView в onCreate
Попробуйте вызвать windowManager.addView
после onWindowFocusChanged
, и статус hasFoucus
будет истинным.
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//code here
//that you can add a flag that you can call windowManager.addView now.
}