6

I am using

window.addEventListener('devicemotion', event => this.watchDeviceMotion(event))

watchDeviceMotion(event: any) {

  let motionData = {
    x: event.acceleration.x,
    y: event.acceleration.y,
    z: event.acceleration.z,
  }
  let rotationData = {
    alpha: event.rotationRate.alpha,
    beta: event.rotationRate.beta,
    gamma: event.rotationRate.gamma
  }

  if (this.getSensorData) {
    // console.log(JSON.stringify(motionData))
    // console.log(JSON.stringify(rotationData))
    this.userData.motionData.push(motionData)
    this.userData.rotationData.push(rotationData)
  }
}

to access accelerometer data on an Android device using Ionic with Angular. When inside the app, the event works at a frequency of 60 Hz but when the app is switched to background, the frequency drops around 9-10 Hz for the first 5 mins and at some point while still in background it goes back at 60 Hz and remains like that indefinitely.

I am also using the background plugin with

this.backgroundMode.enable();
this.backgroundMode.on('activate').subscribe(() => {
  this.backgroundMode.disableWebViewOptimizations();
});

I tried to add disableBatteryOptimizations() to the background plugin with the corresponding condition in config.xml but still no luck.

I also tried the plugins for Device Motion and Gyroscope but they behave the same.

How should I prevent the frequency from slowing down? Has anyone else encountered this problem before?

Daniel T.
  • 451
  • 1
  • 8
  • 23

1 Answers1

1

It is unclear which version of Android you are using, but working against the system usually leads nowhere. Guess you might have tested that with an elder version, because since Android 9, the sampling rate should have a frequency of 0Hz, when the application is in the background. This is due to a new power management with "App Standby Buckets", where only the "active" one isn't restricted.

See the Android 9 behavior changes:

Limited access to sensors in background Android 9 limits the ability for background apps to access user input and sensor data. If your app is running in the background on a device running Android 9, the system applies the following restrictions to your app:

  • Your app cannot access the microphone or camera.
  • Sensors that use the continuous reporting mode,
    such as accelerometers and gyroscopes, don't receive events.
  • Sensors that use the on-change or one-shot reporting modes don't receive events.

The only way to prevent this is manually setting the bucket to "active":

adb shell am set-standby-bucket packagename active|working_set|frequent|rare

Source: Test power-related issues and there's also an UsageStatsManager.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • Hello. I am testing on a Huawei P9 Smart with Android 9.1. If Android 9 does not allow sensor events in background then I am very confused why I am still getting those events. – Daniel T. Jan 08 '20 at 17:27
  • @DanielT. that throttled sampling rate might be Huawei vendor specific, but the stock ROM does not have it. It's not something one can take for granted. [`android.hardware.SensorManager`](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/hardware/SensorManager.java) has values for `SENSOR_DELAY_NORMAL`, `SENSOR_DELAY_UI`, `SENSOR_DELAY_GAME` and `SENSOR_DELAY_FASTEST`, which might at least explain different sampling rates... see line `676` onward; there it suggests a partial wake-lock - but it would waste battery when not handling `onPause` & `onResume`. – Martin Zeitler Jan 08 '20 at 17:57
  • So the sensor data cannot be accessed not even in a Foreground service on Android 9? The Background plugin on Ionic also uses that – Daniel T. Jan 08 '20 at 18:54