我正在学习的Android编程的基础知识。
我在我的加速计,磁力计和方位数据记录到外部文件,同时还显示它简单的Android测试应用程序。 我通过调用一个方法initLogger发起一个启动按钮(registerListener的相关传感器)的点击记录过程。
这类似于这样的东西?
public void initLogger(View view)
{
boolean bFlag = false;
Button btnStart = (Button)findViewById(R.id.btnStartLog);
Button btnStop = (Button)findViewById(R.id.btnStopLog);
btnStart.setEnabled(bFlag);
btnStop.setEnabled(!bFlag);
bEnableLogging = true;
//Start reading the sensor values
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
//so on....
还有一个停止按钮,其中应停止记录进程(和最后通过调用unregisterListener每个传感器注销)
数据检索过程发生在onSensorChanged处理机其中应检索来自相关传感器的数据内,将值设置为相应的UI元素和最后的数据记录到外部.csv文件。
onSensorChanged事件处理程序看起来是这样的...
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
// accelerometer
TextView tAX = (TextView) findViewById(R.id.txtViewAxValue);
TextView tAY = (TextView) findViewById(R.id.txtViewAyValue);
TextView tAZ = (TextView) findViewById(R.id.txtViewAzValue);
// magnetic field
TextView tMX = (TextView) findViewById(R.id.txtViewMx);
TextView tMY = (TextView) findViewById(R.id.txtViewMy);
TextView tMZ = (TextView) findViewById(R.id.txtViewMz);
if (bEnableLogging) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
accelerometerdata = event.values.clone();
tAX.setText(Double.toString(accelerometerdata[0]));
tAY.setText(Double.toString(accelerometerdata[1]));
tAZ.setText(Double.toString(accelerometerdata[2]));
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticmatrixdata = event.values.clone();
tMX.setText(Double.toString(magneticmatrixdata[0]));
tMY.setText(Double.toString(magneticmatrixdata[1]));
tMZ.setText(Double.toString(magneticmatrixdata[2]));
}
// so on ....
虽然我接收来自所有配置的传感器的数据,我没有超过在其上接收所述数据的速率控制。 即
我知道SensorChanged事件被触发为当传感器数据被改变。 不过,我想在一个固定的速度来触发此事件。 对于例如:每40ms
题:
- 如何保证SensorChanged事件以恒定速率解雇?
- 是Java类的TimerTask在这种情况下,任何帮助吗?
专家在这里在SO.Please帮我:)
既然你知道,如果没有SensorChanged触发的事件,也没有改变,你可以用你的旧值。 至于你问在特定的时间间隔的日志数据,我不会做的onSensorChanged方法的任何输出只是复制新的数据到你accelerometerdata变量。 而不是登录accelerometerdata每40ms的价值。 这样,你正在登录的实际价值,甚至每40ms,如果数据没有改变....
注:根据Ridcullys答案也似乎是可能获得传感器数据在特定的时间间隔“交付”。 但由于没有对这些“交付”一如既往与Android设备上的传感器数据的延迟,我的解决方案,你会更准确地在40毫秒的时间间隔。 在另一方面,它可能发生,如果在当下的传感器数据更改登录,它可能发生,你耽误了新的数据对一个区间。 我猜(这点不知道) - 因为它的只是记录和不是像某事“得到它尽可能快地实时”,所以这不是一个要求 - 定时器的解决方案,使更少的CPU负载。
可以通过改变用于传感器注册时的延迟改变的时间间隔。
int SENSOR_DELAY_FASTEST get sensor data as fast as possible
int SENSOR_DELAY_GAME rate suitable for games
int SENSOR_DELAY_NORMAL rate (default) suitable for screen orientation changes
int SENSOR_DELAY_UI rate suitable for the user interface
根据这个 ,最快的延迟,你需要什么,如果不改变速度不够快,你是因为没有改变。 没有getSensorData方法。
您可以指定其他数据的延迟,如SENSOR_DELAY_GAME(20,000微秒延迟),SENSOR_DELAY_UI(60,000微秒延迟),或SENSOR_DELAY_FASTEST(0微秒的延迟)。 由于Android 3.0(API等级11),你还可以指定延迟的绝对值(微秒)。
您指定的延迟仅仅是一个建议的延迟。 Android系统和其他应用程序可以改变这种延迟。 作为最佳做法,应指定,你可以因为系统通常使用超过您指定的一个较小的延迟(即,您应该选择仍满足您的应用需求最慢的采样率)最大的延迟。 使用较大的延迟施加所述处理器上的负载较低,因此使用较少的功率。
当您注册使用监听器SensorManager
使用registerListener ,而不是固定的常数, SENSOR_DELAY_...
你可以通过在如JavaDoc中所述微秒的时间间隔 :
速率传感器事件在被传递的速率。 这只是一个提示系统。 事件可以接收比指定的速率更快或更慢。 通常的事件接收更快。 该值必须是SENSOR_DELAY_NORMAL,SENSOR_DELAY_UI,SENSOR_DELAY_GAME,或SENSOR_DELAY_FASTEST或,在微秒事件之间的期望延迟中的一个。
所以,仅仅通过40000以符合您的要求范例,也为说,这只是一个提示,所以我不会依赖于区间得到确切值到微秒。
我一直在试图找出我怎么能有传感器很长的延迟,到目前为止,我已经成功了。 对延迟时间可以用微秒来指定developer.android会谈的文档,下面是一个大数目我想:
// Initialize in onCreate
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE)
mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
// Register the listener, and play around with delay
mSensorManager.registerListener(this, mLight, 200000000);
但是请注意下面的logcat转储 - 在onSensorChanged() - 被调用多达4次,第二...我想弄清楚越来越大延迟,但没有成功为止!
6月1日至14日:58:07.088:d / IOE传感器(20933):onSensorChanged调用,事件是:android.hardware.SensorEvent@42849f70 6月1日至14日:58:07.268:d / IOE传感器(20933):onSensorChanged称为中,事件是:android.hardware.SensorEvent@42849f70 01-14 06:58:07.448:d / IOE传感器(20933):onSensorChanged调用,事件是:android.hardware.SensorEvent@42849f70 01-14 6点58分: 07.628:d / IOE传感器(20933):onSensorChanged调用,事件是:android.hardware.SensorEvent@42849f70六月一日至14日:58:07.808:d / IOE传感器(20933):onSensorChanged调用,事件是:机器人。 hardware.SensorEvent@42849f70 6月1日至14日:58:07.989:d / IOE传感器(20933):onSensorChanged调用,事件是:android.hardware.SensorEvent@42849f70 6月1日至14日:58:08.169:d / IOE传感器( 20933):onSensorChanged叫,事件是:android.hardware.SensorEvent@42849f70
看来,在这onSensorChanged被称为率已经是4个建议值之一。
你能为“慢读”做的是使用SENSOR_DELAY_UI和(在onSensorChanged)衡量,因为你读的sensordata最后一次经过的时间:
long lastUpdate = System.currentTimeMillis();
// In onSensorChanged:
long curTime = System.currentTimeMillis();
if ((curTime - lastUpdate) > 500){ // only reads data twice per second
lastUpdate = curTime;
// do stuff
}
唯一的缺点我在这里看到的是,if语句将与假的结果多次被调用。