我想知道这个按钮叫什么方法。
我的游戏总是暂停/恢复正常情况,除非我使用此按钮时,似乎此按钮不会调用Activity的onPause()
和onResume()
方法。
它可以工作,如果我退出游戏,转到另一个窗口(如图片中的那个),然后使用此按钮恢复。但是,如果我只是按下这个按钮,当游戏时,游戏暂停,但线程dosnt恢复就像它每隔一段时间一样,游戏类型只是停留在屏幕上并且有点闪烁。
很难解释,但我希望我有点清楚,如果没有,请问!
答案 0 :(得分:23)
按下“Recent Apps”按钮时,不会调用任何标准Activity Lifecycle方法。在最近的应用弹出列表后,活动将保持活动状态。通过此列表的半透明左侧部分,您甚至可以观察应用程序动画是否仍在运行,如果您运行的游戏中包含一些无法正确处理此情况的动画。实际上,Google Play中的许多游戏都没有正确处理这种情况,即使是像“愤怒的小鸟”这样的好游戏。
当用户打开“Recent Apps”列表(或从中返回)时,调用唯一的Activity方法是onWindowFocusChanged,其布尔参数为hasFocus
。当用户在此列表中按“返回”时,当用户打开使用onWindowFocusChanged()
调用的最近应用方法hasFocus
的列表等于false
时,使用hasFocus
调用的相同方法等于true
答案 1 :(得分:5)
检测“最近的应用”和“#39;按下按钮您可以使用辅助功能服务。您需要运行自己的辅助功能服务并接收类型为" TYPE_WINDOW_STATE_CHANGED"的事件。并查看活动的班级名称。
onAccessibilityEvent()
AccessibilityEvent event
个对象,此对象包含有关您设备上刚刚发生的事件的所有必要信息。我们对ClassName感兴趣。 ClassName有时可以为null,所以不要忘记!= null check。 最近的应用程序窗口的程序包名称将根据Android的版本而有所不同:
不知道旧设备的班级名称,但我不认为有人在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.
}
}
我已经在以下真实设备上测试过它:LG,Nexus,索尼和虚拟设备:摩托罗拉,三星。
如果有人知道这些班级名称的例外情况,请告诉我。
答案 2 :(得分:4)
我有同样的问题,我解决了这个问题如下。
注册按钮点击Home和RecentApp的广播
InnerReceiver mReceiver = new InnerReceiver();
IntentFilter mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mReceiver, mFilter);
现在是BroadcastReceiver代码
class InnerReceiver extends BroadcastReceiver {
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
if (mListener != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
// Home Button click
} else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
// RecentApp or Overview Button click
}
}
}
}
}
}
但是别忘了unregisterReceiver
BroadcastReceiver
答案 3 :(得分:3)
我遇到了类似的问题,所以,我需要知道用户何时按下最近的应用程序按钮(旧版Android中的菜单键按钮)。经过几个小时的研究后,当按下主页按钮或菜单按钮时,我没有发现要捕获的事件。我发现当用户按下主页按钮时,需要花费更长的时间来调用onStop(),所以我找到一个技巧来区分这些与响应时间相关的拖拽按钮和覆盖两种方法:
@覆盖
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;
}
答案 4 :(得分:2)
我找到的最佳方式是持续广播行动称为&#34; ACTION_CLOSE_SYSTEM_DIALOGS&#34;。来自Google文档:
广播操作:当用户操作请求时广播 解雇临时系统对话框。临时系统的一些例子 对话框是通知窗口阴影和最近任务对话框。
工作代码:
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);
答案 5 :(得分:0)
这只是这个特定游戏的问题吗?或者你玩的每一场比赛都是这样吗?
在onPause()
和onResume()
旁边,还有另一个名为onStop()
的周期。也许这里有一些基本的事情要做。通过按下“开窗”按钮,游戏可能不会进入onStop
- 状态,而按下“主页”按钮则会。
答案 6 :(得分:0)
试试这个:
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("Focus debug", "Focus changed !");
if (!hasFocus) {
Log.d("Focus debug", "Lost focus !");
}
}
答案 7 :(得分:0)
我写了一个应用程序,明确地展示了最近应用程序 / 最近键相对于活动和片段的行为。
(任何断言正常生命周期事件均未通过此键触发的说法显然都是错误的。)
在onCreate()
中,主 Activity 初始化一个数组,用于记录所有已知的 Activity 生命周期事件,并在第二个FrameLayout中将主Fragment与其自身一起触发
在onAttach()
中,主要的 Fragment 初始化一个单独的数组,用于记录所有已知的 Fragment 生命周期事件。
出于记录目的, Activity 和 Fragment 都将onWindowFocusChanged()
视为另一个生命周期事件。
记录的事件带有时间戳,因此在渲染时可以给出用户“暂停”指示(并且onWindowFocusChanged()
时,渲染发生在hasFocus==true
内部)。
这是启动测试应用程序时用户看到的内容:
几秒钟后,用户按下 recent-apps ,等待几秒钟,然后再次按下以查看真相:
注意:如果不是通过使用“最近使用的应用程序”按钮,而是通过(a)按下数位板关闭/打开按钮(b)按下“开始第二个活动”按钮(c)等重复进行实验,则得出相同的结果。 / p>
答复OP:
显然,没有任何代码可以检测到对最新应用程序键的实际按下!
但这没关系,因为应用程序仍然需要正确处理关联的生命周期事件。