在活动被破坏之前检测旋转(方向变化)

时间:2016-11-16 18:04:22

标签: android android-activity screen-orientation

目标

如果用户离开应用程序(主页按钮,任务切换,任务中断,屏幕关闭等),我正在处理简化音频播放器需要停止播放。我可以让音频继续在后台播放并打开一个带有暂停/停止选项的通知栏,但我的用户几乎没有计算机知识,有些人可能无法在没有帮助的情况下停止音频。

问题

为了停止音频,我需要知道在活动被销毁之前应用程序何时移出焦点。 Android提供了两种方法onStop和onPause,它们表明正在发生的事情,但不是什么。如果可能的话,我如何知道活动何时因方向改变而被销毁?

失败的解决方案

我可以在onPause(或onStop / onDestroy)中使用isFinishing()来检查应用程序是否正在关闭并停止音频。但这只会告诉我们申请何时结束。它没有区分进入背景和旋转。

IsChangingConfigurations是一个有趣的功能,可以解决我的问题,但这需要API 11,我有兴趣支持API 10。

其他解决方案似乎是一个糟糕的黑客。 OrientationChangeListener与this solution一样,似乎是理想的,但它只注意到活动关闭并重新启动后方向已经改变。

与上述选项类似,onConfigurationChanged仅在方向更改后报告方向更改。

有缺陷但可能的解决方案

一种解决方案是在与活动失去连接后让媒体播放器服务通知,然后在一段时间后自动暂停。这绝对是一个可行的解决方案,但它并不理想。多少时间合适?如果平板电脑运行缓慢且旋转时间比平时长,会发生什么?如果没有更好的选择,我会回到这个解决方案。这似乎是一个黑客,容易出错。

2 个答案:

答案 0 :(得分:6)

我在我的片段中使用它(api 11+,但您可以手动决定如何处理旧版本):

@Override
public void onPause() {
    super.onPause();
    if (isRecreating()) {
        //do smth
    }
}

public boolean isRecreating() {
    //consider pre honeycomb not recreating
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB &&
            getActivity().isChangingConfigurations();
}

答案 1 :(得分:1)

在发布问题之前经过大量搜索后,我终于想出了一个基于this post的解决方案。我只是简单地检查当前方向并将其与之前的状态进行比较。

getResources().getConfiguration().orientation

如果不同,则活动因旋转而重新启动。

示例解决方案

我首先要有两个成员变量来跟踪以前的配置并标记旋转:

private int previousOrientation = Configuration.ORIENTATION_UNDEFINED;
private boolean rotating = false;

当活动开始时,在onCreate中,我调用checkAndSetOrientationInfo(),其定义为:

private void checkAndSetOrientationInfo() {
    int currentOrientation = getResources().getConfiguration().orientation;
    debugDescribeOrientations(currentOrientation);
    if(previousOrientation != Configuration.ORIENTATION_UNDEFINED // starts undefined
            && previousOrientation != currentOrientation) rotating = true;

    previousOrientation = currentOrientation;
}

支持功能是:

private String getOrientationAsString(final int orientation) {
    if(orientation == Configuration.ORIENTATION_LANDSCAPE) {
        return "Landscape";
    } else if(orientation == Configuration.ORIENTATION_PORTRAIT) {
        return "Portrait";
    } else return "Undefined";
}

private void debugDescribeOrientations(final int currentOrientation) {
    Log.v("Orientation", "previousOrientation: " + getOrientationAsString(previousOrientation));
    Log.v("Orientation", "currentOrientation: " + getOrientationAsString(currentOrientation));
}

最后,对于onPause:

@Override
protected void onPause() {
    super.onPause();
    if (isFinishing()) {
        Log.v("onPause", "Finishing");
    } else {
        checkAndSetOrientationInfo();
        if (rotating) {
            Log.v("onPause", "Rotating");
        } else {
           Log.v("onPause", "Not rotating (task switch / home etc)");
           // TODO put code here to pause mediaPlayer etc...
        }
    }
}

我问并回答了这个问题,以帮助其他人解决同样的问题。我也有兴趣看到有关此代码可能失败的情况或其他更好解决方案的任何评论。