Обнаружить нажатие кнопки домой в Android - PullRequest
80 голосов
/ 16 января 2012

Это уже давно сводит меня с ума.

Есть ли способ надежно определить, была ли нажата кнопка «Домой» в приложении для Android?

В противном случае, существует ли надежный способ сообщить, что послужило причиной перехода активности в onPause?т.е. мы можем определить, было ли это вызвано запуском новой активности или нажатием back / home.

Одно из предложений, которое я видел, это переопределить onPause () и вызвать isFinishing (), но при возврате будет возвращено falseКнопка «Домой» так же, как и в случае запуска нового действия, поэтому не удается различить их.

Любая помощь очень ценится.

** Обновление **: Спасибо @ android-hungryдля этой ссылки: http://nisha113a5.blogspot.com/

Перечисление следующего метода:

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);           
}

Тогда будет запущено следующее событие для нажатий кнопок home:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {     

    if(keyCode == KeyEvent.KEYCODE_HOME)
    {
       //The Code Want to Perform. 
    }
});

I 'Я не уверен, есть ли какие-либо побочные эффекты с этой линией:

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);   

Так что может показаться, что вопреки распространенному мнению, вы можете прислушиваться к ключу home.Тревожно, вы можете вернуть false и сделать так, чтобы домашний ключ ничего не делал.

Обновление : Как и ожидалось, есть некоторые побочные эффекты - кажется, что встроенные видео и карты Google не видныс включенным этим режимом.

Обновление : возможно, этот хак больше не работает с Android 4.0 и выше

Ответы [ 16 ]

121 голосов
/ 15 января 2015

У меня работает следующий код:)

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();
}
46 голосов
/ 07 июля 2015

Это старый вопрос, но он может кому-то помочь.

@Override
protected void onUserLeaveHint()
{
    Log.d("onUserLeaveHint","Home button pressed");
    super.onUserLeaveHint();
}

Согласно документации, метод onUserLeaveHint () вызывается, когда пользователь нажимает кнопку «Домой» ИЛИ, когда что-то прерывает ваше приложение (например, входящий телефонный звонок).

Это работает для меня ..:)

8 голосов
/ 16 января 2012

Невозможно обнаружить и / или перехватить кнопку HOME из приложения Android.Это встроено в систему для предотвращения вредоносных приложений, которые не могут быть закрыты.

7 голосов
/ 14 марта 2013

Мне нужно было запускать / останавливать фоновую музыку в моем приложении, когда первое действие открывается и закрывается, или когда какое-либо действие приостанавливается кнопкой домой, а затем возобновляется из диспетчера задач.Остановка / возобновление чистого воспроизведения в 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"/>

Изменение этого кода так, что он реагирует толькоНа кнопку «Домой» нажать просто.

4 голосов
/ 21 апреля 2014

Переопределить onUserLeaveHint() в упражнении. Никогда не будет никакого обратного вызова к действию, когда новое действие приходит поверх него или пользователь нажимает кнопку назад.

2 голосов
/ 31 июля 2015

У меня была эта проблема, и так как переопределение метода onKeyDown () ничего не дало из-за того, что базовая система Android не вызывала этот метод, я решил эту проблему с помощью переопределения onBackPressed (), и у меня было установлено логическое значение там ложно, потому что я нажал назад, позвольте мне показать вам, что я имею в виду в коде:

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 должно быть true. Однако это будет работать только с одним экземпляром действия в вашем приложении, потому что в противном случае у вас будет больше возможностей вызвать метод onPause ().

2 голосов
/ 28 июля 2015

Вы можете рассмотреть решение Андреаса Шраде в своем посте на Как создать режим рабочего киоска в Android .Это немного глупо, но учитывая причины, по которым перехват кнопки home предотвращен, это должно быть;)

2 голосов
/ 14 августа 2012

Попробуйте создать счетчик для каждого экрана.Если пользователь коснется HOME, то счетчик будет равен нулю.

public void onStart() {
  super.onStart();
  counter++;
}

public void onStop() {
  super.onStop();
  counter--;    
  if (counter == 0) {
      // Do..
  }
}
1 голос
/ 12 марта 2019

Начиная с 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/

1 голос
/ 06 октября 2017

onUserLeaveHint ();

переопределить этот метод класса активности. Он обнаружит нажатие клавиши home. Этот метод вызывается непосредственно перед обратным вызовом действия onPause (). Но он не будет вызываться, когда действие прерывается, когда входящее действие выходит на передний план, кроме тех прерываний, которые он будет вызывать, когда пользователь нажимает клавишу home.

@Override
protected void onUserLeaveHint() {
    super.onUserLeaveHint();
    Log.d(TAG, "home key clicked");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...