在android中检测主页button

这一直在推动我疯了一段时间。

有什么方法可靠地检测,如果主页button已被按下在Android应用程序?

如果没有,那么有没有一种强有力的方式来说明什么导致了一个活动进入到了暂停? 即我们可以检测到是否是由于新的活动启动或按回家/ home造成的。

我所看到的一个build议是重写onPause()并调用isFinishing(),但是如果按下homebutton,就会返回false,就像新活动正在启动一样,所以无法区分这两者。

任何帮助非常感谢。

**更新**:感谢@ android-hungry这个链接: http : //nisha113a5.blogspot.com/

包含以下方法:

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

然后下面的事件将被解雇主页button:

 @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并让主键不执行任何操作。

更新 :正如所料,这有一些副作用 – 似乎embedded的video和谷歌地图不可见,启用此模式。

更新 :据说这个黑客不再适用于Android 4.0以上

以下代码适合我:)

 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 InnerRecevier mRecevier; public HomeWatcher(Context context) { mContext = context; mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); } public void setOnHomePressedListener(OnHomePressedListener listener) { mListener = listener; mRecevier = new InnerRecevier(); } public void startWatch() { if (mRecevier != null) { mContext.registerReceiver(mRecevier, mFilter); } } public void stopWatch() { if (mRecevier != null) { mContext.unregisterReceiver(mRecevier); } } class InnerRecevier 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 { public void onHomePressed(); public void onHomeLongPressed(); } 

这是一个古老的问题,但它可能有助于某人。

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

根据文档,onUserLeaveHint()方法是当用户单击主页button或者当某个事件中断您的应用程序(如来电)时调用的。

这对我有用.. 🙂

从Android应用程序中检测和/或拦截HOMEbutton是不可能的。 这是内置在系统中,以防止无法退出的恶意应用程序。

当第一个活动打开和closures时,或者任何活动被主页button暂停,然后从任务pipe理器恢复时,我需要在应用程序中启动/停止背景音乐。 在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 } } 

只有当应用程序(所有活动)closures或按下主页button时才会中断播放。 不幸的是,当Activity.startActivity()被调用(或者在onPause()中检测到活动正在启动其他活动时,我并没有设法改变开始活动的onPause()方法和onResume()方式),所以这种情况下,必须专门处理:

 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"/> 

修改这个代码,它只对首页button按下反应是直截了当的。

在活动中重写onUserLeaveHint() 。 当新的活动结束或者用户按回来时,将不会有任何callback。

尝试为每个屏幕创build一个计数器。 如果用户触摸HOME,则计数器将为零。

 public void onStart() { super.onStart(); counter++; } public void onStop() { super.onStop(); counter--; if (counter == 0) { // Do.. } } 

您可能会考虑Andreas Shrade在“ 如何在Android中创build工作信息亭模式”一文中的解决scheme。 这有点不好意思,但鉴于阻止主页button被拦截的原因,它必须是;)

我有这个问题,因为重写的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()方法。

您的应用程序的选项将是使用android.intent.category.HOME意图编写一个replace主屏幕。 我相信这种types的意图,你可以看到主页button。

更多细节:

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

平均的应用程序可以相处得很好,而不需要知道主页新闻和暂停事件之间的区别。 换句话说,onPause()通常就足够了。

你为什么要这样做? 给我们更多关于你的意图的信息可能会为你带来更好的整体策略。

由于您只希望在启动应用程序时重新启动根活动,也许您可​​以通过更改清单中的启动模式等来获得此行为?

例如,你有没有尝试将android:clearTaskOnLaunch =“true”属性应用于你的启动活动,也许与android:launchMode =“singleInstance”一起使用 ?

任务和返回栈是微调这种行为的一个很好的资源。

改变主键的行为是一个坏主意。 这就是为什么Google不允许您覆盖主键。 一般来说,我不会惹上家用钥匙。 无论出于何种原因,您都需要给用户一种摆脱应用程序的方式。

我想像任何工作将有不必要的副作用。

onUserLeaveHint();

重写此活动类的方法。这将检测主键单击。 这个方法在活动的onPause()callback之前被调用,但是当一个活动被打断,就像一个被调用的活动进入前台,除了当用户点击home键时会调用这个活动之外,它不会被调用。

 @Override protected void onUserLeaveHint() { super.onUserLeaveHint(); Log.d(TAG, "home key clicked"); }