Überschreibe die Power-Taste wie die Home-Taste

Nun, ich mache etwas, bei dem ich alle harten Tasten des Gerätes deaktivieren möchte.

Hard Buttons wie Power, Home, Lauter, Leiser, Suche, Zurück.

Ich habe fast alle Tasten außer Power erfolgreich außer Kraft gesetzt.

Ich möchte nur, dass ihr Leute seht und teilt euch ein paar Ideen mit, damit ich davon weg komme.

Ich bekomme das Power-Keyevent in onDispatchKeyEvent() lange gedrückt, genauso wie ich den kurzen Klick des gleichen fangen möchte. Außerdem habe ich beim Drücken von Power versucht, Screen auszuschalten, indem ich den Broadcast von SCREEN_OFF und es mir gelungen ist ihn zu empfangen, aber ich konnte damit nicht umgehen.

Vielen Dank.

Dann hatte ich einen ReceiverScreen erstellt, der Broadcast von Screen an / aus empfängt

ReceiverScreen.java

 public class ReceiverScreen extends BroadcastReceiver { public static boolean wasScreenOn = true; @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { // do whatever you need to do here wasScreenOn = false; } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { // and do whatever you need to do here wasScreenOn = true; } } } 

DeaktivierenHardButton.java

 public class DisableHardButton extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); BroadcastReceiver mReceiver = new ReceiverScreen(); registerReceiver(mReceiver, filter); } @Override protected void onPause() { // when the screen is about to turn off if (ScreenReceiver.wasScreenOn) { // this is the case when onPause() is called by the system due to a screen state change System.out.println("SCREEN TURNED OFF"); } else { // this is when onPause() is called when the screen state has not changed } super.onPause(); } @Override protected void onResume() { // only when screen turns on if (!ScreenReceiver.wasScreenOn) { // this is when onResume() is called due to a screen state change System.out.println("SCREEN TURNED ON"); } else { // this is when onResume() is called when the screen state has not changed } super.onResume(); } } 

Puh. Dies ist eine ziemlich umstrittene Frage mit vielen Kommentaren dahinter.

Lassen Sie mich beginnen, indem Sie Ihre Frage ein wenig umformulieren. Wenn ich es klar verstehe, möchten Sie alle physischen Tasten auf dem Gerät für die Dauer Ihrer Aktivität deaktivieren. Dies schließt die Einschalttaste ein, die Sie erkennen, indem Sie die ACTION_SCREEN_OFF Absicht behandeln. Ihre aktuelle (erfolgreiche) Problemumgehung für dieses Szenario besteht darin, eine ACTION_SCREEN_ON zu senden, die den Bildschirm nach dem Ausschalten wieder zum Leben erweckt, sofern der Host dies ordnungsgemäß implementiert.

Sie möchten jetzt die Extra-Meile gehen, indem Sie diese Aktion unnötig machen, wenn (und nur wenn) Sie in der Lage sind, ACTION_SCREEN_OFF und zu behandeln, bevor es an das System gesendet wird. Ist das möglich und wenn ja, wie?

Dies wirft eine Diskussion auf. Die kurze Version ist jedoch einfach: Dies ist nicht möglich, ohne benutzerdefinierte Anpassung an Ihre Firmware oder den core des Android-Betriebssystems für eine begrenzte Anzahl von Geräten.

Das Android-System definiert dies, soweit es dokumentiert ist, als Broadcast-Aktion . Nach dem Publish-Subscribe-Muster der Nachrichtenverbreitung informiert diese Nachricht alle betroffenen Parteien über diese Aktion. Da diese Nachricht vom System gesendet wird, weil der Nachrichtenstapel vom System verwaltet wird und weil die Nachricht auch vom System empfangen wird, wird Ihr Code einfach nicht an der richtigen Stelle eingefügt, um den Empfang dieser Nachricht zu blockieren.

Darüber hinaus wird dies bei einigen Geräten ein physikalischer Schalter sein, der keinerlei programmatische Unterbrechung aufweist. Im besten Fall kann das Android-System hoffen, für das Ereignis, wenn es passiert, zu handhaben, weshalb gerade diese Broadcast-Nachricht im Service-Stack ein Sonderfall ist. Nach meinem besten Wissen und basierend auf der spärlichen Dokumentation zu diesem Szenario ist dies der Grund, warum es sich nicht um eine sofort einsatzbereite, unterstützte function handelt, bevor wir einen der möglichen Vektoren für Missbrauch in Betracht ziehen.

Ihre beste Möglichkeit ist tatsächlich eine viel einfachere, wenn Sie die physische Hardware für das fragliche Gerät ändern können: Beschränken Sie den Zugriff auf, Mangle, oder deaktivieren Sie die physische Power-Taste. In vielen Szenarien ist dies unerwünscht, aber dies funktioniert in Situationen, in denen Ihr Android-Gerät zum Beispiel als Point-of-Sale- oder als Service-Automat verwendet wird. Wenn dies nicht möglich ist, kann es erforderlich sein, physische Einschränkungen für den Zugriff auf die ACTION_SCREEN_ON , um den Rest der Fälle (z. B. Spot-Versuche zum ACTION_SCREEN_ON des Bildschirms) durch Senden von ACTION_SCREEN_ON .

Denken Sie daran, diese Strategie ist nicht narrensicher. Tun Sie dies kompetent und dokumentieren Sie den Ablauf gut, damit Sie nicht für das nächste Exposé 2600 füttern .

Viel Glück mit Ihrer Bewerbung.

Im Gegenteil zu allen Antworten .. Überprüfen Sie dies:


 @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { Log.i("", "Dispath event power"); Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeDialog); return true; } return super.dispatchKeyEvent(event); } 

Was es macht:

Immer wenn der Benutzer den Netzschalter drückt. Wir brechen den Dialog vorzeitig ab! :). Das funktioniert für mich .. (Getestet auf note2)

Hier ist was ich getan habe:

(1) Erstellen Sie eine Empfängerklasse:

 public class ScreenReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); switch (action) { case Intent.ACTION_SCREEN_OFF: BaseActivity.unlockScreen(); break; case Intent.ACTION_SCREEN_ON: // and do whatever you need to do here BaseActivity.clearScreen(); } } } 

(2) Die beiden oben genannten Methoden sahen so aus:

 public static void unlockScreen () { if (current == null) return; Log.i( Constants.TAG, "Turning on screen ... " ); Window window = current.getWindow(); window.addFlags( WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD ); window.addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED ); window.addFlags( WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ); } public static void clearScreen () { if (current == null) return; Log.i( Constants.TAG, "Clearing screen flag when on ... " ); Window window = current.getWindow(); window.clearFlags( WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD ); window.clearFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED ); window.clearFlags( WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON ); } private static BaseActivity current; @Override protected void onResume () { current = this; } 

(3) Registrieren Sie in der Hauptaktivitätsklasse onCreate () den Empfänger:

  IntentFilter filter = new IntentFilter( Intent.ACTION_SCREEN_ON ); filter.addAction( Intent.ACTION_SCREEN_OFF ); registerReceiver(new ScreenReceiver(), filter); 

Sie können über die Power-Taste drücken, aber ich denke nicht, dass Sie es überschreiben können und Sie können den Dialog für Ausschalten ausschalten und etwas anderes zeigen.

Hier ist, was ich versucht habe,

 package com.easylogs.app; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; public class CloseSystemDialogsIntentReceiver extends BroadcastReceiver { public void onReceive(final Context context, final Intent intent) { Log.i("HERE", "------------------------------------HERE"); Toast.makeText(context, "OFFFFFFFFFFFFFFFF",Toast.LENGTH_LONG).show(); } } 

und Erklärung in Manifest als,

        
 @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { return true; } return super.dispatchKeyEvent(event); } 

Haben Sie den obigen Code ausprobiert, in dem wir das Power Key-Ereignis behandeln können? Schauen Sie sich auch diesen LINK an, der das Power Button gedrückt hat.

Ich weiß es zu spät, kann aber in Zukunft für andere Entwickler hilfreich sein. Getestet über Android N. Referenz von https://StackOverflow.com/a/15828592/1065357

  @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if(!hasFocus) { Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeDialog); } }