Back pressed events with system alert window

后端 未结 10 1426
南笙
南笙 2021-01-03 03:21

I need to dismiss system alert window on back pressed and home button event.I have tried with onKeyEvent but in vain. As we can\'t cap

10条回答
  •  抹茶落季
    2021-01-03 04:08

    Since it's a service that hosting an overlay window, It's a bit tricky solution but it is possible.

    You should handle these 2 cases separately (overriding home button press, and back button press).


    1. Overriding home button press:

    Create this HomeWatcher class which contains a BroadcastReceiver that will notify when home button was pressed. Register this receiver only when your window comes up.

    Android: associate a method to home button of smartphone

    Inside your service onCreate method use this:

    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. Overriding back button press:

    The idea is creating an empty layout as a data member of your window class, and attach your view to it (even if its an inflated XML layout).

    For example, this is gonna be your window class:

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

    And now create the MyLayout class to override the back button press:

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

    I know it's a bit complicated as I said since it's a system alert window hosted by a service, BUT it's working. I have the same issue as well and it has been solved exactly like that. Good luck.

提交回复
热议问题