在特定条件下恢复应用程序时,后退和音量按钮不起作用

时间:2014-06-13 17:08:33

标签: android-activity touch google-play-services leaderboard start-activity

我正在开始一项新活动,以在我的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商店的其他几个应用程序上对此进行了测试,并得到了相同的结果。

一个应用程序明显使用像我这样的单一活动模型,后面和音量停止在整个应用程序中工作。

另一个可能会对菜单和游戏使用不同的活动。当我在这个应用程序上测试时,后面/音量中断但是如果你开始一个游戏(因此是第二个活动),后退键会重新开始工作,即使你返回第一个活动(重新创建这个活动?!)

所以也许我可以通过确保重新创建活动来解决这个问题?我以为我已经,但也许我没有得到什么。也许这与堆栈有关.........

2 个答案:

答案 0 :(得分:2)

我没有办法解决您的问题,但有一些额外的见解,因为我在排行榜和后退按钮方面面临同样的错误/问题(而且它让我发疯了)。

我使用单个活动来处理我登录Google Play的片段,以您完全正确的方式打开排行榜和成就(startActivityForResult)。总是当我从任何Google Play服务活动回来时,我的后退按钮已损坏。有时,如果我尝试登录Google Play以使其中断,这甚至是足够的,这意味着登录弹出窗口有时会破坏后退按钮(但并非总是如此)。

可能有助于解决问题的更多见解:

  • 我没有使用OpenGL,所以它与此无关 - 我只使用一个活动和片段
  • 当我只使用后退按钮从任何Google Play活动中返回时,它也会让我失望(我甚至不需要通过主页键,只需正常的后退即可)。
  • 当后退按钮被破坏时,Activity没有收到任何关键事件(OnKeyDown,OnKeyUp,dispatchKeyEvent)都无法正常工作,尽管使用该活动并完全触摸它。我的猜测是,有些观点正在抓住事件......

修改

我还尝试检查 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"/>

我有动态布局,所以我不能确定我的布局中是否存在任何视图,所以我创建了这个虚拟视图,它也可能以编程方式添加。您可以选择固定的视图来获得焦点,但请记住,更改焦点可能会改变视图的外观(可绘制状态)。