2

我正在编写一个相机应用程序,它通过设置在相机预览期间禁用自动旋转android:screenOrientation="nosensor"。但是,我仍然想知道拍照时手机的旋转方向。 getResources().getConfiguration().orientation不够具体,只返回纵向、横向或正方形。 getWindowManager().getDefaultDisplay().getRotation()始终为 0,因为屏幕被迫处于其默认方向 -如果启用自动旋转,我如何获得该值?

4

4 回答 4

6

这有点深入,但可以很好地跟踪方向变化。当打开相机意图并拍摄照片时,我使用它来获取照片方向。然后我知道照片是什么方向。它显然不适用于照片库,但您可以使用 exif 信息。令我惊恐的是,我发现三星 Galaxy S3 和 S4 没有从相机返回 exif 方向数据。

//keep a history
private int [] _orientationHistory = new int[5];
private int _orientationIndex;
private int _highestIndex = -1;
private int _currentOrientation;

//essentially compute the mode of the data. This could be improved
protected int getOrientation()
{
    if (_highestIndex < 0) return 0;

    Arrays.sort(_orientationHistory);
    return _orientationHistory[_highestIndex / 2];
}

OrientationEventListener _imageViewOrientationListener = new            
              OrientationEventListener(getContext(), SensorManager.SENSOR_DELAY_NORMAL) {
public void onOrientationChanged(int angle) {
        //angle comes in 360 degrees, convert that to a 0-3 rotation
        //Get the angle in 90 degree increments, 0,90,180,270 
        //with 45 degrees tolerance in each direction (straight up is 0) 
        //this is the same as the data coming from getWindowManager().getDefaultDisplay().getRotation()

        angle = angle + 45;
        if (angle > 360) angle = angle - 360;
        int orientation = angle / 90;

        //I use a history in order to smooth out noise 
        //and don't start sending events about the change until this history is filled
        if (_orientationIndex > _highestIndex) {
            _highestIndex = _orientationIndex;
        }
        _orientationHistory[_orientationIndex] = orientation;
        _orientationIndex ++;

        if (_orientationIndex == _orientationHistory.length) {
            _orientationIndex = 0;
        }

        int lastOrientation = _currentOrientation;
        //compute the orientation using above method
        _currentOrientation = getOrientation();

        if (_highestIndex == _orientationHistory.length - 1 && lastOrientation != _currentOrientation) {
            //enough data to say things changed
            orientationChanged(lastOrientation, _currentOrientation);
        }
    }
};

然后要启用这个监听器,只需添加这行代码:

if (_imageViewOrientationListener != null) {
     _imageViewOrientationListener.enable();
}

最后,添加方法orientationChanged() 并在方向改变时接收更新。如果您需要像我一样,请在打开相机活动时开始记录此信息,并且如果方向翻转为不同的东西,例如从肖像横向,您可以假设在该时间段内拍摄的照片是您记录的旋转变化.

protected void orientationChanged(int lastOrientation, int currentOrientation) {
    Log.d(getClass().getSimpleName(), "Orientation changed to " + currentOrientation + " from " + lastOrientation);
}
于 2013-07-12T19:17:22.277 回答
1

在活动中,您可以使用

@Override
public void onConfigurationChanged(Configuration newConfig) {    //this method return you latest configuration
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
//  newConfig.orientation  //Using this you will able to get orientation of device
}

此方法在您更改设备配置后调用。

于 2013-04-08T05:29:42.347 回答
1

您可以收听配置更改

<activity
...
            android:configChanges="orientation|screenSize"
...

在 onConfigurationChanged() 中,您可以强制设置所需的方向(例如纵向),但可以获取有关方向更改的信息。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    //get new configuration orientation from newConfig.orientation
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

并且不要使用 android:screenOrientation="portrait" 所以当用户改变方向时 onConfigurationChanged 将被调用。

于 2013-04-08T06:51:36.147 回答
0

当设备的方向发生变化时,使用此类接收来自 SensorManager 的通知。

于 2013-04-08T05:09:55.627 回答