Question

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.

Était-ce utile?

La solution

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.

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top