我一直在努力使用getOrientation获取设备的实际方向。通过TYPE_ACCELEROMETER和TYPE_MAGNETIC_FIELD获取加速度计和磁场读数非常简单,通过TYPE_ORIENTATION获取方向也是如此。但是使用getOrientation根据世界坐标系获取方向。有许多好的教程here和here,但我还没有把它们放在一起。为此,我正在开发一个应用程序,它只是从getOrientation中吐出Accelerometer,Magnetic Field,原始Orientation数据和Orientation数据。我已经附加了代码,但它在我的手机上经常出现故障。有什么建议吗?
package com.sensorall;
import com.sensorall.R;
import android.hardware.*;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class OrientationAccelerometer extends Activity {
SensorManager sensorManager;
float[] mGravs = new float[3];
float[] mGeoMags = new float[3];
float[] mRotationM = new float[16];
float[] mInclinationM = new float[16];
float[] mOrientation = new float[3];
float[] mOldOreintation = new float[3];
String[] mAccelerometer = new String[3];
String[] mMagnetic = new String[3];
String[] mRotation = new String[16];
String[] mInclination = new String[16];
String[] mOrientationString = new String[3];
String[] mOldOreintationString = new String[3];
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.orientationaccelerometer);
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
} /* End onCreate activity */
private SensorEventListener sensorEventListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/* Get the Sensors */
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, mGravs, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, mGeoMags, 0, 3);
break;
case Sensor.TYPE_ORIENTATION:
System.arraycopy(event.values, 0, mOldOreintation, 0, 3);
break;
default:
return;
}
// If mGravs and mGeoMags have values then find rotation matrix
if (mGravs != null && mGeoMags != null) {
// checks that the rotation matrix is found
boolean success = SensorManager.getRotationMatrix(mRotationM, mInclinationM, mGravs, mGeoMags);
if (success) {
/* getOrientation Values */
SensorManager.getOrientation(mRotationM, mOrientation);
for(int i=0; i<2; i++){
mAccelerometer[i] = Float.toString(mGravs[i]);
mMagnetic[i] = Float.toString(mGeoMags[i]);
mOrientationString[i] = Float.toString(mOrientation[i]);
mOldOreintationString[i] = Float.toString(mOldOreintation[i]);
}
/* Make everything text to show on device */
TextView xaxisAccelerometerText = (TextView)findViewById(R.id.xaxisAccelerometer);
xaxisAccelerometerText.setText(mAccelerometer[0]);
TextView yaxisAccelerometerText = (TextView)findViewById(R.id.yaxisAccelerometer);
yaxisAccelerometerText.setText(mAccelerometer[1]);
TextView zaxisAccelerometerText = (TextView)findViewById(R.id.zaxisAccelerometer);
zaxisAccelerometerText.setText(mAccelerometer[2]);
TextView xaxisMagneticText = (TextView)findViewById(R.id.xaxisMagnetic);
xaxisMagneticText.setText(mMagnetic[0]);
TextView yaxisMagneticText = (TextView)findViewById(R.id.yaxisMagnetic);
yaxisMagneticText.setText(mMagnetic[1]);
TextView zaxisMagneticText = (TextView)findViewById(R.id.zaxisMagnetic);
zaxisMagneticText.setText(mMagnetic[2]);
TextView xaxisOrientationText = (TextView)findViewById(R.id.xaxisOrientation);
xaxisOrientationText.setText(mOrientationString[0]);
TextView yaxisOrientationText = (TextView)findViewById(R.id.yaxisOrientation);
yaxisOrientationText.setText(mOrientationString[1]);
TextView zaxisOrientationText = (TextView)findViewById(R.id.zaxisOrientation);
zaxisOrientationText.setText(mOrientationString[2]);
TextView xaxisOldOrientationText = (TextView)findViewById(R.id.xaxisOldOrientation);
xaxisOldOrientationText.setText(mOldOreintationString[0]);
TextView yaxisOldOrientationText = (TextView)findViewById(R.id.yaxisOldOrientation);
yaxisOldOrientationText.setText(mOldOreintationString[1]);
TextView zaxisOldOrientationText = (TextView)findViewById(R.id.zaxisOldOrientation);
zaxisOldOrientationText.setText(mOldOreintationString[2]);
}else{
/* Make everything text to show on device even if getRotationMatrix fails*/
String matrixFailed = "Rotation Matrix Failed";
TextView xaxisAccelerometerText = (TextView)findViewById(R.id.xaxisAccelerometer);
xaxisAccelerometerText.setText(mAccelerometer[0]);
TextView yaxisAccelerometerText = (TextView)findViewById(R.id.yaxisAccelerometer);
yaxisAccelerometerText.setText(mAccelerometer[1]);
TextView zaxisAccelerometerText = (TextView)findViewById(R.id.zaxisAccelerometer);
zaxisAccelerometerText.setText(mAccelerometer[2]);
TextView xaxisMagneticText = (TextView)findViewById(R.id.xaxisMagnetic);
xaxisMagneticText.setText(mMagnetic[0]);
TextView yaxisMagneticText = (TextView)findViewById(R.id.yaxisMagnetic);
yaxisMagneticText.setText(mMagnetic[1]);
TextView zaxisMagneticText = (TextView)findViewById(R.id.zaxisMagnetic);
zaxisMagneticText.setText(mMagnetic[2]);
TextView xaxisOrientationText = (TextView)findViewById(R.id.xaxisOrientation);
xaxisOrientationText.setText(matrixFailed);
TextView yaxisOrientationText = (TextView)findViewById(R.id.yaxisOrientation);
yaxisOrientationText.setText(matrixFailed);
TextView zaxisOrientationText = (TextView)findViewById(R.id.zaxisOrientation);
zaxisOrientationText.setText(matrixFailed);
TextView xaxisOldOrientationText = (TextView)findViewById(R.id.xaxisOldOrientation);
xaxisOldOrientationText.setText(mOldOreintationString[0]);
TextView yaxisOldOrientationText = (TextView)findViewById(R.id.yaxisOldOrientation);
yaxisOldOrientationText.setText(mOldOreintationString[1]);
TextView zaxisOldOrientationText = (TextView)findViewById(R.id.zaxisOldOrientation);
zaxisOldOrientationText.setText(mOldOreintationString[2]);
}
}
}
};
@Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(sensorEventListener);
}
}
答案 0 :(得分:3)
以下内容与我合作:
float[] r = new float[**16**];
对我
使用 nullfloat[] mOrientation = new float[4];
是 4 而非 3 。但是你只使用3。
SensorManager.getRotationMatrix(rotationMatrix, null, accelVals, magVals);
This code为我工作。
答案 1 :(得分:2)
这可能不适用于您的代码,但就使用getRotationMatrix()而言,它可能会解决其他问题。
我不确定这是否是我身上的版本问题,但我查看了getRotationMatrix()
方法的源代码,与文档中有关R[]
和{{的内容不同1}}参数, CAN NOT 为空。在声明我的I[]
和R
之后:
I
float[] r = new float[9];
方法操作正确。
float[] i = new float[9];
- &gt; SensorManager.getRotationMatrix(r,i,gravity,geomagnetic)
......奇怪的文档错误。
答案 2 :(得分:0)
在回答需要关闭力量的应用时,听起来像是你经常在UI线程上做太多。您正在接收来自3个不同传感器的数据,延迟为SENSOR_DELAY_NORMAL
。虽然这应该是大约5读数/秒,但我已经看到它每秒可以超过20个读数(因为传感器延迟只是建议的延迟)。因此,对于所有3个传感器,您每秒可以接收超过60个读数。对于每次阅读,您正在更新12 TextView
,因此您每秒可以执行超过720次UI更新。这也导致我的手机崩溃。尝试在UI更新之间设置最短时间:
long currentTime = System.currentTimeMillis();
if ((currentTime - lastUpdateTime) >= MIN_TIME_BETWEEN_UPDATES) {
// Update UI
lastUpdateTime = currentTime;
}
如果需要,您可以快速存储数据以供使用,但会降低UI更新速度。
答案 3 :(得分:-2)
事件的接收不遵循线性程序执行流程。 为避免出现问题,建议将与传感器事件接收相关的代码放在互斥模块中。
我的意思是:
public void onSensorChanged(SensorEvent event) {
synchronized (this) {
...
}
}
希望这有帮助。