Android传感器数据丢失

时间:2013-02-06 23:09:54

标签: android sensor

我正在我的Android应用中收集数据,如下所示(这是一个精简版):

public class Main extends Activity {

    ...

    public void log5secs(){
        try {
            CollectData collectData = new CollectData(this);
            // collect data for five seconds in the background
            Thread.sleep(5000);
            Log.d("unregister", "gyro from Main: "+collectData.gyroscopeResults.size());
            fingerprint.finish();
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }        

}

public class CollectData implements SensorEventListener  {

    ArrayList<SensorEvent> gyroscopeResults = new ArrayList<SensorEvent>();

    public CollectData(Context context){
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void onSensorChanged(SensorEvent event) {
        gyroscopeResults.add(event); 
        Log.d("SensorChanged", "gyro results size: "+gyroscopeResults.size());
    }

    public void finish(){
        unregister();
    }

    private void unregister() {
        Log.d("Unregister", "gyro results size before unregister: "+gyroscopeResults.size());
        sensorManager.unregisterListener(this);
    }
}

因此,日志消息显示每次调用onSensorChanged事件时,ArrayList的大小都会增加(在五秒内变为26)。

但是,当从Main请求大小或由于调用unregister()时,ArrayList的大小为零。在调试器中,我无法看到它在哪里发生变化。

我的数据发生了什么???

我在HTC Sensation XL上运行它。

更新:了解更多信息!出于好奇,我将ArrayList gyroscopeResults作为Main类中的静态字段。效果很有意思 - 记录完成的第二次,第一次的结果是可见的(但不是第一次)。我猜这意味着主要线程在传感器数据被记录之前完成 - 某种缓冲问题???

1 个答案:

答案 0 :(得分:2)

您的数据不会丢失,Thread.sleep()中的问题会暂停程序5秒钟(包括传感器收集),然后在此启动后执行fingerprint.finish(); 行传感器系列。

因此,当您致电Log.d("Unregister", "gyro results size before unregister: "+gyroscopeResults.size());时,您会收到0,因为在程序正在睡眠时没有记录传感器数据。

以下是一些使您的程序按预期运行的建议

要收集 5秒的数据,您可以使用Timer(此处我在5秒后取消定时器,但您可以在清除{{1}后继续收集不要耗尽内存)

ArrayList

另一种解决方案可能更简单,如果您想让final Timer timer = new Timer(); final CollectData collectData = new CollectData(MainActivity.this); timer.schedule(new TimerTask() { boolean started = false; @Override public void run() { if (!started) { Log.d("unregister", "BEFORE] gyro from Main: " + collectData.gyroscopeResults.size()); started = true; } else { collectData.finish(); Log.d("unregister", "AFTER] gyro from Main: " + collectData.gyroscopeResults.size()); timer.cancel(); } } }, 0, 5000); Thread.sleep()

内运行log5secs()
Thread

然而,如果您想要连续的传感器记录,使用new Thread() { public void run() { log5secs(); } }.start(); 将更合适,您每隔5秒就会使用数据 (例如,记录到文件和/或清除{{1} })