Это уже какое-то время сводит меня с ума.
Есть ли способ надежно определить, была ли нажата кнопка домой в приложении для Android?
Если это не удается, есть ли надежный способ узнать, что заставило действие перейти в onPause? т.е. можем ли мы определить, было ли это вызвано запуском нового действия или нажатием кнопки «Назад / домой».
Одно из предложений, которое я видел, - переопределить onPause () и вызвать isFinishing (), но это вернет false при нажатии кнопки домой, как если бы начиналось новое действие, поэтому это не позволяет различить два.
Любая помощь очень ценится.
** Обновление **: спасибо @ android-hungry за эту ссылку: https://nishandroid.blogspot.com/
Преодоление следующего метода:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
}
Тогда следующее событие БУДЕТ запускаться при нажатии кнопки домой:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_HOME)
{
//The Code Want to Perform.
}
});
Я не уверен, есть ли у этой строки какие-либо побочные эффекты:
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
Таким образом, может показаться, что вопреки распространенному мнению, на самом деле вы можете услышать домашний ключ. К сожалению, вы можете вернуть false, и домашний ключ ничего не сделает.
Обновление : как и ожидалось, здесь есть некоторые побочные эффекты - кажется, что встроенные видео и карты Google не отображаются в этом режиме.
Обновление : предположительно, этот хак больше не работает, начиная с Android 4.0.
источник
Activity.onUserLeaveHint()
.Ответы:
Для меня работает следующий код :)
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(); }
источник
onHomeLongPressed
собственно похоже соответствует открытию активности системы "Недавние". На моем телефоне это запускается нажатием кнопки недавних событий рядом с кнопкой «Домой», поэтому предположение вашего кода о том, что это долгое нажатие «домой», не всегда верно.final String SYSTEM_DIALOG_REASON_LONG_PRESS = "assist"
Это старый вопрос, но он может кому-то помочь.
@Override protected void onUserLeaveHint() { Log.d("onUserLeaveHint","Home button pressed"); super.onUserLeaveHint(); }
Согласно документации, метод onUserLeaveHint () вызывается, когда пользователь нажимает кнопку «Домой» ИЛИ когда что-то прерывает работу вашего приложения (например, входящий телефонный звонок).
У меня это работает .. :)
источник
Невозможно обнаружить и / или перехватить кнопку HOME из приложения Android. Это встроено в систему для предотвращения вредоносных приложений, из которых невозможно выйти.
источник
Мне нужно было запускать / останавливать фоновую музыку в моем приложении, когда первое действие открывается и закрывается или когда какое-либо действие приостанавливается кнопкой домой, а затем возобновляется из диспетчера задач. Чистое воспроизведение останавливается / возобновляется
Activity.onPause()
иActivity.onResume()
на некоторое время прерывает музыку, поэтому мне пришлось написать следующий код:@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 } }
который прерывает воспроизведение только тогда, когда приложение (все его действия) закрыто или когда нажата кнопка домой. К сожалению, мне не удалось изменить порядок вызовов
onPause()
метода начального действия иonResume()
запущенного действия приActivity.startActivity()
вызове (или обнаружить,onPause()
что в этом действии запускается другое действие другим способом), поэтому этот случай нужно обрабатывать специально:private boolean mIsStarting; @Override public void startActivity(Intent intent) { mIsStarting = true; super.startActivity(intent); }
Еще один недостаток заключается в том, что для этого требуется
GET_TASKS
разрешение, добавленное кAndroidManifest.xml
:<uses-permission android:name="android.permission.GET_TASKS"/>
Изменить этот код так, чтобы он реагировал только на нажатие кнопки «Домой», несложно.
источник
Отмена
onUserLeaveHint()
действия. Никогда не будет никакого обратного вызова для действия, когда над ним появится новое действие или пользователь нажмет кнопку возврата.источник
onUserLeaveHint ();
переопределить этот метод класса активности. Это обнаружит нажатие клавиши Home. Этот метод вызывается непосредственно перед обратным вызовом onPause () активности, но он не будет вызываться, когда действие прерывается, например, действие вызова выходит на передний план, за исключением тех прерываний, которые он вызывает, когда пользователь нажимает кнопку Home.
@Override protected void onUserLeaveHint() { super.onUserLeaveHint(); Log.d(TAG, "home key clicked"); }
источник
Попробуйте создать счетчик для каждого экрана. Если пользователь коснется HOME, счетчик будет равен нулю.
public void onStart() { super.onStart(); counter++; } public void onStop() { super.onStop(); counter--; if (counter == 0) { // Do.. } }
источник
Вы можете рассмотреть решение Андреаса Шрейда в его сообщении « Как создать рабочий режим киоска на Android» . Это немного взломано, но, учитывая причины, по которым предотвращается перехват кнопки Home, так и должно быть;)
источник
У меня была эта проблема, и поскольку переопределение метода onKeyDown () ничего не дало, потому что базовая система Android не вызвала этот метод, я решил это переопределением onBackPressed (), и у меня было логическое значение, установленное там на false , поскольку я нажал "назад", позвольте мне показать вам, что я имею в виду в коде:
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"); } }
Итак, причина, по которой это сработало, заключается в том, что единственный способ выйти за пределы этого действия - это нажать назад или домой, поэтому, если была нажата кнопка возврата, я знаю, что причина не в доме, но в противном случае причина была в доме, поэтому я установил логическое значение по умолчанию значение для homePressed, чтобы быть правдой. Однако это будет работать только с одним экземпляром действия в вашем приложении, потому что в противном случае у вас будет больше возможностей вызвать метод onPause ().
источник
homePressed
значение true, а затем переключение на другое приложение будет думать, что Home была нажата, хотя на самом деле это не так.Начиная с API 14, вы можете использовать функцию
onTrimMemory()
и проверять наличие флагаTRIM_MEMORY_UI_HIDDEN
. Это сообщит вам, что ваше приложение переходит в фоновый режим.Итак, в своем пользовательском классе Application вы можете написать что-то вроде:
override fun onTrimMemory(level: Int) { if (level == TRIM_MEMORY_UI_HIDDEN) { // Application going to background, do something } }
Для более глубокого изучения этого я предлагаю вам прочитать эту статью: http://www.developerphil.com/no-you-can-not-override-the-home-button-but-you-dont-have -to /
источник
Вариант для вашего приложения - написать заменяющий домашний экран с использованием намерения android.intent.category.HOME. Я считаю, что при таком намерении вы можете увидеть кнопку «Домой».
Подробнее:
http://developer.android.com/guide/topics/intents/intents-filters.html#imatch.
источник
Поскольку вы хотите, чтобы при запуске приложения отображалось только корневое действие, возможно, вы сможете добиться такого поведения, изменив режимы запуска и т. Д. В манифесте?
Например, пробовали ли вы применить атрибут android: clearTaskOnLaunch = "true" к своей активности запуска, возможно, в тандеме с android: launchMode = "singleInstance" ?
Задачи и Back Stack - отличный ресурс для тонкой настройки такого поведения.
источник
Изменять поведение клавиши Home - плохая идея. Вот почему Google не позволяет вам переопределить домашний ключ. Вообще говоря, я бы не стал связываться с домашним ключом. Вы должны дать пользователю возможность выйти из вашего приложения, если оно по какой-то причине уйдет в тупик.
Я полагаю, что любая работа будет иметь нежелательные побочные эффекты.
источник
Недавно я пытался обнаружить кнопку возврата домой, потому что мне нужно было, чтобы она делала то же, что и метод onBackPressed () . Для этого мне пришлось переопределить метод onSupportNavigateUp () следующим образом:
override fun onSupportNavigateUp(): Boolean { onBackPressed() return true }
Это сработало отлично. знак равно
источник
Ответ Джека отлично работает для
click
события, покаlongClick
рассматривается какmenu
нажатие кнопки.Кстати, если кому интересно как через котлин сделать,
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() } } } } }
источник
Android Home Key обрабатывается уровнем фреймворка, вы не можете справиться с этим на уровне уровня приложения. Потому что действие кнопки «Домой» уже определено на нижнем уровне. Но если вы разрабатываете свой собственный ПЗУ, это может быть возможно. Google ограничил функции переопределения HOME BUTTON из соображений безопасности.
источник
У меня это работает. Вы можете переопределить метод onUserLeaveHint https://www.tutorialspoint.com/detect-home-button-press-in-android
@Override protected void onUserLeaveHint() { // super.onUserLeaveHint(); }
источник