Получение данных датчика в течение x секунд после нажатия кнопки

Я все еще изучаю Android-разработку, поэтому извините, если этот вопрос кажется глупым, но я пытаюсь получить данные акселерометра с телефона только в течение ограниченного времени. Цель состоит в том, чтобы значения координаты x от датчика записывались только в течение примерно 3 секунд после нажатия кнопки.

public class AccelerometerTestingActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    float x_event[];
    @Override
    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
        // add listener. The listener will be HelloAndroid (this) class
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_GAME);

    }

    public void onAccuracyChanged(Sensor sensor,int accuracy){

    }

    public void onSensorChanged(SensorEvent event){

        // check sensor type
        if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){

            // assign directions
            float x=event.values[0];
            x_event=addArrayElement(x_event,x);
        }
    }

    private float[] addArrayElement(float[] currentArray, float x) {
        // TODO Auto-generated method stub
        float newArray[] = new float[currentArray.length+1];
        int i= 0;

        for(i=0;i<currentArray.length;i++)
        {
            newArray[i] = currentArray[i];
        }

        newArray[i+1]=x;

        return newArray;
    }

Таким образом, x_event — это массив, который периодически заполняется положением X акселерометра каждую SENSOR_DELAY_GAME.

Дело в том, что этот код записывает все значения во время выполнения активности.

Я хотел бы, чтобы этот массив заполнялся только с момента нажатия кнопки и заполнялся только в течение x секунд (еще не определился со значением x). После этого массив будет передан другой функции для анализа.

Я просто не понимаю, как ограничить Listener во времени.

Спасибо за помощь.


person Robin Eisenberg    schedule 14.12.2011    source источник


Ответы (3)


Вот быстрое решение; в вашем onCreate() после того, как вы зарегистрировали своего слушателя, вы можете сделать это:

    final SensorEventListener listener = this;
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            sensorManager.unregisterListener(listener);
        }
    }, theTimeInMilliseconds);

Вам также следует рассмотреть возможность использования списка, а не массива, для сохранения ваших значений, поэтому вам не нужно воссоздавать его каждый раз, когда вы получаете новое значение:

ArrayList<Float> xEvent = new ArrayList<Float>();

И чтобы добавить элементы:

xEvent.add(event.values[0]);
person Jave    schedule 14.12.2011
comment
Спасибо, очень полезно, работает отлично. Я изменил свое приложение, чтобы использовать списки, это намного проще, спасибо. - person Robin Eisenberg; 14.12.2011
comment
Для SensorManager.unregisterListener(слушатель); , с моим кодом, как я могу получить ссылку на фактического слушателя? Его нельзя создать отдельно, а затем зарегистрировать/не зарегистрировать, не так ли? - person Robin Eisenberg; 14.12.2011
comment
Я обновил свое решение, чтобы оно лучше работало с вашим кодом :) Обычно у меня есть настраиваемый сенсорный прослушиватель отдельно от действия и ссылка на переменную, но в этом случае вы можете получить ссылку с помощью «этого». («это» не будет работать внутри runnable, так как в этом случае это будет ссылка на runnable, а не на действие) - person Jave; 14.12.2011

Рассматривали ли вы использование таймера, который после 3-секундной задержки - отменит регистрацию слушателя - вызовет вашу функцию анализа?

person Ramseys    schedule 14.12.2011
comment
Нет, не пробовал. Отменить регистрацию слушателя, это то, что мне было нужно. Спасибо, это должно сделать это. Я попробую, вернусь, чтобы проверить, работает ли это. Большое спасибо - person Robin Eisenberg; 14.12.2011

Решил проблему

Просто используйте метод класса Timer, делайте это каждые 1 с.

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

                                     // Just calculate your accleration here

                              }
                                                 }, 0, 1000);

Лучшее решение, я думаю

person Anas Aijaz    schedule 16.07.2017