У меня есть некоторый код, который расширяет сервис и записывает onSensorChanged (событие SensorEvent) чтения датчика акселерометра на Android. Я хотел бы смочь записать эти чтения датчика, даже когда устройство выключено (я осторожен с ресурсом аккумулятора, и оно делало ясным, когда оно работает). В то время как экран находится на входе, хорошо работает на 2.0.1 Motorola Droid и 2,1 Nexus One.
Однако, когда телефон засыпает (путем продвижения кнопки питания), экран выключает и onSensorChanged
события прекращают поставляться (проверенный при помощи сообщения Log.e каждый времена N onSensorChanged
назван).
Сервис получает wakeLock, чтобы гарантировать, что он продолжает бежать в фоновом режиме; но, это, кажется, не имеет эффекта. Я попробовал все различные блокировки следа PowerManager., но ни один из них, кажется, не имеет значения.
_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
_WakeLock.acquire();
Были противоречивые сведения о том, можно ли на самом деле получить данные из датчиков, в то время как экран от... у кого-либо есть опыт с этим на более современной версии Android (Эклер) и аппаратные средства?
Это, кажется, указывает, что работало в Капкейке: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5
PS: Тот же самый код работает, как предназначено в 1,5 на G1. Вход продолжается, когда экран выключает, когда приложение в фоновом режиме и т.д.
Мы вычислили, что это началось с 2.0.1. Похоже, что это было преднамеренное, возможно, частичное увеличение срока службы батареи, которое было расценено как особенность. У нас была рабочая встряска для пробуждения или разблокировки на 2.0, затем она сломалась при обновлении, и мы не смогли получить никаких обходных путей. ;''( Не имеет значения, удерживается ли частичная блокировка процессора, которая должна всегда препятствовать спящему процессору. Из того, что я видел в логах отладки через USB, время от времени появляется упоминание об изменении сенсорного прослушивателя, когда происходит сон.
Пользователь опубликовал обходной путь, который, как он утверждал, работает на устройствах Motorola - https://sites.google.com/a/bug-br.org.br/android/technical-documents
Я протестировал обходной путь, придумав следующий код из руководства и некоторые ручные версии (есть несколько "багов" в его руководстве представлен код):
public class ShakeWakeupService extends Service implements SensorEventListener{
private Context mContext;
SensorManager mSensorEventManager;
Sensor mSensor;
// BroadcastReceiver for handling ACTION_SCREEN_OFF.
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Check action just to be on the safe side.
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.v("shake mediator screen off","trying re-registration");
// Unregisters the listener and registers it again.
mSensorEventManager.unregisterListener(ShakeWakeupService.this);
mSensorEventManager.registerListener(ShakeWakeupService.this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
};
@Override
public void onCreate() {
super.onCreate();
Log.v("shake service startup","registering for shake");
mContext = getApplicationContext();
// Obtain a reference to system-wide sensor event manager.
mSensorEventManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
// Get the default sensor for accel
mSensor = mSensorEventManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// Register for events.
mSensorEventManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
// Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver
// code be called whenever the phone enters standby mode.
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
}
@Override
public void onDestroy() {
// Unregister our receiver.
unregisterReceiver(mReceiver);
// Unregister from SensorManager.
mSensorEventManager.unregisterListener(this);
}
@Override
public IBinder onBind(Intent intent) {
// We don't need a IBinder interface.
return null;
}
public void onShake() {
//Poke a user activity to cause wake?
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//not used right now
}
//Used to decide if it is a shake
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) return;
Log.v("sensor","sensor change is verifying");
}
}
Обходной путь работает на меня, но не будет работать, пока у меня работает screebl, что является особенностью, которую многие из моих пользователей действительно хотят работать в сочетании с тем, что я разрабатываю.
Только что обновил свой Nexus One с помощью ПЗУ FROYO FRF50, которое было популярно в Интернете в течение последних нескольких дней. , и кажется, что датчики теперь снова работают, когда экран выключен, если у вас есть PARTIAL_WAKELOCK. Я не знаю, попадет ли это в официальную сборку, хотя я понимаю, что это основано на официальной сборке, которую получили некоторые пользователи N1. Так что, возможно, они передумали (еще раз) и снова включили датчики, когда телефон заблокирован. Скрещенные пальцы.
Конечно, они могли просто пойти и снова отключить их в 2.2-r1, кто знает ...