我正在开始一项新活动,以在我的Android应用中显示排行榜。
当显示排行榜活动,并且用户按下主页键然后恢复应用程序(以便再次出现排行榜活动),然后按下导航键回到主要活动后退键,后退键和音量键停止工作)。
我试图在我的活动类中覆盖onBackPressed。我可以确认,当出现此问题时, onBackPressed未被调用(当后退/音量正在工作时,按下后会触发onBackPressed)。
通常我在LogCat中收到一条消息,当我按下后退键'未实现的WebView方法onKeyDown从android.webkit.WebView,onKeyDown(WebView.java.2178)调用时 - 再次当后退键不起作用时,我可以确认此消息没有出现
有了上述信息,我只能假设它与View没有焦点或某些东西有关。我会指出屏幕上的触摸输入确实有效。它似乎只是后面和音量键/按钮没有效果。
这是一个openGL ES 2.0应用,所以在我的onPause()中我正在调用view.onPause();在onResume中,我正在调用view.onResume();
我真的不知道发生了什么,我已经连续3天了,所以如果有人能指出我正确的方向,那就太好了。
如果用户退出排行榜并返回主应用之前他们按下主页键,则一切正常,只是在显示排行榜活动时按下主页键如上所述。
因此,当我在后面/音量键不起作用的时候,如果我点击我的分数按钮并再次启动排行榜活动,它们就会起作用。回到我的活动后,他们再次停止工作。
不确定这是否相关,但以下显示了我如何开始我的排行榜活动:
if (scoresButtonPresses){
displayLeaderBoard();
}
void displayLeaderBoard(){
//Display the leaderboard if already signed in
if (checkSignedIn()){
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID), 1);
}
//if not already connected, then set flag and connect to play services before displaying leaderbaord
else{
signInAction=SHOW_LEADERBOARD;
getGameHelper().beginUserInitiatedSignIn();
}
}
@Override
public void onSignInSucceeded() {
//If the flag is set, then display the leaderboard
if (signInAction==DISPLAY_LEADERBOARD){
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID), 1);
}
//Otherwise, reset the flag and take no action
else {signInAction=NO_ACTION;}
}
这让我发疯,所以任何帮助甚至是正确方向的推动都会非常感激!!
修改
经过多次测试后,我学到了很多东西:
如果我删除了view.onPause()&& view.onResume()问题似乎消失了。所以这似乎与视图捕获关键事件的方式有关。暂停和恢复似乎搞砸了。
我也试过删除上面的view.onPause()和view.onResume(),而是放入View.setVisibility(View.GONE);然后在public void onWindowFocusChanged(boolean hasFocus)中再次显示它。我再次遇到同样的问题。有趣的是,当我打开排行榜时,正如预期的那样,视图的状态“已经消失”,然后点击主键并再次运行应用程序,它又回到“可见”状态 - 我不明白这种行为,但我会问另一个问题为此。
最后,我发现这很奇怪。如果我把我的应用程序恢复到原来的状态,那么在点击主页键并重新启动应用程序通过Eclipse (我可以多次执行此操作)后,问题似乎不会发生。因此,在这方面,它似乎与触摸屏幕有关。
修改
好像这不仅限于我的应用。我已经在Play商店的其他几个应用程序上对此进行了测试,并得到了相同的结果。
一个应用程序明显使用像我这样的单一活动模型,后面和音量停止在整个应用程序中工作。
另一个可能会对菜单和游戏使用不同的活动。当我在这个应用程序上测试时,后面/音量中断但是如果你开始一个游戏(因此是第二个活动),后退键会重新开始工作,即使你返回第一个活动(重新创建这个活动?!)
所以也许我可以通过确保重新创建活动来解决这个问题?我以为我已经,但也许我没有得到什么。也许这与堆栈有关.........
答案 0 :(得分:2)
我没有办法解决您的问题,但有一些额外的见解,因为我在排行榜和后退按钮方面面临同样的错误/问题(而且它让我发疯了)。
我使用单个活动来处理我登录Google Play的片段,以您完全正确的方式打开排行榜和成就(startActivityForResult)。总是当我从任何Google Play服务活动回来时,我的后退按钮已损坏。有时,如果我尝试登录Google Play以使其中断,这甚至是足够的,这意味着登录弹出窗口有时会破坏后退按钮(但并非总是如此)。
可能有助于解决问题的更多见解:
修改强>
我还尝试检查 activity.getCurrentFocus()和 activity.hasWindowFocus()以及 activity.getCurrentFocus()的父类和上下文类< / em>看看它何时起作用以及它何时不起作用 - 并且没有任何区别......
修改强>
似乎对 View.requestFocus()的简单调用正在解决问题。对于我的单个活动(使用片段实现),我现在添加了:
@Override
public void onResume(){
super.onResume();
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragmentContainer);
fragment.getView().requestFocus();
}
这似乎解决了这个问题。如果它总是固定的,必须进行长期检查。在你的OpenGL实现中,我猜你必须以其他方式获取活动的主视图,因为你没有使用片段。
答案 1 :(得分:0)
我知道这是一个非常古老的问题,但为了澄清:接受的答案是正确的,但不完整。焦点请求应该在onResume,onActivityResult,onSignInSucceeded和onSignInFailed中完成。在前两个你有!打电话给超级。一些代码:
private void requestFocusAfterGooglePlay(){
if(gimmeFocus==null)
return;
View currFocus=getCurrentFocus();
gimmeFocus.setFocusableInTouchMode(true);
gimmeFocus.setFocusable(true);
gimmeFocus.requestFocus();
gimmeFocus.setFocusableInTouchMode(false);
gimmeFocus.setFocusable(false);
if(currFocus!=null)
currFocus.requestFocus();
}
@Override
public void onSignInFailed() {
requestFocusAfterGooglePlay();
}
@Override
public void onSignInSucceeded() {
requestFocusAfterGooglePlay();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
requestFocusAfterGooglePlay();
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onResume(){
super.onResume();
requestFocusAfterGooglePlay();
}
在我的情况下,gimmeFocus是一个虚拟视图,如下所示:
<View
android:id="@+id/gimme_focus"
android:layout_width="0px"
android:layout_height="0px"
android:focusable="false"
android:focusableInTouchMode="false"/>
我有动态布局,所以我不能确定我的布局中是否存在任何视图,所以我创建了这个虚拟视图,它也可能以编程方式添加。您可以选择固定的视图来获得焦点,但请记住,更改焦点可能会改变视图的外观(可绘制状态)。