我正在尝试开发一个适用于 Android 的应用程序,在该应用程序中,我从多个传感器(如果设备上可用)获取数据并将其写入文件,稍后将对其进行分析以用于某些用途。我面临着几个问题,一个我可以忽略的小问题和一个我无法解决并导致应用程序无法正常运行的主要问题。
- 小问题
我正在从以下位置收集数据:加速度计、线性加速度计、陀螺仪和磁力计以及 GPS,但它们的工作方式完全不同,并且只能以低得多的频率进行采样,所以我暂时忽略它。我通过为每个传感器实现一个监听器来收集数据:
public class AccelerometerWatcher implements SensorEventListener
{
private SensorManager sm;
private Sensor accelerometer;
AccelerometerWatcher(Context context) {
sm = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
assert sm != null;
if (sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
}
}
我使用以下方法将频率设置为~50Hz:
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
收集数据时,我知道频率不可能 100% 稳定,但奇怪的是它在每个传感器(大约 50Hz)上都或多或少地保持稳定,除了加速度计,大部分时间它以 100Hz 采样并且有时会下降到 50Hz。
有什么我可能做错了或有什么方法可以控制吗?到目前为止,我尝试过的每台设备都发生了这种情况,尽管它们的行为方式并不完全相同。
- 主要问题
我将信息写入文件,首先将我从传感器获取的所有内容写入字符串,然后每隔 X 秒,将字符串上的内容写入文件并清除它,以便传感器侦听器可以继续写入但它不会变得无限长。
我这样写在字符串上:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
if(initTime == -1)
initTime = event.timestamp;
MyConfig.SENSOR_ACCEL_READINGS += ((event.timestamp - initTime) / 1000000L) + MyConfig.DELIMITER + event.values[0] + MyConfig.DELIMITER + event.values[1] + MyConfig.DELIMITER + event.values[2] + "\n";
}
然后使用以下命令将其保存到文件中:
public class Utils {
private static Timer timer;
private static TimerTask timerTask;
public static void startRecording() {
timer = new Timer();
timerTask = new TimerTask()
{
@Override
public void run()
{
// THIS CODE RUNS EVERY x SECONDS
writeDataToFile();
}
};
timer.scheduleAtFixedRate(timerTask, 0, MyConfig.SAVE_TIMER_PERIOD);
}
public static void stopRecording()
{
if(timer != null)
timer.cancel();
if(timerTask != null)
timerTask.cancel();
writeDataToFile();
}
private static void writeDataToFile()
{
String temp_accel = String.copyValueOf(MyConfig.SENSOR_ACCEL_READINGS.toCharArray());
WriteData.write(MyConfig.RECORDING_FOLDER, MyConfig.FILENAME_ACCEL, temp_accel);
MyConfig.SENSOR_ACCEL_READINGS = MyConfig.SENSOR_ACCEL_READINGS.replaceFirst(temp_accel, "");
}
在监听器中,每次我停止监听时,我都会将“initTime”设置为 -1,因此样本总是从 0 开始,一直到监听周期的持续时间(以毫秒为单位)。(忽略 DELIMITER 只是格式问题)。
我的主要应用程序破坏问题如下:
在大多数手机中(一些幸运的手机可以完美运行)1 或 2 件事情都失败了。
在某些情况下,在闲置一段时间后(例如锁定并放在口袋里),传感器会停止记录数据,因此应用程序只会写入空白值,直到我再次唤醒手机。
在其他情况下,更糟糕的是,不仅传感器停止记录数据,而且计时器/写入文件似乎也停止工作,当手机再次唤醒时,它会尝试写入它应该写入的内容没有工作并且弄乱了所有的时间戳,在“过去”的不同点写入相同的样本,直到它赶上当前时间。(如果您将其可视化为图表,它基本上看起来好像数据收集回到了过去)。
有什么方法可以确保应用程序在任何情况下都能继续工作,无论手机是否被锁定、打瞌睡、应用程序是否最小化、在后台、前台等?
我尝试了一种我在谷歌上搜索的方法,该方法包括设置和警报以每隔 X 秒“唤醒进程”(无论我设置什么时间,它每分钟最多只能工作一次)。我看到每次警报响起的几毫秒内,它再次捕获样本但随后立即进入睡眠状态,它并没有让手机在更长的时间内保持“清醒”。它没有解决任何问题,即使在短时间内强制传感器收集数据,它也只能帮助唤醒传感器,定时器/写入文件的问题仍然存在。
希望有人能阐明如何让手机无论如何收集数据,我一直在尝试我能想到的一切,但我一无所获。对不起,文字砖,但我真的不知道如何用更短的方式解释它。
PS:我发现打开省电模式会让情况变得更糟,即使在通常可以正常工作的手机上,它也开始把事情搞砸了。所以另一个问题是......我怎样才能阻止它干扰?