Android 俯仰和滚动传感器值的更高级别API

Android 俯仰和滚动传感器值的更高级别API,android,sensors,device-orientation,pitch,Android,Sensors,Device Orientation,Pitch,我正在实施我自己的相机活动。 要旋转拍摄的图像,我需要知道拍摄时的方向。 传感器值俯仰和滚动是否有更高级别的API,告诉我我的设备定位在: 自上而下-正常按住手机,纵向 自上而下 右-左-横向-手机顶部位于右侧 左右-横向-手机顶部位于左侧 或者有没有其他方法可以直接从系统中获取它?不幸的是,当相机不处于横向模式时,android上的相机会以一种奇怪的方式工作(这是android上相机的“自然”方向) 最好的做法是将活动设置为横向模式,并添加onConfigurationChanged事件(并将

我正在实施我自己的相机活动。 要旋转拍摄的图像,我需要知道拍摄时的方向。 传感器值俯仰和滚动是否有更高级别的API,告诉我我的设备定位在:

自上而下-正常按住手机,纵向
自上而下
右-左-横向-手机顶部位于右侧
左右-横向-手机顶部位于左侧


或者有没有其他方法可以直接从系统中获取它?

不幸的是,当相机不处于横向模式时,android上的相机会以一种奇怪的方式工作(这是android上相机的“自然”方向)

最好的做法是将活动设置为横向模式,并添加onConfigurationChanged事件(并将android:configChanges=“orientation”添加到清单中),以获取当前方向


拍摄图像时,请检查方向并根据您希望的逻辑进行操作。

确定解决了我的问题,使其适用于我,而我忽略了自下而上的识别

public class DeviceOrientation {

public static final int ORIENTATION_PORTRAIT = 0;
public static final int ORIENTATION_LANDSCAPE_REVERSE = 1;
public static final int ORIENTATION_LANDSCAPE = 2;
public static final int ORIENTATION_PORTRAIT_REVERSE = 3;

int smoothness = 1;
public float averagePitch = 0;
public float averageRoll = 0;
public int orientation = ORIENTATION_PORTRAIT;

private float[] pitches;
private float[] rolls;

public DeviceOrientation(int smoothness) {
    this.smoothness = smoothness;

    pitches = new float[smoothness];
    rolls = new float[smoothness];
}

public void addSensorEvent(SensorEvent event) {
    azimuth = event.values[0];

    averagePitch = addValue(event.values[1], pitches);
    averageRoll = addValue(event.values[2], rolls);

    orientation = calculateOrientation();
}

private float addValue(float value, float[] values) {
    float average = 0;

    for(int i=1; i<smoothness; i++) {
        values[i-1] = values[i];
        average += values[i];
    }
    values[smoothness-1] = value;
    average = (average + value)/smoothness;

    return average;
}

/** handles all 4 possible positions perfectly */
private int calculateOrientation() {
    // finding local orientation dip
    if (((orientation == ORIENTATION_PORTRAIT || orientation == ORIENTATION_PORTRAIT_REVERSE)
            && (averageRoll > -30 && averageRoll < 30))) {
        if (averagePitch > 0)
            return ORIENTATION_PORTRAIT_REVERSE;
        else
            return ORIENTATION_PORTRAIT;
    } else {
        // divides between all orientations
        if (Math.abs(averagePitch) >= 30) {
            if (averagePitch > 0)
                return ORIENTATION_PORTRAIT_REVERSE;
            else
                return ORIENTATION_PORTRAIT;
        } else {
                if (averageRoll > 0) {
                    return ORIENTATION_LANDSCAPE_REVERSE;
                } else {
                    return ORIENTATION_LANDSCAPE;
                }
        }
    }
}
公共类设备定向{
公共静态最终整数方向_纵向=0;
公共静态最终整数方向\横向\反向=1;
公共静态最终int方向_横向=2;
公共静态最终整数方向\纵向\反向=3;
int平滑度=1;
公共浮动平均间距=0;
公共浮动平均值=0;
公共int方向=方向\纵向;
私人浮动[]场;
私人浮动[]卷;
公共设备定向(整数平滑度){
这个。平滑度=平滑度;
音高=新的浮动[平滑度];
转鼓=新浮动[平滑度];
}
public void addSensorEvent(传感器事件){
方位角=事件值[0];
averagePitch=addValue(事件值[1],音高);
averageRoll=addValue(事件值[2],转鼓);
方向=计算方向();
}
私有浮点addValue(浮点值,浮点[]值){
浮动平均值=0;
对于(int i=1;i-30&&averageRoll<30))){
如果(平均间距>0)
返回方向\纵向\反向;
其他的
返回方向与人像;
}否则{
//在所有方向之间划分
如果(数学绝对值(平均螺距)>=30){
如果(平均间距>0)
返回方向\纵向\反向;
其他的
返回方向与人像;
}否则{
如果(平均集合>0){
返回方向\横向\反向;
}否则{
回归导向与景观;
}
}
}
}
说明: 如果我处于纵向模式,并将手机向前倾斜,直到它处于水平位置,由于代码的剩余部分,它将切换到横向。 因此,我检查它是否在纵向,并使条件很难叶这种模式。 这就是我对本地dip的看法。 其余的只分为三个方向

有一件事是不好的。如果设备处于横向,并向后倾斜几度,pich从~2跳到~175。此时,我的代码在横向和纵向之间翻转

平滑度将通过组合最后n个值并计算平均值来平滑传感器数据的值。这不是必需的


我希望这对其他人有帮助。如果你能进一步改进代码,请告诉我。

你说的自上而下,…左-右是什么意思?你可以编写一个函数来检查它,并在需要时调用它。此外,如果你想让别人回答你的问题,你应该接受答案。看看你以前的答案,接受最好的答案。按钮处于答案等级。感谢您的建议,我查看了该功能良好的点。我不知道存在类似OnConfiguration Changed事件的情况。我尝试了它,它只能告诉我是处于纵向模式还是横向模式。当我将相机倾斜到e right或left。我需要一种方法来确定如何旋转结果。如果您的目标是2.2+,您可能会有这样的运气:另一个我从未听说过的API图片;)我尝试过,但它始终显示0度。int rotation=getWindowManager().getDefaultDisplay().getRotation();Maybee这是因为我在清单中设置了固定的方向。代码已更新。要使用它的完整项目在我的谷歌硬盘上。我忽略了可能没有人真正需要的自下而上的方向,如果你将设备倾斜到横向,并向你倾斜一点,使相机看起来向上倾斜约3-10度在横向和纵向之间切换。什么是向下-顶部方向?它是纵向反转吗?它是正常纵向的位置(自上而下)。当您的设备旋转180度时。@我已编辑代码以处理最后一个位置(反向纵向)以防有人像我一样需要它,&感谢计算本身,它帮了我很多:)