防止锁屏后横屏Android应用程序重新启动

3
我正在开发一款使用OpenGL并具备背景音乐的游戏。应用仅支持横屏模式。问题在于,当用户锁定屏幕时会出现问题。此时会调用onStop()方法,屏幕方向会改变,随即由于方向改变而重启Activity。这意味着OpenGL表面被重新创建,音乐再次开始播放以及其他各种情况。这与锁定屏幕应该暂停CPU密集型操作的直觉相反。
android:configChanges="orientation"添加到清单文件中没有起到任何作用。我意识到我可能缺少screenSize选项,但由于我针对的是早期API版本,因此无法添加它。
因此,我的问题是:应该如何处理这个问题?我该在哪个事件上初始化我的应用程序以使一切按预期工作?

你的游戏在手机锁屏时重启了? - DeeV
不,这是我的活动。每次方向改变时,Android都会重新创建活动。 - MeanEYE
6个回答

5

在清单文件中将screenSize添加到configChanges并不意味着您的程序不能在较旧的版本上运行。您只需要将targetSdkVersion设置为更高的版本,minSdkVersion设置为任何您喜欢的版本即可。在IntelliJ IDEA中,我在项目结构中将Module SDK设置为4,因此它不会将screenSize标记为无效。在Eclipse中也应该类似。

<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />

<activity android:name=".MyActivity"
      android:label="@string/app_name"
      android:configChanges="orientation|screenSize|keyboard|keyboardHidden|navigation">

你可以像这样在代码中检查版本:

if (Build.VERSION.SDK_INT >= 11) 

这样你的应用程序就可以在2.2及更高版本上运行。我认为你不需要onConfigurationChanged,因为你的游戏可能只在横屏模式下运行,但如果你感兴趣,可以看看我类似于你的问题和我的答案。 在方向变化时替换布局

当我尝试将此添加到我的清单文件时,Eclipse给出了这个错误:“错误:不允许字符串类型(具有值'orientation | screenSize | keyboard | keyboardHidden | navigation'的“configChanges”)。” - MeanEYE
screenSize在Android 3.0中引入,所以我不能为2.2添加它。即使删除它也没有帮助。 - MeanEYE
@MeanEYE 请尝试使用IntellijIDEA,它的社区版本是免费的,比eclipse更快、更功能丰富。我没有eclipse,所以无法告诉您第一个评论的问题在哪里。 - Ali
@MeanEYE,这没有问题,您可以在旧设备上运行时使用新标签。我再告诉您如何在Intellij中配置它,您需要进入文件菜单,项目结构,模块,选择您的模块,在依赖项选项卡中,选择Android 3.0+作为模块SDK,这样就不会抱怨未知属性。在清单中将minSdk设置为8(2.2)或其他版本。现在您的代码可以编译而不会出现任何错误,并且仍然可以在8+设备上运行。您甚至可以通过检查正确的版本来调用更高版本的API。 - Ali
@MeanEYE 如果你有Intellj,但无法完成它,请告诉我,我会为您创建一个符合这些要求的工作项目。 - Ali
这应该是被接受的答案,因为它正确地解决了Android问题的根本原因。 - Cory Trese

2

在Manifest.xml中的你的activity中添加标签

"android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout"

并重写方法

public void onConfigurationChanged(Configuration newConfig) {}

嗯,我得试着覆盖那个方法。一旦我做完,我会回复你的。 - MeanEYE
还没试过。 抱歉,我有点慢。 - MeanEYE
没起作用。行为还是一样的。当我锁定屏幕后,我的活动被重新启动了。 - MeanEYE
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"android:configChanges="orientation|keyboardHidden|screenSize|screenLayout" - Cory Trese

1
        @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onRestoreInstanceState(savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
    // TODO Auto-generated method stub
    super.onSaveInstanceState(outState);
}

以上是在活动中保存状态的两种方法,当活动方向改变时使用。它以键值对的形式将数据保存在bundle对象中。
不需要在Androidmanifest.xml文件中添加任何标记来实现上述代码。 android:screenOrientation="landscape" 这个标记可以用来让你的活动只在横屏模式下运行。这个标记应该添加到Androidmanifest.xml中存在的活动标记中。

1
在您的具体情况下,我更喜欢使用这个:
@Override
protected void onCreate(final Bundle savedInstance) {
    super.onCreate(savedInstance);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}

适用于所有情况,并强制使您的活动仅限横向模式。


1
如果您的游戏只支持横屏模式,请尝试在标签中设置android:screenOrientation="landscape"属性。

1

我认为你需要接受这样一个事实,当手机锁定时,你的Activity将被暂停和/或停止。这意味着你需要重新启动一些东西。在阅读了一本带有OpenGL的Android游戏开发书后,我也是这样理解的。

你可以做的比@421建议的更多。在onSaveInstanceState和onRestoreInstanceState中,你可以存储你所在歌曲的一部分以及任何其他数据,使得即使游戏必须重新加载一些东西,“平稳”地再次开始。

如果你到现在为止还没有找到其他答案,这可能就是原因。我曾经遇到很多游戏在手机锁定后做出奇怪的行为而感到烦恼。你只需要正确且平稳地手动处理它。


最后我想我只能这样做了。谢谢。 - MeanEYE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接