サービスを拡張し、AndroidでonSensorChanged(SensorEvent event)加速度センサーの読み取り値を記録するコードがいくつかあります。デバイスの電源がオフの場合でも、これらのセンサーの読み取り値を記録できるようにしたいと思います(バッテリーの寿命に注意しており、実行時に明らかになります)。画面が表示されている間、ロギングは2.0.1 MotorolaDroidと2.1NexusOneで正常に機能します。
ただし、電話が(電源ボタンを押して)スリープ状態になると、画面がオフになり、onSensorChanged
イベントの配信が停止します(onSensorChanged
がN回ごとにLog.eメッセージを使用して確認されます)と呼ばれる)。
サービスはwakeLockを取得して、バックグラウンドで実行し続けることを保証します。しかし、効果はないようです。さまざまなPowerManagerをすべて試しました。ウェイクロックが重要ではないようです。
_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
_WakeLock.acquire();
画面がオフのときにセンサーから実際にデータを取得できるかどうかについては、相反する報告があります... Android(Eclair)の最新バージョンでこれを使用した経験はありませんとハードウェア?
これは、カップケーキで機能していたことを示しているようです: http://groups.google.com/group/Android-developers/msg/a616773b12c2d9e5
PS:G1の1.5で意図したとおりにまったく同じコードが機能します。画面がオフになったとき、アプリケーションがバックグラウンドにあるときなど、ロギングは続行されます。
これは2.0.1から始まったと推測しています。これは意図的なもののようで、おそらく機能として宣伝されたバッテリー寿命の向上の一部です。 2.0でウェイクアップまたはロック解除するための動作シェイクがありましたが、アップデートで壊れ、回避策を得ることができませんでした。 ; '(CPUがスリープ状態になるのを常に防ぐはずのCPU部分ロックが保持されているかどうかは関係ありません。USB経由でデバッグをログに記録しているのを見たところ、スリープが発生するとセンサーリスナーが変更されることが時々あります。
ユーザーが、モトローラデバイスで動作すると主張する回避策を投稿しました 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を実行している間は機能しません。これは、多くのユーザーが私が開発しているものと組み合わせて作業したい機能です。
NexusOneをFROYOFRF50 ROMで更新しました。これは、過去数日間インターネットを駆け巡っています。PARTIAL_WAKELOCKを使用している場合、画面がオフのときにセンサーが再び機能するようです。 。これが公式ビルドになるかどうかはわかりませんが、これは一部のN1ユーザーが受け取った公式ビルドに基づいていると理解しています。したがって、彼らは(もう一度)考えを変えて、再電話がロックされているときにセンサーを有効にしました。指が交差しました。
もちろん、2.2-r1で再び無効にすることもできます。
を使って SCREEN_DIM_WAKE_LOCK
HTCEVOで私のために働いた。
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
_WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG");
_WakeLock.acquire();
これは2.1ファームウェアの問題のようです。これを修正する必要がありますが、すべてのバージョンをカバーするには、あらゆる種類の回避策を実行する必要があります。
私は、電話またはファームウェアのいずれかをテストできるように、機能する/機能しない/断続的に機能する電話とファームウェアのリストをまとめています。
http://apprssd.com/2010/09/08/Android-onsensorchanged-not-working-when-screen-lock-is-on/
リストを更新できる新しい電話をお持ちの場合は、お知らせください。
次を使用して画面を常にオンにしておく別の解決策(一種)があります。
Settings.System.putInt(getContentResolver()、Settings.System.SCREEN_OFF_TIMEOUT、-1);
ただし、これは、ユーザーが電源ボタンを押して画面を強制的にオフにし、センサーイベントストリームを停止することを妨げるものではありません。これを機能させるには、WRITE_SETTINGS権限も必要です。
センサーイベントの再登録に関する上記の回避策は、Android 2.1を実行し、アップグレードを取得する予定はないDroid Erisでは機能しません。次の方法を使用しましたが、このアプローチでは、登録を解除して再登録する代わりに、ユーザーがオフにすると画面がオンに戻りますが、淡色表示に戻ります。次のコードでは、ハンドラーはアクティビティで作成された単純なハンドラーです。 (つまり、ハンドラーハンドラー= new Handler();)およびmTurnBackOnはnullに初期化されたWakeLockです。
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
// Turn the screen back on again, from the main thread
handler.post(new Runnable() {
public void run() {
if(mTurnBackOn != null)
mTurnBackOn.release();
mTurnBackOn = mPwrMgr.newWakeLock(
PowerManager.SCREEN_DIM_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP,
"AccelOn");
mTurnBackOn.acquire();
}});
}
}
};