如何在Android中获得方向(如北、西)

如何在Android中获得方向(如北、西),android,android-manifest,compass-geolocation,Android,Android Manifest,Compass Geolocation,我是Android新手,我想根据我的相机来判断方向。如何根据相机获取方向信息?你能给出一个想法吗?根据你的相机不确定你指的是什么,但你可以根据硬件传感器得到它。请参阅以下链接: 另请查看第页的传感器类型\方向。类型\方向已弃用 我们不能再使用方向传感器了,我们可以同时使用磁场传感器和加速度传感器来获得等效的功能。这需要更多的工作,但它允许继续使用回调来处理方向更改 这是一个指南针样本: 从加速计和磁场到方位角的转换: 要指向北方,可以计算旋转角度: float rotation = -azi

我是Android新手,我想根据我的相机来判断方向。如何根据相机获取方向信息?你能给出一个想法吗?

根据你的相机不确定你指的是什么,但你可以根据硬件传感器得到它。请参阅以下链接:

另请查看第页的传感器
类型\方向

类型\方向已弃用 我们不能再使用方向传感器了,我们可以同时使用磁场传感器和加速度传感器来获得等效的功能。这需要更多的工作,但它允许继续使用回调来处理方向更改

这是一个指南针样本

从加速计和磁场到方位角的转换:

要指向北方,可以计算旋转角度:

float rotation = -azimut * 360 / (2 * 3.14159f);

到目前为止,我得到的数据对我来说有些有用,返回的值在0-360之间,但我认为north没有正确校准?我在运行安卓5.0.1的LG G Pad上使用这个

public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        mGravity = event.values;
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
        mGeomagnetic = event.values;
    if (mGravity != null && mGeomagnetic != null) {
        float R[] = new float[9];
        float outR[] = new float[9];
        float I[] = new float[9];

        boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
        if (success) {
            float orientation[] = new float[3];

            SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Y, outR);

            SensorManager.getOrientation(outR, orientation);
            azimut = orientation[0];

            float degree = (float)(Math.toDegrees(azimut)+360)%360;

            System.out.println("degree " + degree);

我肯定我错过了一些东西,但希望这对其他人来说是一个不错的起点。为了达到这一点,我回顾了大量其他问题、评论等。

使用旋转矢量传感器,它结合了地磁和重力传感器。然后使用将5个值的数组转换为OpenGL样式的旋转矩阵。正如文档所述,第一个值是指南针方向(弧度)

就其本身而言,这并不能解决您从相机角度了解指南针方向的问题。相反,它假设屏幕与地面平行,就像老式的袖珍指南针一样,并报告屏幕顶部指向的方向。因此,如果屏幕顶部朝北,则方向(
event.values[0]
)为0。如果屏幕顶部笔直向上,则方向未定义。不幸的是,这是使用相机时常见的情况

在示例侦听器中,我将使用枚举在Android的默认袖珍指南针样式方向和后置摄像头方向之间切换,这样您就可以看到Android期望的用例和您想要的用例

enum class CompassCoordinateSystem { POCKET_COMPASS, REAR_CAMERA }
然后编写一个
SensorEventListener
来跟踪更改。为清楚起见,我没有在下面的代码中导入android.hardware.SensorManager.*
。下面定义的所有阵列都由SensorManager静态方法填充

/** The latest compass orientation as a 3D vector. */
private var orientation3D = FloatArray(3)
private var coordinateSystem = CompassCoordinateSystem.REAR_CAMERA_ROTATION

fun compassDegrees(): Float = azimuthToDegrees(compassRadians())
fun compassRadians(): Float = orientation3D[0]

/** Convert such that North=0, East=90, South=180, West=270. */
fun azimuthToDegrees(azimuth: Float): Float {
    return ((Math.toDegrees(azimuth.toDouble())+360) % 360).toFloat()
}

override fun onSensorChanged(event: SensorEvent?) {
    if (event?.sensor?.type == Sensor.TYPE_ROTATION_VECTOR) {
         val rotationMatrix = FloatArray(9)
         SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
         when (coordinateSystem) {
            CompassCoordinateSystem.POCKET_COMPASS -> SensorManager.getOrientation(rotationMatrix, orientation3D)
            CompassCoordinateSystem.REAR_CAMERA -> {
                val rearCameraMatrix = FloatArray(9)
                // The axis parameters for remapCoordinateSystem() are
                // from an example in that method's documentation
                SensorManager.remapCoordinateSystem(rotationMatrix,
                    SensorManager.AXIS_X, 
                    SensorManager.AXIS_Z, 
                    rearCameraMatrix)
                SensorManager.getOrientation(rearCameraMatrix, orientation3D)
            }
        }
    }
}

类型_定向已被弃用,请参阅链接似乎不起作用。请给出一个例子或另一个链接。当然不清楚你的变量指的是什么。旋转向量、mvaluesororientation等@jaswansinggh:我重写了这个例子,不仅是为了修正变量,也是为了修正摄像机的方向。
/** The latest compass orientation as a 3D vector. */
private var orientation3D = FloatArray(3)
private var coordinateSystem = CompassCoordinateSystem.REAR_CAMERA_ROTATION

fun compassDegrees(): Float = azimuthToDegrees(compassRadians())
fun compassRadians(): Float = orientation3D[0]

/** Convert such that North=0, East=90, South=180, West=270. */
fun azimuthToDegrees(azimuth: Float): Float {
    return ((Math.toDegrees(azimuth.toDouble())+360) % 360).toFloat()
}

override fun onSensorChanged(event: SensorEvent?) {
    if (event?.sensor?.type == Sensor.TYPE_ROTATION_VECTOR) {
         val rotationMatrix = FloatArray(9)
         SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
         when (coordinateSystem) {
            CompassCoordinateSystem.POCKET_COMPASS -> SensorManager.getOrientation(rotationMatrix, orientation3D)
            CompassCoordinateSystem.REAR_CAMERA -> {
                val rearCameraMatrix = FloatArray(9)
                // The axis parameters for remapCoordinateSystem() are
                // from an example in that method's documentation
                SensorManager.remapCoordinateSystem(rotationMatrix,
                    SensorManager.AXIS_X, 
                    SensorManager.AXIS_Z, 
                    rearCameraMatrix)
                SensorManager.getOrientation(rearCameraMatrix, orientation3D)
            }
        }
    }
}