如何检测用户在我的活动中按HOME键?

你能告诉我如何检测用户按HOME键吗?

谢谢。

更新 [2015年8月]:根据JM主的评论,这个答案可能不适用于设备棒棒糖和以上的设备。 请参阅Android L中的getRunningTasks的替代方法


尽pipe这是一个老问题,但是大部分的答案在API 17级及以上都不适用。 我正在回答最后为我工作的东西。 我已经尝试了很多方法,但没有一个像今天一样工作。 我试过答案

在主页上按下android时调用方法 ,

在android和中检测主页button

覆盖主页button – 如何摆脱select? 。 主要是家就像一个紧急逃生button。 所以你不能覆盖它,但可以在某些方面检测到它。

我尝试的一些(包括上面的答案), 并没有工作是:

  1. 如上所述,以许多方式使用keyCode==KeyEvent.KEYCODE_HOME 。 现在,如果你阅读KeyEvent.KEYCODE_HOME的文档,它说This key is handled by the framework and is never delivered to applications 。 所以现在不再有效了。

  2. 我尝试使用onUserLeaveHint() 。 该文件说:

    作为活动生命周期的一部分,当活动即将进入后台时,作为用户select的结果。 例如,当用户按Home键时,onUserLeaveHint()将会被调用,但是当来电打电话时,被呼叫的Activity被自动带到前台。

    这个问题就是当你从你调用onUserleaveLint()的activity中开始一个Activity时候,这个方法也会被调用,就像我的情况一样。 有关更多信息,请参阅Android onBackPressed / onUserLeaveHint问题。 所以不知道是否只能通过按回家键来调用。

  3. 调用onStop() 。 当活动在现有活动之上时,也可以调用它并完全覆盖它。 所以这也不行。

最后以下为我工作:

看到如何检查Android中当前正在运行的应用程序? 你可以说,如果你的是最近的任务,显示在长按主页button,然后发送到后台。

所以,在您尝试检测按下homebutton的活动的onPause()中,可以检查应用程序是否已经发送到后台。

 @Override public void onPause() { if (isApplicationSentToBackground(this)){ // Do what you want to do on detecting Home Key being Pressed } super.onPause(); } 

函数来检查你是否是最近被发送到后台的应用程序:

 public boolean isApplicationSentToBackground(final Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { return true; } } return false; } 

感谢@idish指出,不要忘记在清单中包含以下权限:

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

我不确定这是否有什么不利之处,但是对我很有帮助。 希望有一天能帮助别人。

PS:如果你在一个已经用FLAG_ACTIVITY_NO_HISTORY标志启动的Activity中使用这个方法,那么这个方法就没有用,因为它会检查最近的历史logging来判断是否点击了Homebutton。

你可以通过Activity.onUserLeaveHint()来检测一个HOMEbutton。 这种方法在两种情况下被调用; 当用户按下HOME并且开始新的活动时。 确保以某种方式区分两者之间。

您无法捕获HOME事件并以任何方式拦截它。 当用户按下主页键时,用户将总是被带到设备的主屏幕。

如果你需要知道什么时候你的Activity被发送到后台,比如从用户按Home键或后退键,我会实现onStop()方法。

没有正式的方式来通知“HOME”按键。 但有一个非常简单的工作,让你的应用程序区分“主页”按键和任何其他行动,将导致活动停止。

对于每个需要在“HOME”键上执行某些操作的课程,请按照以下步骤进行操作:

 /**************************************** On Home **********************************/ private boolean leaveCalled = false; @Override public void startActivity(Intent intent) { leaveCalled= true; super.startActivity(intent); } @Override public void onBackPressed() { leaveCalled = true; super.onBackPressed(); } @Override protected void onStop() { super.onStop(); // Home button pressed if(!leaveCalled) { // Do whatever you like. } leaveCalled = false; } 

编辑

你还需要从包含这个的父类中扩展你的片段。 这是因为片段会以其他方式提供额外的path,以预期而非“主页”的方式在应用中的活动之间切换。

 @Override public void startActivity(Intent intent) { getActivity().startActivity(intent); } 

编辑2

我越来越接近认为这不是处理这个最简单的方法…你还需要添加onConfigurationChange =“orientation”所有使用此方法的活动。 然后你可以添加这个:

 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); leaveCalled = true; finish(); startActivity(getIntent()); } 

编辑3

Urgh

 @Override public void finish() { leaveCalled = true; super.finish(); } 

在Activity中使用onUserLeaveHint()方法

 @Override protected void onUserLeaveHint() { super.onUserLeaveHint(); } 

http://developer.android.com/reference/android/app/Activity.html#onUserLeaveHint();

它可以完成(至less2.3)。 testingAndroid 2.3.5版本的HTC WildFire-S。 代码片段捕获/禁用所有的控制键:

 @Override public void onAttachedToWindow() { super.onAttachedToWindow(); this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD); } public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH ) { Toast.makeText(getApplicationContext(),"You pressed a control button with keyCode : " + keyCode, Toast.LENGTH_SHORT).show(); return false; } else { Toast.makeText(getApplicationContext(),"You pressed" + keyCode, Toast.LENGTH_SHORT).show(); } return true; } public boolean onKeyUp(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_POWER || keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_SEARCH ) { return false; } else { // Do nothing } return true; } 

您可以编写一个Broadcast监听器并将其设置为

 <category android:name="android.intent.category.HOME" /> 

从广播接收机启动你的活动/通知活动。

我发现这个解决scheme基于@Springfeed的build议。 这个问题很笼统,请注意,这个特定的解决scheme将会:

  • 工作棒棒糖以及较低的Android版本(基于ActivityManager的先例代码在棒棒糖上失败)
  • 捕获家庭和历史button
  • 如果活动本身被定义为Home – Always,则不会捕获Home
  • 如果活动是多个家庭选项中的一个,或者根本不在家中,则将捕获家庭。

这段代码在我的基类Activity类中(其中所有的活动inheritance)

  public boolean startingActivity = false; @Override protected void onUserLeaveHint() { if(startingActivity) { // Reset boolean for next time startingActivity = false; } else { // User is exiting to another application, do what you want here Log.i(TAG, "Exiting"); ... } } @Override public void startActivity(Intent intent) { startingActivity = true; super.startActivity(intent); } @Override public void startActivityForResult(Intent intent, int requestCode) { startingActivity = true; super.startActivityForResult(intent, requestCode); } 

由于某些方法也可能使用应用程序上下文来启动意图,所以我定义了一个由我的Application类持有的ContextWrapper来切换布尔值(注意,我有通过该基类静态访问我自己的应用程序的最高活动)。

 public class MyContext extends ContextWrapper { public MyContext(Context base) { super(base); } @Override public void startActivity(Intent intent) { BaseActivity activity = BaseActivity.getActivity(); if(activity != null) { activity.startingActivity = true; } super.startActivity(intent); } } 

如有必要,可能还想覆盖startActivities(…)。

希望这可以帮助 :)

 android.text.method.KeyListener.onKeyDown([view],[text],KEYCODE_HOME,[event]) 

我不确定其他参数如何适用,甚至不知道如何实现上述内容,但是这些信息全部来自keylistner 文档 。

但是他们也在另一个页面提到家庭钥匙总是回家,你不能改变这一点。 所以如果你打算有某种“你确定要退出”对话框,那是行不通的。

 public boolean isApplicationSentToBackground(final Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> tasks = am.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { return true; } } return false; } public void onPause() { super.onPause(); if(isApplicationSentToBackground(this)) { Log.i("Home", "Home Pressed..!"); } } 
 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_HOME) { //The Code Want to Perform. } });