Detect home button press in android

2018-12-31 20:10发布

This has been driving me nuts for a while now.

Is there any way of reliably detecting if the home button has been pressed in an android application?

Failing that, is there a robust way of telling what caused an activity to go into onPause? i.e Can we detect if it was caused by a new activity launching or by pressing back/home.

One suggestion I have seen is to override onPause() and call isFinishing() but this will return false when pressing the home button just as it would if a new activity is starting so this fails to distinguish between the two.

Any help much appreciated.

** Update** : Thanks to @android-hungry for this link: http://nisha113a5.blogspot.com/

Overiding the following method:

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

Then the following event WILL get fired for home button presses:

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

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

I'm not sure if there are any side effects with this line:

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

So it would seem that contrary to popular belief, you can in fact listen out for the home key. Worryingly, you can return false and have the home key do nothing.

Update: As expected, there are some side affects with this - it seems that embedded videos and google maps are not visible with this mode enabled.

Update: Supposedly this hack no longer works as of Android 4.0 onwards

14条回答
其实,你不懂
2楼-- · 2018-12-31 20:40

Override onUserLeaveHint() in the activity. There will never be any callback to the activity when a new activity comes over it or user presses back press.

查看更多
无与为乐者.
3楼-- · 2018-12-31 20:41

This is an old question but it might help someone.

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

According to the documentation, the onUserLeaveHint() method is called when the user clicks the home button OR when something interrupts your application (like an incoming phone call).

This works for me.. :)

查看更多
唯独是你
4楼-- · 2018-12-31 20:44

I had this problem, and since overriding the onKeyDown() method didn't accomplish anything because of the underlying android system didn't call this method, I solved this with overriding onBackPressed(), and I had a boolean value set there to false, because I pressed back, let me show you what I mean in code:

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"); }
    }

So the reason why this worked is because the only way to navigate outside this activity is by pressing back or home so if back was pressed then i know the cause wasn't home, but otherwise the cause was home, therefore i set the default boolean value for homePressed to be true. However this will only work with a single activity instance in your application because otherwise you have more possibilities to cause the onPause() method to be called.

查看更多
姐姐魅力值爆表
5楼-- · 2018-12-31 20:45

onUserLeaveHint();

override this activity class method.This will detect the home key click . This method is called right before the activity's onPause() callback.But it will not be called when an activity is interrupted like a in-call activity comes into foreground, apart from that interruptions it will call when user click home key.

@Override
protected void onUserLeaveHint() {
    super.onUserLeaveHint();
    Log.d(TAG, "home key clicked");
}
查看更多
十年一品温如言
6楼-- · 2018-12-31 20:45

An option for your application would be to write a replacement Home Screen using the android.intent.category.HOME Intent. I believe this type of Intent you can see the home button.

More details:

http://developer.android.com/guide/topics/intents/intents-filters.html#imatch

查看更多
深知你不懂我心
7楼-- · 2018-12-31 20:46

I needed to start/stop background music in my application when first activity opens and closes or when any activity is paused by home button and then resumed from task manager. Pure playback stopping/resuming in Activity.onPause() and Activity.onResume() interrupted the music for a while, so I had to write the following code:

@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
  }
}

which interrupts the playback only when application (all its activities) is closed or when home button is pressed. Unfortunatelly I didn't manage to change order of calls of onPause() method of the starting activity and onResume() of the started actvity when Activity.startActivity() is called (or detect in onPause() that activity is launching another activity other way) so this case have to be handled specially:

private boolean mIsStarting;

@Override
public void startActivity(Intent intent) {
  mIsStarting = true;
  super.startActivity(intent);
}

Another drawback is that this requires GET_TASKS permission added to AndroidManifest.xml:

<uses-permission
  android:name="android.permission.GET_TASKS"/>

Modifying this code that it only reacts on home button press is straighforward.

查看更多
登录 后发表回答