Androidでサービスを作成して、その中で歩数計センサー（TYPE_STEP_DETECTOR）を使用して歩数をカウントしています。  
アプリを起動しているときは問題なくカウントされるのですが、スリープ状態（画面が真っ暗の状態）のときにカウントが極端に少ない場合がありました。  
スリープ状態だと必ずカウントが少ないというわけではないのですが、再現パターンがいまいちわかりません。

カウントがされない原因がわからないのですが、スリープ状態だと歩数計センサーが作動しなくなるとかあるのでしょうか？

アドバイスをよろしくお願い致します。

```

    public final class PedometerService extends Service implements SensorEventListener {
    
      private SensorManager mSensorManager;
      private Sensor mSensor;
      private HandlerThread mSensorThread;
    
      @Override
      public void onCreate() {
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
        mSensorThread = new HandlerThread("PedometerServiceThread");
        mSensorThread.start();
        mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_FASTEST,
                                        new Handler(mSensorThread.getLooper()));
      }
    
      @Override
      public void onDestroy() {
        mSensorThread.getLooper().quit();
        mSensorManager.unregisterListener(this);
      }
    
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
      }
    
      @Override
      public IBinder onBind(Intent intent) {
        return null;
      }
    
      @Override
      public void onSensorChanged(SensorEvent event) {
        int value = (int)event.values[0];
    
        //歩行を検知したときの処理
    
      }
    
      @Override
      public void onAccuracyChanged(Sensor sensor, int accuracy) {}
    
    }
    
```
CC BY-SA 3.0
2017-05-12T00:40:54.580
34647
2017-05-16T12:30:27.293
7212
question
android
Androidでスリープ状態で歩数計センサー（TYPE_STEP_DETECTOR）の使用について
アプリが[Dozeモード](https://developer.android.com/training/monitoring-device-
state/doze-standby.html?hl=ja)に入ることによって、カウントがされなくなっていると思われます。  
Dozeモードは簡単に説明すると、電池の消費を抑えるために端末を使用していない場合は、ほぼ全ての処理を止めて節電モードに入る機能です。

DozeモードはAndroid 6.0から導入されました。  
Android 6.0の時は端末を持って歩いている（端末が静止状態じゃない）場合はDozeモードに入らなかったのですが、Android
7.0からは静止状態でなくてもDozeモードに入るようになりました。

Dozeモード中もアプリを動作し続ける方法は[公式のドキュメント](https://developer.android.com/training/monitoring-
device-state/doze-standby.html?hl=ja)にも記載されているので確認してください。  
Qittaに投稿されている [Android
M/NのDozeによる制限とバックグラウンドタスク実行に関するまとめ](http://qiita.com/FumihikoSHIROYAMA/items/b1d6dbda120462d0e209)
が非常によくまとまっているので、参考にしてみてください。

対策としては、[ホワイトリストへの登録](https://developer.android.com/training/monitoring-device-
state/doze-standby.html?hl=ja#whitelisting-cases)が良いかと思います。
CC BY-SA 3.0
2017-05-12T01:48:52.717
34649
2017-05-12T01:48:52.717
21081
34647
answer
自己レスです。

特定の端末(Galaxy Android6.0)で再現性があることがわかりました。  
画面OFFにして、歩くと必ず歩数が極端に少なくなりました。

そこで、Sensor.TYPE_STEP_DETECTORではなくてSensor.TYPE_STEP_COUNTERにして、端末起動してからの累計歩数を保存しつつ、前回保存した累計歩数との差を歩数とするようにしました。  
すると、画面OFFにしてもそれなりにカウントされるようになりました。

TYPE_STEP_DETECTORよりTYPE_STEP_COUNTERを使用したほうがよいのでしょうか？

不可解なのですが、TYPE_STEP_COUNTERを使用することにしました。
CC BY-SA 3.0
2017-05-12T08:58:03.757
34661
2017-05-12T11:51:03.383
2017-05-12T11:51:03.383
7212
7212
34647
answer
(コメント欄に収まらなかったので回答欄を使用します)

Takeruさんのご回答はAndroid側がSleep状態であるとSensorは動かず、  
Android6.0以降のDozeおよびAppStandbyの仕組みによりSleepされる契機が増えたというご回答になります  
それはそれで事実なのですが、「アプリが動ける条件」と「Sensorが動ける条件」は微妙に違います。

Android4.4より追加されたSensorBatchingにより、Android側のprocessor(以下APとします)がSleep状態でもSensor側のチップで情報を蓄積し  
AP側がSleep解除時にSensor側で持っていた情報を一気に渡す仕組みが出来ました。

これによりDozeモード等でアプリ側が動けなくてもSensor側で情報を蓄積し、  
ユーザーがアプリを表示したタイミング等でヒストリカルに情報を取得することができます。

が、Sensor側のチップでそれに対応している必要がありますし、  
Sensor側のHardware FIFOの限界量(蓄積情報の限界量)より前に蓄積されていた古い情報は消えます。  
(Android4.4時に色々な端末を見た限りではほぼ対応していませんでした。具体的なデータがなくて申し訳ないですが・・・)

要はAndroidのソフト仕様ではなく、各端末のハード仕様で挙動が変わってしまい  
上記方法で自分用に作るアプリならまだしも、  
GooglePlayでさまざまな端末向けに公開するようなアプリを対応するのは難しいかと思います。

アプローチは変わりますが、SignificantSensor(TYPE_SIGNIFICANT_MOTION)というSensorがあります。  
これはAPがSleep時でも動作が可能で、かつAPにTriggerを送ることがCDDで保障されているSensorになります。(WakeUp Sensor)  
アプリ側でSleepを検知したら、SignificantSensorを貼り、歩きだしタイミングでAPを起こすというアプローチは可能かと思います。(もちろんSensorBatchingのアプローチと比べ消費電力観点でよいとは言えません。)  
もっともSignificantSensor自体が乗っていない端末もあるのでどっちもどっちですが・・・
CC BY-SA 3.0
2017-05-16T12:30:27.293
34756
2017-05-16T12:30:27.293
19716
34647
answer