(пожалуйста, прочитайте ОБРАЗЕЦ 3 в конце). Я разрабатываю приложение, которое постоянно работает с датчиками устройства, работает с датчиками Accelerometer
и Magnetic
для извлечения ориентации устройства (указанная цель здесь). другими словами, моему приложению необходимо знать ориентацию устройства в режиме реального времени (однако это никогда не возможно, как можно быстрее, но действительно так быстро, как возможно!). как упоминалось в профессиональной разработке приложений Android 4 от Reto Meier:
Акселерометры могут обновлять сотни раз в секунду...
Я не должен потерять данные, которые сообщают датчики, и я также хочу выполнять трудоемкие операции над этими данными (получить ориентацию, а затем выполнить вычисления...). Я решил решить свою проблему, используя LinkedBlockingQueue
:
public void startSensors() {
LinkedBlockingQueue<float[][]> array=new LinkedBlockingQueue();
sensorListenerForOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
if (aValues != null && mValues != null) {
try {
array.put(new float[][] { aValues, mValues });
} catch (InterruptedException e) {
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
sm.registerListener(sensorListenerForOrientation, aSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(sensorListenerForOrientation, mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
executor.execute(new Runnable() {
@Override
public void run() {
doCalculations();
}
});
}
и
public void doCalculations() {
for (;;) {
float[][] result = null;
try {
result = array.take();
} catch (InterruptedException e) {
}
float[] aValues, mValues;
aValues = result[0];
mValues = result[1];
int[] degrees=getOrientation(aValues,mValues);
Log.e("",String.valueOf(degrees[0]));
//other calculations...
}
}
теперь я забираю свое устройство и поворачиваю его на 90 градусов вправо, а затем быстро возвращаю его в первую позицию (например, через 1,5 секунды), но когда я смотрю на ориентации, зарегистрированные на устройстве, я вижу, например: 0,1,2,3,4,5......., 40,39,38,37,...., 0
Я просто хочу сказать, что я не вижу большой области степеней в моем результате. основанный на том, что я сделал и что я исследовал , я просто могу быть уверен, что я не теряю никаких данных, записываются любые новые данные, сообщенные датчиками.
любая идея, решение?!
Привет!
ОБНОВЛЕНИЕ 1: Я сделал еще один эксперимент с моим устройством и получил потрясающие результаты! если я поворачиваю свое устройство по оси на 90 градусов быстро (менее секунды), я могу видеть все градусы в моем результате: 0,1,2,3,...., 89,90 (например), но если я поверните его на 90 градусов, а затем поверните обратно в первое положение, результат будет 0,1,2,..., 36,37,36,... 2,1,0 (например)... действительно путают!
ОБНОВЛЕНИЕ 2: Я обновил метод doCalculations(), чтобы более ясно, что я сделал
ОБНОВЛЕНИЕ 3: Я думаю, возможно, мы сможем решить проблему по-другому! У меня есть четкие цели для этого кода. посмотрите this. я упомянул, что произойдет, мне нужно определить конкретную движение жест. так что, возможно, весь путь, который я выбрал ( техника выше) не является хорошим способом решения этой проблемы. может быть лучше обнаружить этот жест с помощью других датчиков или использовать аналогичные датчики другим способом. что вы думаете?