2

As you know about the activity's life cycle, when another activity (from the same application or from another application) comes in foreground, the background activity goes to onPause state.

I want my activity when it comes to foreground to act as if it's a floating window, that doesn't interrupt other running application.

Is there a flags to set for my activity to be like that?

I thought about using a "Service" as a full screen floating window, but "Service" can't consume pressed hardware buttons (As back key button), and that's why I need to use an activity.

Edit:

The question is still open, and what is needed is:-

1- How to consume used buttons as (Back, Menu, etc.) when my Service in full screen mode and in foreground?

OR

2- How to avoid the foreground activity to go to onPause state when my activity becomes over / on top of it?

I'll reward a 150 points to the answer that solves my problem.

Thank you :)

Ashraf Alshahawy
  • 1,139
  • 1
  • 14
  • 38

1 Answers1

2

If you want to maintain the previous app in the foreground and have your app appear over the top, you could use the SYSTEM_ALERT_WINDOW mechanism. This is what Facebook Messenger ("chat heads"), Evernote, Pocket etc use to draw a window over the top of apps in the foreground, normally briefly to show the user that an action has taken place in an app that's not currently in the foreground.

It's not something create an entire app in however, as this would break how a user expects an Android app to work, and could cause you some usability issues down the road. It's also known to be open to abuse, so some users are averse to app that make use of it, which could lose your users' trust if it's not clear why you want your app to work in that way.

But for cases where you want to provide user with some action option that can't be effectively done as a rich notification, it serves a purpose.

Here's an example of how to implement it. In addition, a longer article explaining what it is and how it works.


Updated Info in response to comments (put here so I can use markdown)

In the example there is an Activity called Main that only exists to start the service, so the Service belongs to the app's package.

Permissions on Android are handled per-package, so you need to declare the permissions that you want a Service to have access to in the AndroidManifest.xml file of the project that the Service belongs to.

Once running, OverlayShowingService gets a handle on the WindowManager for the current display. The system's WindowManager is run as a system service - WINDOW_SERVICE, and is what the OS uses to display apps and Activities that are currently running.

Each app effectively runs within its own Window (which is incidentally why Android N's new multi-window feature can let more than one app run concurrently without needing to change the app lifecycle - they already exist in separate windows, just on top of each other rather than side by side).

So once running, OverlayShowingService programmatically creates the View to be shown over the top (in the case of the example, a Button), and adds that view to the system-wide WindowManager by calling addView(..):

wm.addView(overlayedButton, params);

This immediately adds the View to the screen at the coordinates specified by x and y.

If the Service did not have the SYSTEM_ALERT_WINDOW permission at this point, it would not be allowed to add the view to the system-level WindowManager, as otherwise any malicious or badly made app could add a view to the screen over the top of all other running apps, and capture screen inputs.

Re: How Notifications work

They are also created using a system service. Notifications are added in a similar way to the way that Views are added to the WindowManager:

If you want to make something equivalent to a custom Notification shade, you'll need to create a system service of your own, which is going down the route of compiling your own ROM and replacing parts of the OS for a specific purpose. If you get to that point, your users will need to be rooted and/or running your custom ROM.

Update - Worked Example

I had a spare few minutes this morning so put together a working demo of intercepting the back button from a SYSTEM_ALERT_WINDOW. You can clone it and run it directly to see how the interception works, and there are a few brief comments in the code to explain the steps.

Only the back button is intercepted, but you can use the same method to handle other key types. Be aware however that there are so many different types of Android device out there with hardware and software keys, running on different versions of Android, that it may not be possible to make a solution that works reliably on every device. Especially for things like the menu button, which most newer devices no longer have; when you see the menu dots in most apps, it's handled within the app itself rather than as a system-level interaction, so unless you modify those apps directly, that action cannot be intercepted.

Have a good one.

MattMatt
  • 2,242
  • 33
  • 30
  • Thank you @MattMatt for your answer, help and advice, really appreciated :) I'll check the examples your provided and come back to accept your answer or ask for more help :) – Ashraf Alshahawy Aug 06 '16 at 20:45
  • Hi again, I read the links you provided and got a bit confused, I hope you can help me for a better understanding. The example uses a Service as a full screen overlay not using an activity, why would it need this permission? – Ashraf Alshahawy Aug 07 '16 at 00:00
  • My second question, how to apply the Type_System_Alert on my activity layout? – Ashraf Alshahawy Aug 07 '16 at 00:07
  • BTW, how the pull down menu (Notifications Menu) are created? is it made of a Service or Activity? it doesn't cause the foreground application to pause, yet it captures the back button event? – Ashraf Alshahawy Aug 07 '16 at 14:09
  • Thank you so much for your help, really appreciated :) Could you please check my question, I made an edit with a more direct question about my needs. In a nutshell, is it possible to consume pressed buttons (back key, menu key and power key etc.) when my service is on top of another application, and how if it is possible? – Ashraf Alshahawy Aug 07 '16 at 22:25
  • I really can't thank you enough, and the few minutes are really well spent :) P.S: I'm not concerned about the software keys (Part of the applications codes), but it's really great that you brought my attention to them too. – Ashraf Alshahawy Aug 08 '16 at 21:43
  • I'm concerned about intercepting hardware keys, I tried back / options / volumes and they have been consumed (Thumb up), but for Menu button and Lock button they were not consumed (I'm talking about the hardware buttons), any way to consume them as well ???? – Ashraf Alshahawy Aug 08 '16 at 21:44
  • The question about intercepting the power button (/screen lock button) has already been covered in this answer: http://stackoverflow.com/questions/10077905/override-power-button-just-like-home-button. It's a very low level function, so intercepting the power button or task switcher button (what I think you mean by menu button?) is not possible whether or not your app is a system alert. – MattMatt Aug 09 '16 at 00:19
  • What do you think about this approach to consume Home / Task Switcher button? https://github.com/shaobin0604/Android-HomeKey-Locker Will it be compatible with different Android versions & devices models? https://github.com/shaobin0604/Android-HomeKey-Locker/blob/master/HomeLockerLib/src/main/java/io/github/homelocker/lib/HomeKeyLocker.java – Ashraf Alshahawy Aug 09 '16 at 13:47
  • 1
    By looking at the issues on that GitHub project, it is very device-specific (https://github.com/shaobin0604/Android-HomeKey-Locker/issues/10), so no it wont work for all devices. It's a fairly large security risk for an app to be able to replace your navigation bar. There is SYSTEM_UI_FLAG_HIDE_NAVIGATION which allows apps like games to temporarily hide those buttons, but they can be swiped back in, and this only works if your app is launched as a fullscreen activity, it can't be done from a dialog, even a system alert one. – MattMatt Aug 10 '16 at 14:23
  • Thank you Matt for all the help you provided, really appreciated :) And allow me to gift you a 150 points as a simple way of saying thank you! – Ashraf Alshahawy Aug 10 '16 at 20:36
  • Much appreciated, hope you get your app working the way that you'd like. – MattMatt Aug 11 '16 at 00:44
  • Thanks to your help It's almost there, The thing is, when my System Service is on top of the foreground app and user presses the hardware task switcher button, it causes the idle / home screen to be on foreground and my System service still on top and capture the touch events. Is there a way to get notified when such a change takes place? – Ashraf Alshahawy Aug 12 '16 at 01:49
  • Another question, on Stock Android (For sorry I have only Samsung models) there's a soft keys for (Back, options menu, home), would these keys be functioning / interactive when my service is on foreground? or any touch will be consumed by my service (Just as the back and options menu hardware keys are consumed) ? Knowing that I'm using WindowManager.LayoutParams.TYPE_PHONE – Ashraf Alshahawy Aug 12 '16 at 01:57
  • 1
    Never tried that so am not sure. Best bet would be to write an automated test then submit it to a cloud test lab such as Firebase or AWS Device Farm; best way to prove out unconventional approaches is to test on real hardware. – MattMatt Aug 14 '16 at 15:24