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?

- 5,445
- 7
- 41
- 72

- 59
- 1
- 3
-
1you can do it by overriding the **onBackButtonpressed** method – SAM Jun 16 '15 at 07:16
-
Can you add the piece of code that display the dialog? – Luca Jun 16 '15 at 07:16
-
System alert window is the one which I use to draw over other apps.I want to handle the key events like back pressed,home button pressed from the accessibility service. – user3595323 Jun 16 '15 at 07:26
10 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.

- 1
- 1

- 4,148
- 3
- 24
- 28
-
-
1You can download my app to get impressed the system alert windows behaviors in it, and ask me more questions if you like, and i'll give you some hints and code samples. Basically, sys alert overlay windows needs a lot of care, management and extra maintenance since their are not activities. https://play.google.com/store/apps/details?id=com.accio.app – Eliran Kuta Nov 08 '15 at 23:21
-
in MyWindow class -> what is the "context" there is no variable in the declaration – Maurice Raguse Jul 22 '16 at 12:14
-
this is not an override for the homebutton... but its an extension... the homebutton action performs too :-( – Maurice Raguse Jul 22 '16 at 15:22
-
2
-
dispatchKeyEvent is perfect, but why onKeyUp and onKeyDown are never called. – SDJSK Sep 11 '17 at 14:12
-
Your MyWindow class doesn't have field name context,you should pass view context ? – yarin Sep 27 '18 at 06:20
use below method to handle back button pressed.
public void onBackPressed()
{
super.onBackPressed();
}

- 319
- 2
- 21
You need to overwrite the onBackPressed
method.
@Override
public void onBackPressed() {
super.onBackPressed(); // remove this if u want to handle this event
}

- 10,564
- 3
- 29
- 62

- 844
- 13
- 17
I understand that you are using the <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
permission for showing a floating view.
Using a floating view you can intercept the back
button press, but the home
button press cannot be intercepted (android won't let you primarily because of security reasons).
To intercept the back
button press you need to add a wrapper when you inflate your floating view.
Your wrapper should look like this:
// 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);
}
};
Then you add it to your floating view as a root:
mAddNoteFloatingView = mInflater.inflate(R.layout.floating_add_note, wrapper);
My complete code looks like this:
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);
}

- 988
- 12
- 18
-
you are adding mAddNoteFloatingView to windowManager instead of wrapper, why? wrapper is the top most view, it should be added to WM isn't it? – shantanu May 21 '17 at 20:01
-
@shantanu In this case, `mAddNoteFloatingView` and `wrapper` are referring to the same view. `LayoutInflater.inflate` returns: "The root View of the inflated hierarchy. If root was supplied, this is the root View; otherwise it is the root of the inflated XML file." – Vlad May 25 '17 at 14:40
Use the code below
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();
}

- 3,572
- 5
- 38
- 69

- 12,540
- 3
- 28
- 48
@Override
public void onBackPressed()
{
super.onBackPressed();
}
Declare this on your activity. super.OnBackPressed automatically calls back method in android. it will surely cancel your dialog.
in addition, your dialog must look like this.
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();
or you can set Negative button..
Hope this helps!

- 1
- 4
Define a custom layout and override dispatchKeyEvent
, for example:
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);
}
}
Then add the view with this code:
CustomSystemAlertWindow customSystemAlertWindow = new CustomSystemAlertWindow(context);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
wm.addView(customSystemAlertWindow, params);
When you press the back button the view will dismiss.

- 32,270
- 15
- 87
- 94
-
Post your code otherwise is really difficult to help you. Since the question is not yours you can post it on http://pastebin.com or a similar service. – Mattia Maestrini Nov 04 '15 at 18:50
-
Similar is not the same. What's the difference between the answer's code and yours? – Mattia Maestrini Nov 04 '15 at 19:33
-
My layout is inflated from a predefined XML, which its root is "CustomsystemAlertWindow" – Yaadm Nov 05 '15 at 07:29
-
I just tried with the XML and it works for me. Are you sure that you are using the same flags of the answer to create the `WindowManager.LayoutParams`? – Mattia Maestrini Nov 05 '15 at 08:43
- Show the Alert window through the Activity so you can detect it.
Implement the code to detect easily Back Button or Home Button pressed.
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();
}
}
Note:
Add this Permission in Android Manifest to show the alert Window .
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Happy Coding :)

- 1,382
- 2
- 15
- 28
-
Please note that the question is about "system alert window" that is being started from a service (no activity involved). – Yaadm Nov 04 '15 at 12:15
-
Yes, I know. if you want to detect Back Button & Home Button pressed, You should show activity through the service. Is any other way is there?@Yaadm – Venkatesh Selvam Nov 04 '15 at 12:19
-
I will check it out ASAP. I do not know if there is another way, that's why i'm asking ... Also, I Will try to decompile FB messanger app to see how they did it. – Yaadm Nov 04 '15 at 12:27
-
Ok. I give one of the solution that I know correctly. Dont ask questions without you know properly. – Venkatesh Selvam Nov 04 '15 at 12:31
It's simple. Follow these steps:
- Create a view like Relative Layout, Linear Layout or Frame Layout Dynamically. 2. Override the
dispatchKeyEvent
while creating the view. - Add your original view into this dynamically created view with
addView()
method. - Add the dynamically created view to your Window Manager or Alert Dialog whichever you want.

- 77
- 1
- 8
In addition to @Eliran Kuta's solution, this is more simple answer for Back button.
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)

- 1,459
- 2
- 23
- 42