2016-11-16 96 views
2

目标检测旋转(方向更改)破坏

我工作的一个简化的音频播放器需要停止,如果用户从应用程序(home键,任务切换,任务中断移开打,屏幕关闭等)。我可以让音频继续在后台播放,并打开带有暂停/停止选项的通知栏,但我的用户几乎不懂电脑,有些可能无法在没有帮助的情况下停止音频。

问题

为了阻止声音,我需要知道当应用程序移动到焦点的活性被破坏之前。 Android提供了两种方法onStop和onPause,它们指示正在发生的事情,但不是什么。如果可能的话,我怎么知道活动在什么时候被改变方向?

未能解决

我可以使用内的onPause isFinishing()(或的onStop /的onDestroy)来检查应用程序是否关闭和停止音频。但是这只能告诉我们应用何时关闭。它不区分移动到背景和旋转。

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

另一种解决方案似乎是一个糟糕的黑客。 OrientationChangeListener(如this solution)看起来很理想,但它只是注意到活动关闭并重新启动后方向已更改。

与上述选项类似,onConfigurationChanged只在制作完成后报告方向更改。

有缺陷的,但可能的解决方案

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

+0

为什么你不加'机器人:configChanges =“方向|键盘| keyboardHidden“'到您的''声明中,Android会调用'onConfigurationChanged()'而不会破坏你的'Activity'。然后您可以自己处理配置更改。 –

回答

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... 
     } 
    } 
} 

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

4

我在片段使用这个(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(); 
} 
+0

不错。由于必须支持API 10,我甚至没有查看该功能。 – David

+0

当键盘可用性或语言更改时,这也会触发:https://developer.android.com/guide/topics/resources/runtime-changes。 html –

+0

@RafałZawadzki是的,但键盘更改不会暂停活动,我认为 – j2esu