コンパスを実装して、読み取り値を取得していますSensorManager.getRotationMatrix
(以下のコードを参照)。
をimageView
使用して回転するがありRotateAnimation
ます。コンパスとアニメーションは、1 つの問題を除いて正常に動作します。
を通じて、SensorManager.getOrientation
方位角、ピッチ、ロールの 3 つの値の配列を取得します。array[0]
方位角値を保持するのみを使用します
電話を平らに持ち、Z 軸 (方位角) で回転させると、完全に機能します。しかし、携帯電話を X 軸または Y 軸 (ピッチまたはロール) に傾けると、コンパスは正しい測定値から外れます。言い換えれば、ピッチまたはロールを傾けると、方位角からの読み取りに深刻な影響を与えます。
それで、私の質問を要約すると、どうすればピッチ/ロールの読み取り値からの干渉をブロックできますか (コードではまったく対処していませんが) - または、何か間違ったことをしていますか?
前もって感謝します!
ここに私のコードのほとんどがあります:
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor accelerometer;
private Sensor magnetometer;
private float[] mGravity;
private float[] mGeomagnetic;
float avgRead[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
private TextView tvCurrAzim;
private ImageView ivCompass;
private float currentDegree = 0f;
private float azimuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
tvCurrAzim = (TextView) findViewById(R.id.tvaz);
ivCompass = (ImageView) findViewById(R.id.imageView1);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
// Compass Sensor Methods:
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
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 I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
//Creating a running smooth average of readings
avgRead[0] = avgRead[1];
avgRead[1] = avgRead[2];
avgRead[2] = avgRead[3];
avgRead[3] = avgRead[4];
avgRead[4] = avgRead[5];
avgRead[5] = avgRead[6];
avgRead[6] = avgRead[7];
avgRead[7] = avgRead[8];
avgRead[8] = orientation[0]; // orientation contains: azimuth, pitch and roll
azimuth = (avgRead[0] + avgRead[1] + avgRead[2] + avgRead[3]
+ avgRead[4] + avgRead[5] + avgRead[6] + avgRead[7] + avgRead[8]) / 9;
azimuth = Math.round(azimuth * 360 / (2 * 3.14159f));
if (azimuth < 0 && azimuth > -180)
azimuth += 360;
}
}
tvCurrAzim.setText(Float.toString(azimuth));
// get the angle around the z-axis rotated
// create a rotation animation (reverse turn degree degrees)
if (-azimuth - currentDegree > 180)
azimuth = azimuth - 360;
RotateAnimation ra = new RotateAnimation(currentDegree, -azimuth,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
// how long the animation will take place
ra.setDuration(50);
// set the animation after the end of the reservation status
ra.setFillAfter(true);
// Start the animation
ivCompass.startAnimation(ra);
currentDegree = -azimuth;
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer,
SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer,
SensorManager.SENSOR_DELAY_UI);
}
}