众所周知,在许多设备上,当屏幕关闭时,加速度计事件的监听器停止生成事件(关于这个问题的一些链接:http://code.google.com/p/android/issues/detail?id=3708 ,即使使用WakeLock,Droid/Nexus One上的屏幕关闭后加速度计仍将停止传递样本)。我已经彻底搜索了一些替代方案,其中一些包括解决方法,但对我的设备(LG P990,原生ROM)不起作用。
所以问题来了: 当在Service中为Android加速度计传感器注册事件监听器时,它正常工作,直到屏幕关闭。我已经尝试在Service、IntentService上注册eventListener,并尝试获得WakeLocks。关于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及以上版本中问题是否仍然存在?
[更新]
不幸的是,这似乎是一些手机的错误。更多详细信息请参见我的答案。