[英]Android could not get Sensor Type Sensor.TYPE_MAGNETIC_FIELD on some devices
I have this app in which the screen orientation is fixed on portrait and instead of doing a full screen rotation, and having to re-build the activity, I have decided to use the accelerometer instead. 我有一个此应用,其中屏幕方向固定为纵向,而不是进行全屏旋转,并且不得不重新构建活动,因此我决定使用加速度计。
The following code works fine on all the devices I test until I came across this one device (One+ running 6.0), in which I was unable to get the geomagnetic field in order to calculate the orientation. 下列代码在我测试的所有设备上都可以正常工作,直到碰到这台设备(运行6.0的One +)为止,在该设备中,我无法获取地磁场来计算方向。
Is this a problem from the hardware? 这是硬件问题吗? am I missing some permissions?
我缺少一些权限吗? I have looked into it and I didn't find any documentation saying I need to ask for permissions during runtime for an accelerometer.
我已经研究过了,但没有找到任何文档说明我需要在运行时为加速度计请求权限。
Here is the code of the onSensor: 这是onSensor的代码:
public void onSensorChanged(SensorEvent event) {
boolean isOrientationEnabled;
try {
isOrientationEnabled = Settings.System.getInt(getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION) == 1;
} catch (Settings.SettingNotFoundException e) {
isOrientationEnabled = false;
}
if (!isOrientationEnabled){
if(this.Orientation!= ORIENTATION_PORTRAIT)rotateViews(ORIENTATION_PORTRAIT);
this.Orientation = ORIENTATION_PORTRAIT;
return;
}
if(allow_rotation) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
//mGeomagnetic is null
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);
// orientation contains: azimut, pitch and roll
float pitch = (float) Math.toDegrees(orientation[1]);
if (pitch < -45 && pitch > -135) {
// if device is laid flat on a surface
if(this.Orientation!= ORIENTATION_PORTRAIT) rotateViews(ORIENTATION_PORTRAIT);
this.Orientation = ORIENTATION_PORTRAIT;
return;
}
float roll = (float) Math.abs(Math.toDegrees(orientation[2]));
if ((roll > 60 && roll < 135)) {
// The device is closer to landscape orientation. Enable fullscreen
int landscape_mode;//0 = right, 2 = left
if (Math.toDegrees(orientation[2]) > 0) landscape_mode = ORIENTATION_LANDSCAPE_RIGHT;
else landscape_mode = ORIENTATION_LANDSCAPE_LEFT;
if(this.Orientation!=landscape_mode) rotateViews(landscape_mode);
this.Orientation = landscape_mode;
} else if (roll < 45 && roll > 135) {
// The device is closer to portrait orientation. Disable fullscreen
if(this.Orientation!=1)rotateViews(ORIENTATION_PORTRAIT);
this.Orientation = ORIENTATION_PORTRAIT;
}
}
}
}
}
You do not need Magnetic sensor
for pitch
and roll
. 您不需要
Magnetic sensor
进行pitch
和roll
。 Just low pass filter accelerometer
to get gravity. 只需低通滤波器
accelerometer
即可获得重力。
private static final float ALPHA = 0.8;
private float[] mGravity;
public void onSensorChanged(SensorEvent event) {
mGravity[0] = ALPHA * mGravity[0] + (1 - ALPHA) * event.values[0];
mGravity[1] = ALPHA * mGravity[1] + (1 - ALPHA) * event.values[1];
mGravity[2] = ALPHA * mGravity[2] + (1 - ALPHA) * event.values[2];
double gravityNorm = Math.sqrt(mGravity[0] * mGravity[0] + mGravity[1] * mGravity[1] + mGravity[2] * mGravity[2]);
pitch = (float) Math.asin(-mGravity[1] / gravityNorm);
roll = (float) Math.atan2(-mGravity[0] / gravityNorm, mGravity[2] / gravityNorm);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.