之前做一个项目的时候需要获取手机在手机运动平面上(此平面与桌面可以任意角)的水平方向加速度ax,垂直方向加速度ay(ax,ay在运动平面上),手机与水平方向的倾角。
研究后发现,Sensor.TYPE_ACCELEROMETER获取的加速度实际上是手机运动的加速度与重力加速度的合加速度。
Sensor.TYPE_ORIENTATION获取的方向value[1]是手机坐标系y轴与桌面的夹角,value[2]是手机坐标系x轴与桌面的夹角。
具体推导见下图:
代码:
SenserListenerActivity.java:
package zhang.zhuoyueBei.Senser;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
public class SenserListenerActivity extends Activity implementsSensorListener {
SensorManager sm = null;
TextView acx = null;
TextView acy = null;
TextView o = null;
double ax =0;
double ay =0;
double oy =0;
double oz =0;
doubleaxp=0;
doubleayp=0;
doubleg=10;
doublegp=0;
doubletmp1=0,tmp2=0,tmp3=0,tmp4=0;
publicdouble getAccelerationX()
{
return axp;
}
publicdouble getAccelerationY()
{
return ayp;
}
publicdouble getOrientation()
{
return Math.asin(tmp4)/Math.PI*180.0;
}
@Override
public voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get reference to SensorManager
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
setContentView(R.layout.main);
acx = (TextView) findViewById(R.id.xbox);
acy = (TextView) findViewById(R.id.ybox);
o = (TextView) findViewById(R.id.obox);
}
public voidonSensorChanged(int sensor, float[] values) {
synchronized (this) {
if (sensor == SensorManager.SENSOR_ORIENTATION) {
oy=values[1];
oz=values[2];
}
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
ax=values[0];
ay=values[1];
}
tmp1=Math.sin(oz*Math.PI/180.0);
tmp2=Math.sin(Math.abs(oy)*Math.PI/180.0);
tmp3=Math.sqrt(tmp1*tmp1+tmp2*tmp2);
tmp4=tmp1/tmp3;
gp=10*tmp3;
axp=ax*Math.cos(tmp4)+ay*Math.sin(tmp4);
ayp=-ax*Math.sin(tmp4)+ay*Math.cos(tmp4)+gp;
acx.setText("a X: " + getAccelerationX());
acy.setText("a Y: " + getAccelerationY());
o.setText("Orientation : " + getOrientation());
}
}
public voidonAccuracyChanged(int sensor, int accuracy) {
}
@Override
protectedvoid onResume() {
super.onResume();
// register this class as a listener for the orientation andaccelerometer sensors
sm.registerListener(this,
SensorManager.SENSOR_ORIENTATION|SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protectedvoid onStop() {
// unregister listener
sm.unregisterListener(this);
super.onStop();
}
}
main.xml:
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Accelerometer"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="X Value"
android:id="@+id/xbox"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Y Value"
android:id="@+id/ybox"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Orientation"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="direction Value"
android:id="@+id/obox"
/>
</LinearLayout>