对于我正在制作的应用程序,我需要一个相机和一个指南针。应用程序在清单中设置为横向模式。
首先,我实现了指南针。正如 Android Developers 中所建议的,我使用了两个传感器——加速度计和磁场。这就是我的做法:
我有我的活动实施SensorEventListener
。在onCreate()
我初始化我的sensorManager
使用:
sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
我像这样注册我的听众onResume()
:
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
sManager.registerListener(this, sManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_NORMAL);
当然也可以在onPause()
. 我不使用onAccuracyChanged()
. 这就是我所做的onSensorChanged()
:
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD:
mags = event.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER:
accels = event.values.clone();
break;
}
if (mags != null && accels != null) {
gravity = new float[9];
magnetic = new float[9];
SensorManager.getRotationMatrix(gravity, magnetic, accels, mags);
float[] outGravity = new float[9];
float inclination = (float) Math.acos(gravity[8]);
if (inclination < Math.toRadians(25)
|| inclination > Math.toRadians(155)) {
// device is close to flat. Remap for landscape.
SensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_Y,SensorManager.AXIS_MINUS_X, outGravity);
SensorManager.getOrientation(outGravity, values);
} else {
// device is not flat. Remap for landscape and perpendicular
SensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_X,SensorManager.AXIS_Z, outGravity);
SensorManager.getOrientation(outGravity, values);
}
azimuth = Math.round(Math.toDegrees(values[0]));
}
}
如您所见,我区分了手机平放在桌子上的时间和用户拿着手机的时间(就像拍照时一样)。当我单独使用这段代码时,一切都或多或少地工作得很好。当手机放在桌子上和垂直于桌子握住时(大约 5-10 度的差异,但我可以忍受),我都得到了正确的方位角值。
将相机预览添加到应用程序时,问题就开始了。我有我的活动工具SurfaceHolder.Callback
。我初始化我的相机onCreate()
:
SurfaceView cameraView = (SurfaceView)findViewById(R.id.camera_view);
surfaceHolder = cameraView.getHolder();
surfaceHolder.addCallback(this);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
这就是我实现接口的方式:
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
camera = Camera.open();
camera.setDisplayOrientation(0);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
if (isCameraOn) {
camera.stopPreview();
isCameraOn = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
isCameraOn = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
camera.stopPreview();
camera.release();
camera = null;
}
当我将相机代码添加到我的项目中并在手机屏幕上显示相机时,当手机突然垂直时,我的传感器无法正常工作。如果手机平放在桌子上,我得到的方位角值是正确的。当手机与桌子垂直时,我的方位角值偏离了大约 40 度(虽然稳定)。
我已经尝试寻找解决方案(我自己和在线),但到目前为止我的努力都是徒劳的。我很想就如何解决这个问题获得一些指导。
谢谢!