我正在为计算机科学的期末论文开发一个应用程序,我需要收集和记录加速度计数据。我需要使用一整天,因此电池存在严重限制(例如,我无法让屏幕保持打开状态)。此外,这不是一个针对市场的应用程序,因此如果需要的话,进行一些严重的黑客攻击,甚至是低级 C/C++ 编码是完全可以接受的。
众所周知,在许多设备上,当屏幕关闭时,加速度计事件的侦听器会停止生成事件(有关此问题的一些链接:http://code.google.com/p/android/issues/detail?id=3708 http://code.google.com/p/android/issues/detail?id=3708 , 当 Droid/Nexus One 屏幕关闭时,即使使用 WakeLock,加速计也会停止提供样本 https://stackoverflow.com/questions/2143102/accelerometer-stops-delivering-samples-when-the-screen-is-off-on-droid-nexus-one)。我彻底搜索了一些替代方案,其中一些包括不适用于我的设备(LG P990,库存 ROM)的解决方法。
那么发生的事情是这样的:
当您在服务中为 Android 加速计传感器注册事件侦听器时,它会正常工作,直到屏幕关闭。我已经尝试在服务上注册 eventListener,在 IntentService 上尝试获取 WakeLocks。关于唤醒锁,我可以通过观察 LOGcat 输出来验证服务是否仍在运行,但加速度计似乎已进入睡眠模式。某些链接中提供的解决方法之一是使用 IntentService 的线程定期取消注册并重新注册事件侦听器,如下面的代码片段所示
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,NAME);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
@Override
protected void onHandleIntent(Intent intent) {
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
synchronized (this) {
boolean run = true;
while (run){
try {
wait(1000);
getLock(AccelerometerService.this).acquire();
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
Log.d("Accelerometer service", "tick!");
} catch (Exception e) {
run = false;
Log.d("Accelerometer service", "interrupted; cause: " + e.getMessage());
}
}
}
}
@Override
public void onSensorChanged(SensorEvent event) {
Log.d("accelerometer event received", "xyz: "+ event.values[0] + "," + event.values[1] + "," + event.values[2]);
}
这确实使得每次我们注销/注册监听器时都会调用 onSensorChange 。问题是,无论我摇动设备,接收到的事件始终包含相同的值。
所以,基本上我的问题是:(请耐心等待,我即将完成:P)
是否可以在不注册事件侦听器的情况下对加速度计硬件进行低级访问(C/C++ 方法)?
还有其他解决方法或黑客吗?
任何拥有更新手机的人都可以测试一下固件3.0及以上版本中问题是否仍然存在吗?
[UPDATE]
不幸的是,这似乎是某些手机的一个错误。更多细节在我的回答中。