Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 带有系统警报窗口的反按事件_Android_Back Button_Android Homebutton - Fatal编程技术网

Android 带有系统警报窗口的反按事件

Android 带有系统警报窗口的反按事件,android,back-button,android-homebutton,Android,Back Button,Android Homebutton,我需要在按下back和home按钮事件时关闭系统警报窗口。我尝试了onKeyEvent,但没有成功。由于我们无法在服务中捕获backpressed事件,如何实现这一点?使用下面的代码 public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { exitByBackKey(); //moveTaskToBack(false);

我需要在按下
back
home
按钮事件时关闭系统警报窗口。我尝试了
onKeyEvent
,但没有成功。由于我们无法在服务中捕获
back
pressed事件,如何实现这一点?

使用下面的代码

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        exitByBackKey();

        //moveTaskToBack(false);

        return true;
    }
    return super.onKeyDown(keyCode, event);
    }

    protected void exitByBackKey() {

    AlertDialog alertbox = new AlertDialog.Builder(this)
    .setMessage("Do you want to exit application?")
    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {

        // do something when the button is clicked
        public void onClick(DialogInterface arg0, int arg1) {

            finish();
            //close();


        }
    })
    .setNegativeButton("No", new DialogInterface.OnClickListener() {

        // do something when the button is clicked
        public void onClick(DialogInterface arg0, int arg1) {
                       }
    })
      .show();

    }
  public void onBackPressed()
  {
        super.onBackPressed();
  }

使用以下方法处理按下的后退按钮

  public void onBackPressed()
  {
        super.onBackPressed();
  }
在您的活动中声明这一点。在android中,super.OnBackPressed自动回调方法。它肯定会取消您的对话

  public void onBackPressed()
  {
        super.onBackPressed();
  }
此外,您的对话框必须如下所示

  public void onBackPressed()
  {
        super.onBackPressed();
  }
AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder1.setMessage("TEST DIALOG.\n");
    builder1.setPositiveButton("Ok",
            new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                Toast.makeText(MainActivity.this, "This Is test Dialog", Toast.LENGTH_SHORT).show();
        }
    });
    AlertDialog alert11 = builder1.create();
    alert11.show();
或者您可以设置负按钮

  public void onBackPressed()
  {
        super.onBackPressed();
  }

希望这有帮助

定义自定义布局并覆盖dispatchKeyEvent,例如:

  public void onBackPressed()
  {
        super.onBackPressed();
  }
public class CustomSystemAlertWindow extends FrameLayout {

    public static final String TAG = "CustomSystemAlertWindow";

    private WeakReference<Context> mContext;

    public CustomSystemAlertWindow(Context context) {
        super(context);

        mContext = new WeakReference<Context>(context);

        // Set a background color to identify the view on the screen
        this.setBackgroundColor(getResources().getColor(android.R.color.holo_red_light));
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Log.d(TAG, "back button pressed");

            if (mContext != null && mContext.get() != null) {
                WindowManager wm = (WindowManager) mContext.get().getSystemService(Context.WINDOW_SERVICE);
                wm.removeView(this);
            }

            return true;
        }

        return super.dispatchKeyEvent(event);
    }
}
当您按下后退按钮时,视图将消失

  public void onBackPressed()
  {
        super.onBackPressed();
  }
  • 通过活动显示警报窗口,以便您可以检测到它
  • 执行代码以轻松检测按下的后退按钮或主页按钮

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    public class alertPopup extends Activity {
    
        Context context;
        final AlertDialog alertDialog;
        String TAG = "your Activity Name"
        boolean homePressed = false; // to detect the Homebutton pressed
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
         AlertDialog.Builder builder = newAlertDialog.Builder(YourActivity.this, R.style.AppCompatAlertDialogStyle);
         builder.setTitle("AlertDialog Title");
                ..........
                ....... // Build ur AlertDialog
    
         alertDialog= builder.create();
         alertDialog.show();
    
    
             //to detect Alert Dialog cancel when user touches outside the Dialog prompt
         alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    Log.v(TAG,"Alert Dialog cancelled when user touches outside the Dialog prompt")
                }
            });
    
        }
    
    
        @Override
        public void onBackPressed()
        {
        Log.v(TAG,"Back Button Pressed");
         super.onBackPressed();
    
         alertDialog.dismiss();   //dismiss the alertDialog
         alertPopup.this.finish();  // Destroy the current activity
    
         homePressed = false;
        }
    
        @Override
        public void onResume() {
            super.onResume();
            homePressed = true; // default: other wise onBackPressed will set it to false
        }
    
    
        @Override
        public void onPause() {
            super.onPause();
            if(homePressed) { 
    
            alertDialog.dismiss();   //dismiss the alertDialog
            alertPopup.this.finish();  // Destroy the current activity
    
            Log.v(TAG, "Home Button Pressed"); }
        }
    
    
        public void onDestroy(){
    
            super.onDestroy();
        }
    
    
    }
    
    注:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    在Android清单中添加此权限以显示警报窗口

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
    
    

    快乐编码:)

    因为这是一个托管覆盖窗口的服务,这是一个有点棘手的解决方案,但它是可能的

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    您应该分别处理这两种情况(覆盖home按钮按下和back按钮按下)

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    

    1。覆盖主页按钮按下:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    创建此HomeWatcher类,该类包含一个BroadcastReceiver,当按下home按钮时将发出通知。仅当窗口打开时才注册此接收器

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    在服务onCreate方法中,请使用以下方法:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    HomeWatcher mHomeWatcher = new HomeWatcher(this);
    mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
        @Override
        public void onHomePressed() {
            yourWindow.hide()  //means: windowManager.removeView(view);
        }
        @Override
        public void onHomeLongPressed() {
        }
    });
    mHomeWatcher.startWatch();
    

    2。覆盖后退按钮按下:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    其思想是创建一个空布局作为window类的数据成员, 并将视图附加到它(即使它是一个膨胀的XML布局)

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    例如,这将是您的窗口类:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    public class MyWindow
    {
        private WindowManager windowManager;
        private WindowManager.LayoutParams params;
        private View view;
    
        // Add this empty layout:
        private MyLayout myLayout;
    
        public MyWindow()
        {
            windowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.your_original_window_layout, null);
    
            // Add your original view to the new empty layout:
            myLayout = new MyLayout(this);
            myLayout.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        }
    
        // And show this layout instead of your original view:
        public void show()
        {
            windowManager.addView(myLayout, params);
        }
    
        public void hide()
        {
            windowManager.removeView(myLayout);
        }
    }
    
    现在创建MyLayout类以覆盖按back按钮:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    public class MyLayout extends LinearLayout
    {
        private MyWindow myWindow;
    
        public MyLayout(MyWindow myWindow)
        {
            super(myWindow.context);
    
            this.myWindow = myWindow;
        }
    
    
        @Override public boolean dispatchKeyEvent(KeyEvent event)
        {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
            {
                if (event.getAction() == KeyEvent.ACTION_DOWN  &&  event.getRepeatCount() == 0)
                {
                    getKeyDispatcherState().startTracking(event, this);
                    return true;
    
                }
    
                else if (event.getAction() == KeyEvent.ACTION_UP)
                {
                    getKeyDispatcherState().handleUpEvent(event);
    
                    if (event.isTracking() && !event.isCanceled())
                    {
                        // dismiss your window:
                        myWindow.hide();
    
                        return true;
                    }
                }
            }
    
            return super.dispatchKeyEvent(event);
        }
    }
    
    我知道这有点复杂,因为它是一个由服务托管的系统警报窗口,但它正在工作。我也有同样的问题,它已经完全解决了。
    祝你好运。

    你需要覆盖
    onBackPressed
    方法

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    @Override
    public void onBackPressed() {
    
        super.onBackPressed(); // remove this if u want to handle this event
    }
    

    我知道您正在使用
    权限来显示浮动视图

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    使用浮动视图,您可以截获
    back
    按钮按下,但无法截获
    home
    按钮按下(android不会让您这样做,主要是因为安全原因)

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    要截取
    back
    按钮,请在充气浮动视图时添加包装。 您的包装应该如下所示:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
        // Wrapper for intercepting System/Hardware key events
        ViewGroup wrapper = new FrameLayout(this) {
            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {
                if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
                    hideAddNotesFloatingView();
                    return true;
                }
                return super.dispatchKeyEvent(event);
            }
        };
    
    private void addFloatingView() {
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                0,
                PixelFormat.TRANSLUCENT);
    
        params.gravity = Gravity.CENTER | Gravity.LEFT;
        params.x = 0;
        params.y = 0;
    
        // Wrapper for intercepting System/Hardware key events
        FrameLayout wrapper = new FrameLayout(this) {
            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {
                if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
                    // Add your code for handling the back button press
                    return true; // Return true means that the event was handled
                }
                return super.dispatchKeyEvent(event);
            }
        };
    
        mAddNoteFloatingView = mInflater.inflate(R.layout.floating_view, wrapper);
    
        mWindowManager.addView(mAddNoteFloatingView, params);
    }
    
    然后将其作为根添加到浮动视图中:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
            mAddNoteFloatingView = mInflater.inflate(R.layout.floating_add_note, wrapper);
    
    我的完整代码如下所示:

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
        // Wrapper for intercepting System/Hardware key events
        ViewGroup wrapper = new FrameLayout(this) {
            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {
                if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
                    hideAddNotesFloatingView();
                    return true;
                }
                return super.dispatchKeyEvent(event);
            }
        };
    
    private void addFloatingView() {
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                0,
                PixelFormat.TRANSLUCENT);
    
        params.gravity = Gravity.CENTER | Gravity.LEFT;
        params.x = 0;
        params.y = 0;
    
        // Wrapper for intercepting System/Hardware key events
        FrameLayout wrapper = new FrameLayout(this) {
            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {
                if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
                    // Add your code for handling the back button press
                    return true; // Return true means that the event was handled
                }
                return super.dispatchKeyEvent(event);
            }
        };
    
        mAddNoteFloatingView = mInflater.inflate(R.layout.floating_view, wrapper);
    
        mWindowManager.addView(mAddNoteFloatingView, params);
    }
    
    很简单。遵循以下步骤:
  • 动态创建类似相对布局、线性布局或框架布局的视图。2.在创建视图时覆盖
    dispatchKeyEvent
  • 使用
    addView()
    方法将原始视图添加到此动态创建的视图中
  • 将动态创建的视图添加到您的窗口管理器或警报对话框中
    除了@Eliran Kuta的解决方案之外,这是对后退按钮的更简单的回答

      public void onBackPressed()
      {
            super.onBackPressed();
      }
    
    val view = getAlertView()
    val windowParam = WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT, // whatever
        WindowManager.LayoutParams.WRAP_CONTENT, // whatever
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // use WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY before Oreo
        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, // whatever
        PixelFormat.TRANSLUCENT // whatever
    )
    
    view.isFocusableInTouchMode = true
    view.setOnKeyListener { view, keyCode, event ->
        when (keyCode) {
            KeyEvent.KEYCODE_BACK -> {
                // do your work here
                true
            }
            else -> false
        }
    }
    
    val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
    windowManager.addView(view, windowParam)
    


    您可以通过覆盖onBackButtonpressed方法来实现这一点。您可以添加显示对话框的代码吗?系统警报窗口是我用来绘制其他应用程序的窗口。我想处理关键事件,例如从辅助功能服务中按下BackButton和home按钮。请注意,问题是关于“系统警报窗口”这是从服务开始的(不涉及任何活动)。是的,我知道。如果要检测按下的后退按钮和主页按钮,应通过服务显示活动。还有别的办法吗?@yaemi会尽快检查的。我不知道还有没有别的办法,这就是为什么我要问。。。另外,我将尝试反编译FB messanger应用程序,看看他们是如何做到的。我给出了一个我正确知道的解决方案。不要在你不知道的情况下问问题。发布你的代码,否则很难帮助你。既然这个问题不是你的,你可以把它贴在网上或类似的服务上。类似的就不一样了。答案的代码与您的代码有什么区别?我的布局是从预定义的XML扩展而来的,它的根是“CustomsystemAlertWindow”,我刚刚尝试使用XML,它对我有效。你确定你正在使用与答案相同的标志来创建
    WindowManager.LayoutParams
    ?谢谢,我会尽快尝试。你可以下载我的应用程序,了解其中的系统警报windows行为,如果你愿意,可以问我更多问题,我会给你一些提示和代码示例。基本上,sys alert overlay窗口需要大量的维护、管理和额外的维护,因为它们不是活动。在MyWindow类->什么是“上下文”中,声明中没有变量这不是homebutton的重写。。。但它是一个延伸。。。homebutton操作也执行以下操作:-(dispatchKeyEvent从未调用您将mAddNoteFloatingView添加到windowManager而不是wrapper,为什么?wrapper是最上面的视图,它应该添加到WM中,不是吗?@shantanu在这种情况下,
    mAddNoteFloatingView
    wrapper
    都引用了相同的视图。
    LayoutInflater.inflate
    返回:膨胀层次结构的根视图。如果提供了根视图,则为根视图;否则为膨胀XML文件的根视图