如何检测“Recent Apps”系统button点击(Honeycomb +)

我想知道这个button调用什么方法。

在这里输入图像说明

我的游戏总是暂停/恢复,除了当我使用这个button时,它看起来像这个button不会调用Activity的onPause()onResume()方法。 如果我退出游戏,则可以使用另一个窗口(如图片上的窗口),然后使用此button恢复。 但是如果我只是按下这个button,在游戏过程中,游戏会暂停,但是线程dosnt会像其他时间一样恢复,游戏种类只会停留在屏幕上并闪烁一下。

很难解释,但我希望我有点清楚,如果没有,问!

Solutions Collecting From Web of "如何检测“Recent Apps”系统button点击(Honeycomb +)"

当“最近使用的应用程序”button被按下时,没有标准的Activity Lifecycle方法被调用。 在最近的应用程序popup列表后,活动将保持活动状态。 通过这个列表的半透明的左边部分,你甚至可以观察到应用程序的animation仍在运行,如果你运行的游戏中有一些animation没有正确处理这种情况。 实际上Google Play中的很多游戏都没有正确处理这种情况,即使是好的,比如“愤怒的小鸟”。

当用户打开“Recent Apps”列表(或从中返回)时,唯一的Activity方法是在窗口焦点更改中使用布尔参数hasFocus 。 当用户使用hasFocus调用的最近应用方法onWindowFocusChanged()打开的列表等于false ,当用户在此列表中按Back时,用hasFocus调用的同一方法等于true

我面临类似的问题,所以,我需要知道什么时候用户按最近的应用程序button(旧版本的Android中的菜单键button)。 经过几个小时的研究后,我没有发现一个事件,赶上当主页button或菜单button被按下。 我发现当用户按下主页button时,需要花费更长的时间来调用onStop(),所以我想到了一个技巧来区分这两个button的响应时间和重写两种方法:

@覆盖

 public void onUserLeaveHint() { // do stuff super.onUserLeaveHint(); userLeaveTime = System.currentTimeMillis() ; isNotPower = true; } 

@覆盖

 public void onStop() { super.onStop(); if (isNotPower) { defStop = System.currentTimeMillis() - userLeaveTime; if (defStop > 200 ) { //home button } if (defStop < 200) { //recent apps button } } isNotPower = false; } 
  • isNotPower参数是检查电源button是否被按下 – 当电源button按下onStop()方法被调用,而不是onUserLeaveHint()。

要检测何时按下“最近的应用”button,您可以使用辅助function服务。 您需要运行您自己的辅助function服务,并接收types为“TYPE_WINDOW_STATE_CHANGED”的事件并检查事件的类名称。

  1. 阅读有关Android开发人员的辅助function服务 。 设置您自己的辅助function服务,请求用户的许可。
  2. 在您的辅助function服务覆盖方法onAccessibilityEvent()
  3. 在此方法中,您将收到AccessibilityEvent event对象,该对象包含有关设备上发生的事件的所有必要信息。
  4. 我们对ClassName感兴趣。 ClassName有时可以为null,所以不要忘记!= null检查。 最近的应用程序窗口的包名称将根据Android的版本而有所不同:

    • Android 4.1:“com.android.internal.policy.impl.RecentApplicationsDialog”
    • Android 4.2 – 4.4:“com.android.systemui.recent.RecentsActivity”
    • Android 5.0 – 7.1:“com.android.systemui.recents.RecentsActivity”(“s”字母被添加)

不知道旧设备的类名,但我不认为有人在2017年维护它们;)

所以你会有这样的东西:

 @Override public void onAccessibilityEvent(AccessibilityEvent event) { if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.getClassName() == null) return; String className = String.valueOf(event.getClassName()); if (className.equals("com.android.internal.policy.impl.RecentApplicationsDialog") || className.equals("com.android.systemui.recent.RecentsActivity") || className.equals("com.android.systemui.recents.RecentsActivity")){ //Recent button was pressed. Do something. } } 

我已经在以下真实设备上进行了testing:LG,Nexus,索尼和虚拟设备:摩托罗拉,三星。

如果有人知道这些类名的例外,请ping我。

我发现的最好的方法是广播行动称为“ACTION_CLOSE_SYSTEM_DIALOGS”。从谷歌文档:

广播动作:当用户动作应该请求临时系统对话框消除时广播。 临时系统对话框的一些示例是通知窗口阴影和最近的任务对话框

工作代码:

 IntentFilter intentFilterACSD = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { //do what you want here } } }; this.registerReceiver(broadcastReceiver, intentFilterACSD); 

这只是这个具体游戏的问题吗? 还是每个游戏都玩?

onPause()onResume()旁边,还有一个叫做onStop()循环。 也许这里有一些基本的事情要做。 按下“windows-open”button,游戏可能不会进入onStop-状态,而按下“home”button则会进入。

试试这个:

 public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); Log.d("Focus debug", "Focus changed !"); if (!hasFocus) { Log.d("Focus debug", "Lost focus !"); } }