There are some parts of the framework which are not quite clear to me yet. I am well known with the flow of an input event (Kernel -> Eventhub -> InputReader -> InputDispatcher -> ...).

Situation

(Requirements: Handle input keys without changing the Android Framework.)
I want to handle key events coming from a device (keyboard/gamepad/controller/...) but there are some requirements. For one, I don't want to change the Android framework. This means, I don't want to extends the WindowManagerPolicy and its functions like interceptKeyBeforeDispatching where the home-key is being handled. This would result in the key event being dispatched into the application layer which is fine. The downside is, I have another tricky requirement here.
Example: When I am playing Angry Birds and I press my GoToAlpha-button on my connected input device, the Alpha-application has to start. Angry Birds has no clue which button GoToAlpha is, will not handle/recognize it and there will be for example no intent broadcasted to start my Alpha-application.

Question

Is there a way to handle my (custom) key event after it is being dispatched, knowing that the application in the foreground can not handle the key?

My (failed) solutions

Create a service which will handle the key events. This is not possible because an application like Angry Birds will not bind to my service and the key event will not be caught inside my service. If I am wrong, please provide more information :).

Create an external library where I allow my application's activities to inherit from my own ActivityBase. All the key events and there default behavior can be handled here. Downside, existing applications will not support my custom key events because they don't use the library.

Extend the framework would be in my eyes the cleanest solution but that will result in not meeting my requirement.

Any help or useful information would be appreciated

Extra

If the first question could be solved on one way or another.. I want
to customize my Intent behind the GoToAlpha-button. This means.. By
default the Alpha-application will be started but after the user has
customized it, the Beta-application will be started from now on.. Any
thoughts?

Wouldn't it be weird if it is possible to capture key events from other applications? I guess this would be a security risk
–
BoyAug 14 '12 at 8:25

True. Once the key event leaves the framework, it goes to only one application and is handled there. If not, it is returned to the framework. This would mean that there is no solution that would meet both my requirements?
–
DroidBenderAug 14 '12 at 8:32

In my opinion there will probably be no way, just because of the security issue: handling key events while your app has no focus. Maybe the only way would be if you implement an Android keyboard (I have no knownledge on that)? This should be able to handle key events (and users are also pointed on this security risk when you select a 3rd party keyboard)
–
BoyAug 14 '12 at 8:45

2 Answers
2

Using the InputMethodService will not provide me with enough freedom and functionality to handle my problems.

My Solution / Compromise

Within the Android Framework, there is a PhoneWindowManager which is responsible for handling InputEvents. The WindowManagerService which is started by the SystemServer, is owner of this manager and creates an instance.

By creating my own custom WindowManager and let it inherit from Android's PhoneWindowManager, I don't lose any default functionality and this allows me to add my own implementation within this class. This results is adding a new file to the framework and changing only one line inside the Android Framework: The WindowManagerService will not create a PhoneWindowManager, but will create a CustomPhoneWindowManager (extends PhoneWindowManager).

If anyone sees a better solution or has any specific thoughts about my compromis, don't hesitate to comment. :)

One more idea. I heard about it somewhere, but I can't remember where and what were the results. You can try to create transparent window which will sit on top of all windows, so you will receive all clicks/keyboard typing. And now, you will need to send it to the application is right behind yours. This way you can change your problem from "receiving all input" to sending clicks to other app.
–
Victor RoninAug 23 '12 at 17:20

1

That's a rather dangerous approach Victor, wouldn't that clash with some security standards :)? Another problem, there are InputEvents (similar to KEYCODE_HOME) that are caught inside the Framework and are not dispatched to the Application Layer. These events wouldn't even arrive in the invisible window. Thanks for your support!
–
DroidBenderAug 24 '12 at 7:18

Oh.. yeah.. It is dangerous :) However, I believe that business value trumps security concerns 80% of time. I have very limited insight in whole InputMethodService (just know about it's existence).
–
Victor RoninAug 24 '12 at 15:19

@DroidBender I have scrutinized WindowManagerService but have not found any PhoneWindowManager "creat"ed. Only two static flags were accessed. Can you please point me to the PhoneWindowManager in the WindowManagerService?
–
CampiadorNov 24 '14 at 12:44