I'm using the GreenRobot EventBus lib on Android.
Could someone tell me, what's best practice for calling the removeStickyEvent(...)? Up-Action, back button pressed, ...?
Thank you guys.
To answer your question about the Event object staying in memory: only the last sticky event posted stays in memory for each given type.
Take a look at the source here.
Basically to summarize: Eventbus keeps a map of stickyEvents with the key being class type and the value being the field. So when a new sticky event is posted with EventBus.postSticky(event) the event posted overwrites the old event. So I think you are safe from building up many sticky events.
I was worried about that also. I wish it was explained better in the docs but at least its open source so we can look inside and see whats happening.
I guess to answer your question more completely. When should you remove a sticky event? When you don't want calls to get the sticky event to not return anything. When exactly that is is an application specific requirement. Good luck.
Related
I am keen to know how Android's event handling and dispatching work. Code walk-through is an option, of course. But, if there's any document one can refer me to, that'd be great.
As a concrete example, consider a click event on a button. How does that click propagate within the framework? In case of multiple event occurring one after another, is there some sort of event queue, and a dispatcher calling methods on the events in the queue? What goes on under the hood? If not any document, if one can point me to the relevant part of the code I should look at, that'd be great.
According to my knowledge the parent is the first asked, if he can handle the event, otherwise he asks his childs who can handle this event ?
https://developer.android.com/training/gestures/viewgroup
Let me first start off by explaining my problem -
I am working on an application that is lying between the a system activity (com.google.tv.player.PlayerActivity) and user-space.
The system activity has a certain behaviour that happens when I press the MENU button. Because of my newly deployed application in-between, I am trying really hard to send that MENU keyevent to the "activity above me". Otherwise, it's just intercepted and consumed by my app.
I have no references to the activity. I have somewhat examined it's old code to figure out that the menu button press eventually calls void openOptionsMenu(); and most attempts have been fruitless. Here's a short list of what I tried, I catch the MENU press in MyActivity.onKeyDown() and tried doing the following
super.onKeyDown(keyEvent); got me really nowhere.
dispatching the key with dispatchKey caused stackoverflows depending on use
dispatching the event with menuEvent.dispatch((Activity) getRefByReflection());
grabbing the WindowManager and dispatchin the key to it.
overriding dispatchKey obviously, which just ended in a stackoverflow :)
I have read online that there is/was a way to dispatch a key via a PID - I can get the player's pid, but lack the method to use to dispatch the key! I simply have no dispatchKey(KeyEvent event, int recvPID, int recvUID) that they have seem to be using.
I am also aware that I will get a few faking user-input is shaky and it's better to refactor the button behaviour than to simulate pressing it and I agree but, I am in no position to even get the source, much less afford changes to it. Reversing it would be an option, if only to know what members I need to reflect against.
To me, it seems that there simply is no way to route the keypress as a passthru and let it sink into the activity below, so I really do have to SEND / DISPATCH it somehow. Any help would be really appreciated.
Once again, I'm looking for a way to allow pass-through of keypresses, all for sake of opening a menu that i have no way of reaching programatically through my code.
The last, not-completely-explored option is the InputManager's injectInputEvent method - but without a way of 'directing' it anywhere, I do not know if it'll bare fruit to explore that venue thoroughly. Then again, it's the only thing left to explore.
It might be worth noting that the reflection approach failed due to
Caused by: java.lang.ClassNotFoundException: Didn't find class
"com.google.tv.player.PlayerActivity" on path: /system/app/myAPK.apk
so maybe (hopefully) it's some sort of class loader issue?
I'll be awarding 100 bounty on this question as soon as I can, in the meantime - please help :) I have searched SO high and low, and tried all things suggested and what I could think of. At the moment i'm really stumped.
According to Diane Hackborne on a discussion had on android-developers mailing list quoting
From: Dianne Hackborn (hack...#android.com)
Date: Mar 11, 2011 5:24:06 pm
List: com.googlegroups.android-developers
Correct you can't do this, very much by design.
It turns out that it is a major security risk to allow foreign apps to dispatch key events to other apps. Therefore, apps that need to work together this way also need to share either the GroupID or the PID.
Conclusion: unfortunately, what you are asking doesn't seem possible at the moment.
If there is any encapsulating code you could post it would greatly help in understanding your call stack. From the description you gave my thought is that you should return false from your key handler (what ever method is actually capturing the key press) this would allow it to bubble up from the middleware you mentioned. Again I'm not sure of your key entry point since you did not provide a signature or indicate what method is trapping the key press.
If you unpack the GTV TV Player APK, the manifest references several libraries:
<uses-library android:name="com.google.android.tv" />
<uses-library android:name="com.google.tv" />
<uses-library android:name="com.google.tv.epg" />
<uses-library android:name="com.google.tv.mediadevices" />
Not sure if this will resolve the reflection class loader issue, but it is worth a try.
I think I have read all post related with my query, some of them helped but I still can´t find the correct approach.
Im trying to develope an app which has to inject touch events into the system. As I was reading if you dont have system signature you can´t use the "logic" way, so we have to manage it using /dev/input/eventX.
Said that, I also attach photo of how events go through the system:
http://imageshack.us/f/201/eventosenandroid.png/
So I want to be sure that I understand how system manage events.
What I suppose is: When you inject a touch event in /dev/input/eventX the sequence for the event will finish into the activity which is currently "in the screen"
I just need to be sure if I can assume that it works like that or not really.
Thanks in advance
You managed to get somewhere with that? If not, did you have a look here?
Android INJECT_EVENTS permission
http://developer.android.com/reference/android/Manifest.permission.html#INJECT_EVENTS
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?
Thanks
Thanks for the comment Victor.
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. :)
I doubt that it's possible with public API's (Boy and Martijn pointed out security concerns).
Most like your best bets (if you don't want to customize Android) would be
a) Try to use InputMethodService (http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html)
It doesn't give that kind of control which you wish, but it could be enough for some needs.
b) Try to go through whole stack (from Kernel to Application) and find some vulnerabilities to use.
This definitely will take a lot of time and doesn't guarantee to bring any fruits.
I would like to know how to intercept incoming calls and also how to forward them. I know there are several questions regarding this topic here and elsewhere on the net, but all the answers use the android.intent.action.PHONE_STATE action which is broadcast always after the phone begins to ring and the call screen is shown.
That's why I'm looking for a solution where i could intercept the call in an early stage before any notification (ringing etc..) has been done. I would like to know if maybe this is possible on a platform level in native code and if yes how ? Or perhaps with some kind of trick with the SDK ?
In general, if you can't do it in Java, you can't do it in the NDK. Most of the time the opposite is true: You can't do MOST things on Android in the NDK.
I don't know of a way to do that, and frankly doubt it exists: It would be a huge security hole if you could download an application that would forward calls to another number.
You may want to look at this source code, it may help you : http://code.google.com/p/auto-answer/
None of the existing apps in Android can forward a call based on a given number. All they can do is forward all or nothing. There's one app in particular (cBlocker) that can forward calls on schedule besides blocking incoming and outgoing calls and SMS based on rules.