To już od jakiegoś czasu doprowadza mnie do szału.
Czy istnieje sposób na niezawodne wykrycie, czy przycisk Home został naciśnięty w aplikacji na Androida?
Jeśli to się nie powiedzie, czy istnieje skuteczny sposób na stwierdzenie, co spowodowało rozpoczęcie działania onPause? tj. czy możemy wykryć, czy było to spowodowane uruchomieniem nowej aktywności lub naciśnięciem przycisku wstecz / home.
Jedną z sugestii, które widziałem, jest zastąpienie onPause () i wywołanie isFinishing (), ale po naciśnięciu przycisku home zwróci to fałsz, tak jak w przypadku rozpoczęcia nowej czynności, więc nie rozróżnia tych dwóch.
Każda pomoc bardzo doceniona.
** Aktualizacja **: dzięki @ android-hungry za ten link: https://nishandroid.blogspot.com/
Pomijając następującą metodę:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
}
Następnie następujące zdarzenie zostanie zwolnione z powodu naciśnięcia przycisku głównego:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_HOME)
{
//The Code Want to Perform.
}
});
Nie jestem pewien, czy są jakieś skutki uboczne z tą linią:
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
Wydawałoby się więc, że wbrew powszechnemu przekonaniu można faktycznie posłuchać klucza domowego. Niepokojące jest to, że możesz zwrócić fałsz i pozwolić, aby klucz domowy nic nie robił.
Aktualizacja : zgodnie z oczekiwaniami są pewne skutki uboczne - wygląda na to, że osadzone filmy i mapy Google nie są widoczne przy włączonym tym trybie.
Aktualizacja : podobno ten hack nie działa już od Androida 4.0
źródło
Activity.onUserLeaveHint()
.Odpowiedzi:
Poniższy kod działa u mnie :)
HomeWatcher mHomeWatcher = new HomeWatcher(this); mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() { @Override public void onHomePressed() { // do something here... } @Override public void onHomeLongPressed() { } }); mHomeWatcher.startWatch();
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; public class HomeWatcher { static final String TAG = "hg"; private Context mContext; private IntentFilter mFilter; private OnHomePressedListener mListener; private InnerReceiver mReceiver; public HomeWatcher(Context context) { mContext = context; mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); } public void setOnHomePressedListener(OnHomePressedListener listener) { mListener = listener; mReceiver = new InnerReceiver(); } public void startWatch() { if (mReceiver != null) { mContext.registerReceiver(mReceiver, mFilter); } } public void stopWatch() { if (mReceiver != null) { mContext.unregisterReceiver(mReceiver); } } class InnerReceiver extends BroadcastReceiver { final String SYSTEM_DIALOG_REASON_KEY = "reason"; final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); if (reason != null) { Log.e(TAG, "action:" + action + ",reason:" + reason); if (mListener != null) { if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) { mListener.onHomePressed(); } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { mListener.onHomeLongPressed(); } } } } } } }
public interface OnHomePressedListener { void onHomePressed(); void onHomeLongPressed(); }
źródło
onHomeLongPressed
Wygląda na to, że Twój faktycznie odpowiada otwarciu aktywności systemu „Ostatnie”. Na moim telefonie jest to wyzwalane przez naciśnięcie przycisku Ostatnie obok przycisku strony głównej, więc założenie w kodzie, że jest to długie naciśnięcie w domu, nie zawsze jest poprawne.final String SYSTEM_DIALOG_REASON_LONG_PRESS = "assist"
To stare pytanie, ale może komuś pomóc.
@Override protected void onUserLeaveHint() { Log.d("onUserLeaveHint","Home button pressed"); super.onUserLeaveHint(); }
Zgodnie z dokumentacją metoda onUserLeaveHint () jest wywoływana, gdy użytkownik kliknie przycisk strony głównej LUB coś zakłóci działanie aplikacji (np. Przychodzące połączenie telefoniczne).
To działa dla mnie .. :)
źródło
Niemożliwe jest wykrycie i / lub przechwycenie przycisku HOME z poziomu aplikacji na Androida. Jest to wbudowane w system, aby zapobiec złośliwym aplikacjom, których nie można zamknąć.
źródło
Musiałem uruchomić / zatrzymać muzykę w tle w mojej aplikacji, gdy pierwsze działanie jest otwierane i zamykane lub gdy jakakolwiek czynność jest wstrzymywana przyciskiem Home, a następnie wznawiana z poziomu menedżera zadań. Czyste odtwarzanie zatrzymało się / wznowiło
Activity.onPause()
iActivity.onResume()
przerwało na chwilę muzykę, więc musiałem napisać następujący kod:@Override public void onResume() { super.onResume(); // start playback here (if not playing already) } @Override public void onPause() { super.onPause(); ActivityManager manager = (ActivityManager) this.getSystemService(Activity.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(Integer.MAX_VALUE); boolean is_finishing = this.isFinishing(); boolean is_last = false; boolean is_topmost = false; for (ActivityManager.RunningTaskInfo task : tasks) { if (task.topActivity.getPackageName().startsWith("cz.matelier.skolasmyku")) { is_last = task.numRunning == 1; is_topmost = task.topActivity.equals(this.getComponentName()); break; } } if ((is_finishing && is_last) || (!is_finishing && is_topmost && !mIsStarting)) { mIsStarting = false; // stop playback here } }
która przerywa odtwarzanie tylko wtedy, gdy aplikacja (wszystkie jej działania) jest zamknięta lub gdy wciśnięty jest przycisk home. Niestety nie udało mi się zmienić kolejności wywołań
onPause()
metody czynności startowej i czynnościonResume()
rozpoczętej, gdyActivity.startActivity()
jest wywoływana (lub wykryć wonPause()
tej czynności inną aktywność), więc ten przypadek wymaga specjalnej obsługi:private boolean mIsStarting; @Override public void startActivity(Intent intent) { mIsStarting = true; super.startActivity(intent); }
Inną wadą jest to, że wymaga to
GET_TASKS
uprawnień dodanych doAndroidManifest.xml
:<uses-permission android:name="android.permission.GET_TASKS"/>
Modyfikacja tego kodu, tak aby reagował tylko na naciśnięcie przycisku głównego, jest prosta.
źródło
Zastąp
onUserLeaveHint()
w działaniu. Nigdy nie będzie żadnego oddzwaniania do działania, gdy nadejdzie nowe działanie lub użytkownik naciśnie przycisk wstecz.źródło
onUserLeaveHint ();
zastępuje tę metodę klasy aktywności, co spowoduje wykrycie kliknięcia klawisza głównego. Ta metoda jest wywoływana tuż przed wywołaniem zwrotnym onPause () działania, ale nie będzie wywoływana, gdy działanie zostanie przerwane, tak jak działanie w wywołaniu, poza tym, że będzie wywoływane, gdy użytkownik kliknie klawisz home.
@Override protected void onUserLeaveHint() { super.onUserLeaveHint(); Log.d(TAG, "home key clicked"); }
źródło
Spróbuj utworzyć licznik dla każdego ekranu. Jeśli użytkownik dotknie HOME, licznik będzie wynosił zero.
public void onStart() { super.onStart(); counter++; } public void onStop() { super.onStop(); counter--; if (counter == 0) { // Do.. } }
źródło
Możesz rozważyć rozwiązanie Andreasa Shrade'a w jego poście na temat tworzenia działającego trybu kiosku w systemie Android . To trochę zepsute, ale biorąc pod uwagę powody, dla których zapobiega się przechwyceniu przycisku Home, musi tak być;)
źródło
Miałem ten problem, a ponieważ nadpisanie metody onKeyDown () nic nie dało, ponieważ podstawowy system Android nie wywołał tej metody, rozwiązałem to przez nadpisanie onBackPressed () i miałem ustawioną tam wartość logiczną na false , ponieważ nacisnąłem, pokażę Ci, co mam na myśli w kodzie:
import android.util.Log; public class HomeButtonActivity extends Activity { boolean homePressed = false; // override onCreate() here. @Override public void onBackPressed() { homePressed = false; // simply set homePressed to false } @Overide public void onResume() { super.onResume(); homePressed = true; // default: other wise onBackPressed will set it to false } @Override public void onPause() { super.onPause(); if(homePressed) { Log.i("homePressed", "yay"); } }
Powodem, dla którego to zadziałało, jest to, że jedynym sposobem na poruszanie się poza tą czynnością jest naciśnięcie przycisku wstecz lub do domu, więc jeśli naciśnięto przycisk wstecz, wiem, że przyczyną nie było w domu, ale poza tym przyczyną był dom, dlatego ustawiam domyślną wartość logiczną wartość dla domuPressed, aby było prawdziwe. Jednak zadziała to tylko z pojedynczą instancją działania w aplikacji, ponieważ w przeciwnym razie masz więcej możliwości spowodowania wywołania metody onPause ().
źródło
homePressed
na wartość true, a następnie przełączenie do innej aplikacji mogłoby pomyśleć, że przycisk Home został naciśnięty, gdy tak naprawdę nie był.Od API 14 możesz używać funkcji
onTrimMemory()
i sprawdzać flagęTRIM_MEMORY_UI_HIDDEN
. Dzięki temu dowiesz się, że Twoja aplikacja działa w tle.Więc w swojej niestandardowej klasie Application możesz napisać coś takiego:
override fun onTrimMemory(level: Int) { if (level == TRIM_MEMORY_UI_HIDDEN) { // Application going to background, do something } }
Aby uzyskać dogłębną analizę tego zagadnienia, zapraszam do przeczytania tego artykułu: http://www.developerphil.com/no-you-can-not-override-the-home-button-but-you-dont-have -do/
źródło
Opcją dla twojej aplikacji byłoby napisanie zastępczego ekranu głównego przy użyciu intencji android.intent.category.HOME. Wierzę, że tego typu intencji można zobaczyć przycisk strony głównej.
Więcej szczegółów:
http://developer.android.com/guide/topics/intents/intents-filters.html#imatch
źródło
Ponieważ chcesz, aby aktywność roota była ponownie wyświetlana po uruchomieniu aplikacji, może możesz uzyskać to zachowanie, zmieniając tryby uruchamiania itp. W manifeście?
Na przykład, czy próbowałeś zastosować atrybut android: clearTaskOnLaunch = "true" do swojej aktywności uruchamiania, być może w połączeniu z android: launchMode = "singleInstance" ?
Zadania i Back Stack to świetne źródło informacji o dostosowywaniu tego rodzaju zachowań.
źródło
Zmiana zachowania klucza domowego to zły pomysł. Dlatego Google nie zezwala na zastąpienie klucza głównego. Ogólnie rzecz biorąc, nie zadzierałbym z kluczem do domu. Musisz dać użytkownikowi możliwość wyjścia z aplikacji, jeśli z jakiegoś powodu znika ona w chwasty.
Wyobrażam sobie, że każde obejście będzie miało niepożądane skutki uboczne.
źródło
Ostatnio próbowałem wykryć przycisk home, ponieważ potrzebowałem go do zrobienia tego samego co metoda „ onBackPressed () ”. Aby to zrobić, musiałem zastąpić metodę „ onSupportNavigateUp () ” w następujący sposób:
override fun onSupportNavigateUp(): Boolean { onBackPressed() return true }
Działało doskonale. =)
źródło
Odpowiedź Jacka doskonale sprawdza się w
click
przypadku zdarzenia, podczas gdylongClick
rozważa tomenu
kliknięcie przycisku.Swoją drogą, jeśli ktoś się zastanawia, jak to zrobić przez kotlin,
class HomeButtonReceiver(private var context: Context,private var listener: OnHomeButtonClickListener) { private val mFilter: IntentFilter = IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) private var mReceiver: InnerReceiver = InnerReceiver() fun startWatch() { context.registerReceiver(mReceiver, mFilter) } fun stopWatch() { context.unregisterReceiver(mReceiver) } inner class InnerReceiver: BroadcastReceiver() { private val systemDialogReasonKey = "reason" private val systemDialogReasonHomeKey = "homekey" override fun onReceive(context: Context?, intent: Intent?) { val action = intent?.action if (action == Intent.ACTION_CLOSE_SYSTEM_DIALOGS) { val reason = intent.getStringExtra(systemDialogReasonKey) if (reason != null && reason == systemDialogReasonHomeKey) { listener.onHomeButtonClick() } } } } }
źródło
Android Home Key obsługiwany przez warstwę frameworkową, nie można tego obsłużyć na poziomie warstwy aplikacji. Ponieważ akcja przycisku głównego jest już zdefiniowana na poniższym poziomie. Ale jeśli opracowujesz niestandardową pamięć ROM, może to być możliwe. Google ograniczyło funkcje nadpisywania PRZYCISKU HOME ze względów bezpieczeństwa.
źródło
To działa dla mnie. Możesz zastąpić metodę onUserLeaveHint https://www.tutorialspoint.com/detect-home-button-press-in-android
@Override protected void onUserLeaveHint() { // super.onUserLeaveHint(); }
źródło