2012-08-14 11 views
8

Es gibt einige Teile des Frameworks, die mir noch nicht ganz klar sind. Ich kenne den Ablauf eines Input-Events (Kernel -> Eventhub -> InputReader -> InputDispatcher -> ...).Android Key Handling (Framework)

Situation

(Bedarf:. Eingabetaste Griff, ohne den Android-Framework zu ändern) ich von einem Gerät kommende Schlüsselereignisse zu handhaben will (Tastatur/Gamepad/Controller/...), aber es sind einige Anforderungen. Zum einen möchte ich das Android-Framework nicht ändern. Das heißt, ich möchte die WindowManagerPolicy und ihre Funktionen wie interceptKeyBeforeDispatching, wo der Home-Key behandelt wird, nicht erweitern. Dies würde dazu führen, dass das Schlüsselereignis in die Anwendungsebene gesendet wird, was in Ordnung ist. Der Nachteil ist, ich habe hier noch eine knifflige Anforderung. Beispiel: Wenn ich Angry Birds spiele und meine GoToAlpha-Taste an meinem angeschlossenen Eingabegerät drücke, muss die Alpha-Anwendung starten. Angry Birds hat keine Ahnung, welcher Button GoToAlpha ist, wird es nicht behandeln/erkennen und es wird zum Beispiel keine Absicht gesendet, meine Alpha-Anwendung zu starten.

Frage

Gibt es eine Möglichkeit, mein (custom) Schlüsselereignis zu behandeln, nachdem es versandt wird, wohl wissend, dass die Anwendung im Vordergrund den Schlüssel nicht umgehen kann?

My (nicht) Lösungen

  • einen Dienst erstellen, der die wichtigsten Ereignisse behandelt. Dies ist nicht möglich, da eine Anwendung wie "Angry Birds" nicht an meinen Dienst gebunden ist und das Schlüsselereignis nicht in meinem Dienst erfasst wird. Wenn ich falsch liege, bitte geben Sie weitere Informationen an :).

  • Erstellen Sie eine externe Bibliothek, in der ich die Aktivitäten meiner Anwendung von meiner eigenen ActivityBase erben lasse. Alle wichtigen Ereignisse und ihr Standardverhalten können hier behandelt werden. Nachteilige, vorhandene Anwendungen unterstützen meine benutzerdefinierten Schlüsselereignisse nicht, da sie die Bibliothek nicht verwenden.

  • Erweitern Sie den Rahmen wäre in meinen Augen die sauberste Lösung, aber das wird nicht meine Anforderung erfüllen.

Jede Hilfe oder nützliche Informationen würden

Extra-

Wenn die erste Frage auf der einen oder anderen .. könnte ich möchte anpassen geschätzt werden gelöst Intent hinter dem GoToAlpha-Button. Das bedeutet .. Durch Standard wird die Alpha-Anwendung gestartet, aber nachdem der Benutzer hat, wird die Beta-Anwendung von nun an gestartet. Irgendwelche Gedanken?

Dank

+0

Wäre es nicht seltsam, wenn es möglich ist, wichtige Ereignisse aus anderen Anwendungen zu erfassen? Ich denke, das wäre ein Sicherheitsrisiko – Boy

+0

True. Sobald das Schlüsselereignis das Framework verlässt, wird es nur zu einer Anwendung weitergeleitet und dort behandelt. Wenn nicht, wird es an das Framework zurückgegeben. Das würde bedeuten, dass es keine Lösung gibt, die beide Anforderungen erfüllt? – DroidBender

+0

Meiner Meinung nach wird es wahrscheinlich keinen Weg geben, nur wegen des Sicherheitsproblems: Umgang mit wichtigen Ereignissen, während Ihre App keinen Fokus hat. Vielleicht wäre der einzige Weg, wenn Sie eine Android-Tastatur implementieren (ich habe keine Kenntnis davon)? Dies sollte in der Lage sein, Schlüsselereignisse zu behandeln (und Benutzer werden auch auf dieses Sicherheitsrisiko hingewiesen, wenn Sie eine Drittanbieter-Tastatur auswählen) – Boy

Antwort

3

Danke für den Kommentar Victor.

Mit der InputMethodService mir nicht bieten genügend Freiheit und Funktionalität meine Probleme zu behandeln.

Meine Lösung/Compromise

Im Android-Framework gibt es eine PhoneWindowManager, die für den Umgang mit InputEvents verantwortlich ist. Die WindowManagerService, die von der SystemServer gestartet wird, ist Besitzer dieses Managers und erstellt eine Instanz.

Indem ich meinen eigenen benutzerdefinierten WindowManager erstelle und ihn von Android PhoneWindowManager erben lasse, verliere ich keine Standardfunktionalität und dies erlaubt mir, meine eigene Implementierung innerhalb dieser Klasse hinzuzufügen. Das Ergebnis ist das Hinzufügen einer neuen Datei zum Framework und das Ändern nur einer Zeile in Android Framework: WindowManagerService erstellt kein PhoneWindowManager, aber erstellt ein CustomPhoneWindowManager (erweitert PhoneWindowManager).

Wenn jemand eine bessere Lösung oder bestimmte Gedanken über meine Kompromisse sieht, zögern Sie nicht, zu kommentieren. :)

+0

Eine weitere Idee. Ich habe irgendwo davon gehört, aber ich kann mich nicht erinnern, wo und wie die Ergebnisse waren. Sie können versuchen, ein transparentes Fenster zu erstellen, das über allen Fenstern sitzt, so dass Sie alle Klicks/Tastatureingabe erhalten. Und jetzt müssen Sie es an die Anwendung direkt hinter Ihrem schicken. Auf diese Weise können Sie Ihr Problem von "Empfangen aller Eingaben" zum Senden von Klicks an andere Apps ändern. –

+1

Das ist ein ziemlich gefährlicher Ansatz Victor, würde das nicht mit einigen Sicherheitsstandards kollidieren :)? Ein weiteres Problem sind 'InputEvents' (ähnlich wie KEYCODE_HOME), die innerhalb des Frameworks abgefangen werden und nicht an die Anwendungsschicht gesendet werden. Diese Ereignisse würden nicht einmal im unsichtbaren Fenster ankommen.Danke für deine Unterstützung! – DroidBender

+0

Oh .. yeah .. Es ist gefährlich :) Allerdings glaube ich, dass Business-Wert 80% der Zeit Sicherheitsprobleme betrifft. Ich habe einen sehr eingeschränkten Einblick in den gesamten InputMethodService (weiß nur über seine Existenz). –

0

Ich bezweifle, dass es mit der öffentlichen API (Junge und Martijn wies darauf hin, Sicherheitsbedenken) möglich ist.

Die meisten, wie Sie Ihre besten Wetten (wenn Sie nicht Android anpassen wollen) würde

a) Versuchen sein InputMethodService zu verwenden (http://developer.android.com/reference/android/inputmethodservice/InputMethodService .html)

Es gibt nicht die Art von Kontrolle, die Sie wünschen, aber es könnte genug für einige Bedürfnisse sein.

b) Versuchen Sie, den gesamten Stack (vom Kernel bis zur Anwendung) durchzugehen und einige Sicherheitslücken zu finden.

Dies wird definitiv viel Zeit in Anspruch nehmen und garantiert keine Früchte zu bringen.