12

It is a well known issue that many Android phones switch off the accelerometer when the screen goes off. However something seems to have changed with Android Fit (the app). Fit keeps counting steps even when the screen goes off. If Fit is installed, then events are raised for step counting within the Fit environment and I am able to capture them using

Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
                .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)

I have tested this on a Samsung S4 and on a Oneplus One and in both cases the steps are counted. How do they do that? What Android classes do they use? My understanding is that the available method introduced since Kitkat is to implement a SensorEventListener. For example theelfismike provides code that implements this. However on many phones the step counting stops when the screen goes off. Interestingly the counting does not seem to stop if the Google Fit app is installed (hence I guess they keep the accelerometer on).

Am I missing something? Is the functionality of keeping counting steps after screen off available to the mortal programmers? Thanks!

FabioC
  • 452
  • 4
  • 14

2 Answers2

8

As Ilja said, your code runs even after the screen gets turned off. But in this case I guess we need a little different answer.

They definitely use a Service that keeps a wakelock and they query the sensors for data. Important part here is holding the wakelock - you have to prevent the device from going into sleep during lifetime of your service - if you don't want to miss some data.

But this approach will be drain the battery really fast, because in order to detect steps you need to process quite a lot of data from sensors.

Thats why there is sensor batching. That allows you to get continuous sensor data even without keeping the device awake. It basically stores the sensor events in a hw based queue right in the chip itself and only sends them to your app (service,..) at predefined intervals in batches. This allows you to do a 24/7 monitoring without draining the battery significantly. Please note that only supported chipsets can do that (you can find details in Android docs), in case of older phones you need to fallback to the hideous wakelock keeping method in order to get your data.

You can also just use Google Fit APIs, but this would only work when there're both Google Fit + Google Play Services installed on the device with monitoring turned on.

simekadam
  • 7,034
  • 10
  • 49
  • 75
  • Thanks @simekadam. What you say is correct. However what I do not understand is how they do it. The only way I can see to keep the step counter on on many phones is to acquire a full lock, which is not really energy efficient. The partial wakelocks such as WakefulBroadcastReceiver seem to be ignored by most accelerometers. This is why I am wondering how they do it in an efficient manner. – FabioC May 23 '15 at 07:39
  • @FabioCiravegna could you please post more code to your question? That could help me resolve your issue..You are starting your stepcounter from a WakefulBroadcastReceiver? Do you start your recording service with startWakefulService? Do you acquire a separated wakelock for your service then as well? (WakeFullBroadcastReceiver releases its wakelock after 60 seconds) – simekadam May 23 '15 at 08:27
  • many thanks for offering to help. I have created a simple example on [link] (https://github.com/fabcira/step_counter_with_wakeLock) Github. It is even simpler than the one I mention before. The Main Activity registers the sensor and sets up a partial wakelock. Then I start the activity. The step_counter works. When I turn the phone off it stops. However I have created a service that checks if the wakeLock is on. It is. But the step counter is off. The set up also checks if the phone has the hardware step counter. Mine has it. I am baffled. Any help is welcome. Thanks! – FabioC May 25 '15 at 11:45
  • try to remove the `activityRunning` conditition..this will make your step counter working even after screen goes off..Also you should better move your step counting logic to the service. The activity could be terminated at any time regardless you hold a wakelock – simekadam May 25 '15 at 12:05
  • oh dear that was a silly mistake. I am currently away without my G4 so I won't be able to test it until later next week. I will let you know. Many thanks for now! – FabioC May 26 '15 at 22:21
  • As feared, it still does not work. I have modified so to remove the error but still it does not work. Any idea? – FabioC Jun 01 '15 at 06:51
  • Any thoughts on how this will be affected by the new M version and dosing? – JohanShogun Jul 25 '15 at 09:23
  • 1
    @JohanShogun: what's in docs: Network access is disabled, unless your app receives a high priority Google Cloud Messaging tickle. Wake locks are ignored. Alarms scheduled with the AlarmManager class are disabled, except for alarms that you've set with the setAlarmClock() method and AlarmManager.setAndAllowWhileIdle(). Syncs and jobs for your sync adapters and JobScheduler are not permitted to run. Conclusion: You won't be able to get accelerometer data while being dozed - you might get them (or some part) later depending on the HW queue size though (once undozed). – simekadam Jul 30 '15 at 12:16
0

Every normal Thread is keep on working when the screen goes off or when the Activity lost its focus...but when the activity gets killed then all thread are killed...

However you can use services for longrunning tasks like asking the accelerometer for example

Ilja KO
  • 1,006
  • 11
  • 22
  • Thanks for your answer. I use background services so when the app loses focus they are still working. I use both the step counter and the activity recognition in that process. The activity recognition keeps going. The step counter is killed. – FabioC May 22 '15 at 07:07