检测安卓设备方向(不是屏幕方向)

7

有没有办法检测Android设备的当前方向?

我不是在谈论屏幕方向,而是指设备实际上被持有的方式。到目前为止,我找到的所有解决方案都告诉我屏幕方向(在我的应用中始终是纵向)。我需要知道用户是否水平持有设备,即使我没有旋转屏幕。

谢谢。


http://developer.android.com/guide/topics/sensors/sensors_overview.html - CommonsWare
3个回答

7
您可以使用加速度计。要使用它,您需要在传感器TYPE_ACCELEROMETER 上注册一个监听器。
一旦完成,当该传感器的值发生变化时(当用户手持设备时非常频繁),您将收到通知。
从此传感器接收到的值是表示重力的向量在X,Y和Z轴上的投影(好吧...这并不完全正确:事实上这些值表示应用于设备的所有力的总和的投影)。所以:
  • X轴上的正值(SensorEvent.values [0]):表示设备的右侧边缘在左侧边缘下面。
  • Y轴上的正值(SensorEvent.values [1] ):表示顶部边缘在底部边缘下面。
  • Z轴上的正值(SensorEvent.values [2] ):表示设备的前面朝向地面,因此必须颠倒前面的两个规则。
以下是示例代码(警告:它不关心Z轴上的值)。
/**
 *  Logs the device orientation. Results are not valid when the screen is facing the ground.
 *  (when the discriminant value is low (i.e. device almost horizontal) : no logs)
 */
public void onSensorChanged(SensorEvent event) {
    if (event.sensor == mAccelerometer) {
        if(Math.abs(event.values[1]) > Math.abs(event.values[0])) {
            //Mainly portrait
            if (event.values[1] > 1) {
                Log.d(TAG,"Portrait");
            } else if (event.values[1] < -1) {
                Log.d(TAG,"Inverse portrait");
            }
        }else{
            //Mainly landscape
            if (event.values[0] > 1) {
                Log.d(TAG,"Landscape - right side up");
            } else if (event.values[0] < -1) {
                Log.d(TAG,"Landscape - left side up");
            }
        }
    }
}

1

在2.2版本之前,您可以使用方向传感器来实现此功能-这只是加速度计和磁力计的花式混搭,然后在2.2版本之后被弃用。现在,您可以自己编写该类的代码。

来源:https://dev59.com/qGkv5IYBdhLWcg3w3Uk0#10291428
public class OrientationTestActivity extends Activity implements SensorEventListener
{
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;

    private float[] mLastAccelerometer = new float[3];
    private float[] mLastMagnetometer = new float[3];
    private boolean mLastAccelerometerSet = false;
    private boolean mLastMagnetometerSet = false;

    private float[] mR = new float[9];
    private float[] mOrientation = new float[3];

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    protected void onResume() {
        super.onResume();
        mLastAccelerometerSet = false;
        mLastMagnetometerSet = false;
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

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

    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if (mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
            SensorManager.getOrientation(mR, mOrientation);
            Log.i("OrientationTestActivity", String.format("Orientation: %f, %f, %f",
                                                           mOrientation[0], mOrientation[1], mOrientation[2]));
        }
    }
}

磁力计在这里并非严格必需,此外它也并不总是可用的(至少我曾经使用过没有磁力计的设备)。 - ben75
谢谢,我今天稍后会尝试一下。 - Flarosa


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接