Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Back pressed events with system alert window

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 capture the back pressed event in a service, how to achieve this?

like image 607
user3595323 Avatar asked Jun 16 '15 07:06

user3595323


People also ask

How can I tell if my Android back button is pressed?

In order to check when the 'BACK' button is pressed, use onBackPressed() method from the Android library. Next, perform a check to see if the 'BACK' button is pressed again within 2 seconds and will close the app if it is so.

How to handle Back press in Android fragment?

In those cases we can set the isEnabled variable to false and call the onBackPressed() method on activity again manually: Well, it's much easier to achieve this by registering OnBackPressedCallback instances for handling the ComponentActivity. onBackPressed() callback via composition.

Do all Android devices have Back button?

All Android devices provide a Back button for this type of navigation, so you should not add a Back button to your app's UI. Depending on the user's Android device, this button might be a physical button or a software button.

What is AlertDialog in Android?

Android AlertDialog can be used to display the dialog message with OK and Cancel buttons. It can be used to interrupt and ask the user about his/her choice to continue or discontinue. Android AlertDialog is composed of three regions: title, content area and action buttons.


1 Answers

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.

like image 79
Eliran Kuta Avatar answered Oct 13 '22 02:10

Eliran Kuta