我如何得到正确的方位(磁方位),无论屏幕方向? [英] How do I get the correct bearing (magnetic orientation) regardless of screen orientation?

查看:610
本文介绍了我如何得到正确的方位(磁方位),无论屏幕方向?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获得当前磁性取向无论当前屏幕方向(横向或纵向)。

I want to get the current magnetic orientation regardless of the current screen orientation (landscape or portrait).

我发现这个的例子,但它不是方向独立,对吧?和没有帮助我满意。我也看过的http://android-developers.blogspot.de/2010/09/one-screen-turn-deserves-another.html.

I found this example, but it's not orientation independant, right? And this didn't help me either. I did also read http://android-developers.blogspot.de/2010/09/one-screen-turn-deserves-another.html.

这是我目前的做法与德precated办法,我不想用(短):

This is my current approach with the deprecated way I don't want to use (short):

mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

private SensorEventListener sensorEventListener = new SensorEventListener() {

    public void onSensorChanged(SensorEvent event) {

        /* Get measured value */
        float current_measured_bearing = (float) event.values[0];

        /* Compensate device orientation */
        switch (((WindowManager) getSystemService(WINDOW_SERVICE))
                .getDefaultDisplay().getRotation()) {
        case Surface.ROTATION_90:
            current_measured_bearing = current_measured_bearing + 90f;
            break;
        case Surface.ROTATION_180:
            current_measured_bearing = current_measured_bearing - 180f;
            break;
        case Surface.ROTATION_270:
            current_measured_bearing = current_measured_bearing - 90f;
            break;
        }

但最后一部分肯定是不对的!如何在这种情况下,正确地使用较新的方法 getRotationMatrix()? (方向无关)或者,我只需要使用 event.values​​ [] 基于旋转矩阵阵列中的其他值?或将我需要重新映射坐标?那么,<一个href="http://stackoverflow.com/questions/11744201/android-sensor-type-orientation-works-perfect-and-i-cant-get-the-same-results-w">that实现这一目标的正确方法是什么?

But the last part is definitely wrong! How do I use the newer method getRotationMatrix() correctly in this case? (Orientation independent) Or do I simply have to use other values of the event.values[] array based on the Rotation Matrix? Or will I need to 'remap the coordinates'? So is that the correct way of achieving this?

我正在开发的360度屏幕旋转和API级别11 +设备。

I'm developing for devices with 360° screen rotation and on API Level 11+.

我知道,这些问题的提出往往但我根本就没有自己的答案传送给我的问题。

I know that those questions are asked very often but I could simply not transfer their answers to my question.

推荐答案

确定我终于设法得到code工作!

OK I finally managed to get the code working!

首先,我注册一个 Sensor.TYPE_MAGNETIC_FIELD Sensor.TYPE_GRAVITY :(!喜欢的还阮说)

First, I register a Sensor.TYPE_MAGNETIC_FIELD and Sensor.TYPE_GRAVITY: (like Hoan Nguyen said!)

/**
 * Initialize the Sensors (Gravity and magnetic field, required as a compass
 * sensor)
 */
private void initSensors() {

    LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    Sensor mSensorGravity = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
    Sensor mSensorMagneticField = sensorManager
            .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

    /* Initialize the gravity sensor */
    if (mSensorGravity != null) {
        Log.i(TAG, "Gravity sensor available. (TYPE_GRAVITY)");
        sensorManager.registerListener(mSensorEventListener,
                mSensorGravity, SensorManager.SENSOR_DELAY_GAME);
    } else {
        Log.i(TAG, "Gravity sensor unavailable. (TYPE_GRAVITY)");
    }

    /* Initialize the magnetic field sensor */
    if (mSensorMagneticField != null) {
        Log.i(TAG, "Magnetic field sensor available. (TYPE_MAGNETIC_FIELD)");
        sensorManager.registerListener(mSensorEventListener,
                mSensorMagneticField, SensorManager.SENSOR_DELAY_GAME);
    } else {
        Log.i(TAG,
                "Magnetic field sensor unavailable. (TYPE_MAGNETIC_FIELD)");
    }
}

和我使用 SensorEventListner 的计算:

private SensorEventListener mSensorEventListener = new SensorEventListener() {

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {

            mGravity = event.values.clone();

        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {

            mMagnetic = event.values.clone();

        }

        if (mGravity != null && mMagnetic != null) {

            /* Create rotation Matrix */
            float[] rotationMatrix = new float[9];
            if (SensorManager.getRotationMatrix(rotationMatrix, null,
                    mGravity, mMagnetic)) {

                /* Compensate device orientation */
                // http://android-developers.blogspot.de/2010/09/one-screen-turn-deserves-another.html
                float[] remappedRotationMatrix = new float[9];
                switch (getWindowManager().getDefaultDisplay()
                        .getRotation()) {
                case Surface.ROTATION_0:
                    SensorManager.remapCoordinateSystem(rotationMatrix,
                            SensorManager.AXIS_X, SensorManager.AXIS_Y,
                            remappedRotationMatrix);
                    break;
                case Surface.ROTATION_90:
                    SensorManager.remapCoordinateSystem(rotationMatrix,
                            SensorManager.AXIS_Y,
                            SensorManager.AXIS_MINUS_X,
                            remappedRotationMatrix);
                    break;
                case Surface.ROTATION_180:
                    SensorManager.remapCoordinateSystem(rotationMatrix,
                            SensorManager.AXIS_MINUS_X,
                            SensorManager.AXIS_MINUS_Y,
                            remappedRotationMatrix);
                    break;
                case Surface.ROTATION_270:
                    SensorManager.remapCoordinateSystem(rotationMatrix,
                            SensorManager.AXIS_MINUS_Y,
                            SensorManager.AXIS_X, remappedRotationMatrix);
                    break;
                }

                /* Calculate Orientation */
                float results[] = new float[3];
                SensorManager.getOrientation(remappedRotationMatrix,
                        results);

                /* Get measured value */
                float current_measured_bearing = (float) (results[0] * 180 / Math.PI);
                if (current_measured_bearing < 0) {
                    current_measured_bearing += 360;
                }

                /* Smooth values using a 'Low Pass Filter' */
                current_measured_bearing = current_measured_bearing
                        + SMOOTHING_FACTOR_COMPASS
                        * (current_measured_bearing - compass_last_measured_bearing);

                /* Update normal output */
                visual_compass_value.setText(String.valueOf(Math
                        .round(current_bearing))
                        + getString(R.string.degrees));

                /*
                 * Update variables for next use (Required for Low Pass
                 * Filter)
                 */
                compass_last_measured_bearing = current_measured_bearing;

            }
        }
    }
};

这篇关于我如何得到正确的方位(磁方位),无论屏幕方向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆