Reputation: 5576
I want to detect if the device is facing up. (Not angled but flat to the ground facing up).
On some devices for facing up, z value will return values between 9~10. (Most devices)
However, on Nexus 7, for facing up, z value will return values between 6~8.
My code was:
if(z_value > 9.0) {
// device facing up
}
else {
// device is in angled
}
However, above code doesn't work anymore. Since Nexus7 doesn't reach z_value of 9.
How can I detect if the device is facing (entirely) up or not. (not asking z_value > 0)
My full code is below:
@Override
protected void onStart() {
super.onStart();
try {
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if(sensorList.size() > 0){
accelerometerPresent = true;
accelerometerSensor = sensorList.get(0);
}
else{
accelerometerPresent = false;
}
if(accelerometerPresent){
sensorManager.registerListener(accelerometerListener, accelerometerSensor, SensorManager.SENSOR_DELAY_UI);
}
} catch(Exception e) {}
}
private SensorEventListener accelerometerListener = new SensorEventListener(){
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {}
@Override
public void onSensorChanged(SensorEvent arg0) {
float z_value = arg0.values[2];
Log.d("test", "z:" + z_value);
}};
Note #1
arg0.sensor.getMaximumRange() returns 19.6133 for Nexus 7. Which sensor never returns.
Note #2
If you shake the devices, z_value tends to go little higher (sometimes 8~8.5).
If you steadily tilt the device, z_value doesn't reach 8 (max).
Upvotes: 3
Views: 2830
Reputation: 58501
Apparently the device is poorly calibrated. A well-calibrated device should return 9.81m/s^2, the gravitational acceleration.
What you could do instead: Compare the z value to the x and y values. If the z value dominates than the device is facing up. For example:
if (z/sqrt(x^2+y^2+z^2+1.0e-6) > 0.9) { // Facing up
I added the term 1.0e-6
so that you won't accidentally divide by zero.
This heuristic requires testing and tweaking but I guess you get the idea. Good luck!
Upvotes: 2
Reputation: 523
The general idea about this kind of sensors is to avoid them or to not abuse them in a way that your application relies on a really precise measure.
The problem with this sensors is basically that they have really different range of values and they are really noisy, so they need to be normalized by you, the coder, and they can't be so reliable in terms of accuracy.
I forgot the exact name of this public speech, but even Google and the Android team suggest to not rely so much on this in terms of decimals or to not expect great accuracy; also remember that every little part of this smartphones and tablets is really really cheap, we are talking about sensors that usually do not cost more than 1$.
Try to code in a way that your code only requires the general direction or axis, if you want a value be sure that it's an integer and always do rough calc and do not expect precision or decimals.
Also remember that Android doesn't offers a normalized approach to this values, so you have to deal with that in your code.
Upvotes: -1