No hay nada más que hacer que estar de acuerdo con los argumentos razonables presentados en todas las grandes respuestas anteriores, sin embargo, si eres del tipo pragmático como yo, necesito encontrar una solución que funcione de alguna manera.
Sufrí un problema similar al suyo y decidí hacer mi propia solución después de no encontrar ningún en línea. Solo necesitaba una entrada de "inclinación" simple para controlar un juego, por lo que esta solución probablemente NO funcionará para necesidades más complejas, sin embargo, decidí compartirla en caso de que otros buscaran algo similar.
NOTA: I have pasted my entire code here, y es gratis para cualquier uso.
Básicamente lo que hago en mi código es buscar el sensor del acelerómetro. Si no se encuentra, la retroalimentación de inclinación se desactivará. Si el sensor acelerómetro está presente, busco el sensor de campo magnético, y si está presente, obtengo mi ángulo de inclinación de la manera recomendada combinando datos de acelerómetro y campo magnético.
public TiltSensor(Context c) {
man = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE);
mag_sensor = man.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
acc_sensor = man.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
has_mag = man.registerListener(this, mag_sensor, delay);
has_acc = man.registerListener(this, acc_sensor, delay);
if (has_acc) {
tiltAvailble = true;
if (has_mag) {
Log.d("TiltCalc", "Using accelerometer + compass.");
}
else {
Log.d("TiltCalc", "Using only accelerometer.");
}
}
else {
tiltAvailble = false;
Log.d("TiltCalc", "No acceptable hardware found, tilt not available.");
//No use in having listeners registered
pause();
}
}
Si sin embargo, sólo el sensor de acelerómetro estaba presente, I caer de nuevo a la acumulación de la aceleración, que se amortigua de forma continua (multiplicado por 0,99) para eliminar cualquier deriva. Para mis necesidades de inclinación simple, esto funciona muy bien.
@Override
public void onSensorChanged(SensorEvent e) {
final float[] vals = e.values;
final int type = e.sensor.getType();
switch (type) {
case (Sensor.TYPE_ACCELEROMETER): {
needsRecalc = true;
if (!has_mag) {
System.arraycopy(accelerometer, 0, old_acc, 0, 3);
}
System.arraycopy(vals, 0, accelerometer, 0, 3);
if (!has_mag) {
for (int i = 0; i < 3; i++) {
//Accumulate changes
final float sensitivity = 0.08f;
dampened_acc[i] += (accelerometer[i] - old_acc[i]) * sensitivity;
//Even out drift over time
dampened_acc[i] *= 0.99;
}
}
}
break;
case (Sensor.TYPE_MAGNETIC_FIELD): {
needsRecalc = true;
System.arraycopy(vals, 0, magnetic_field, 0, 3);
}
break;
}
}
En conclusión Me limitaré a repetir que esto probablemente no es "correcta" de ninguna manera, sino que simplemente funciona como una entrada simple de un juego. Para usar este código simplemente hago algo como lo siguiente (sí las constantes mágicas son malas mkay):
Ship ship = mShipLayer.getShip();
mTiltSensor.getTilt(vals);
float deltaY = -vals[1] * 2;//1 is the index of the axis we are after
float offset = ((deltaY - (deltaY/1.5f)));
if (null != ship) {
ship.setOffset(offset);
}
Enjoi!
@Ignacio ¿Qué? La aceleración constante significa que la velocidad aumenta linealmente. – Imran
¿Tiene alguna solución de trabajo? ¿Puede indicarme eso o compartir el código? – VenomVendor
Hola, ¿alguna vez pensó en cerrar esta pregunta? –