2

I have developed an app to communicate with an IOT device with this architecture:

IOT: Websocket server that pings all devices connected to it every 5 seconds.

Android 11 App: Foreground Started service that has a websocket client running in a thread and connects to IOT through WiFi. Battery optimization for this app is disabled in android settings so it never puts the app to sleep.

Everything works fine even after turning phone screen off IF I leave the app open and turn screen off. But when I close the app (and Foreground service is still running) then turn the screen off, after almost a minute pings are no longer received and after few minutes websocket connection throws an exception and re stablishes connection and after receiving few pings goes to limbo again and again and again:

2021-07-23 19:12:47.015 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:12:52.008 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:12:57.104 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:02.108 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:07.113 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:12.115 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:17.128 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:22.148 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:27.148 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:32.169 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:37.188 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:42.215 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:47.228 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:52.268 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:13:57.272 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:14:02.272 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:14:07.291 31236-8286/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:22:35.087 31236-8286/com.example.rfremote I/EXCEPTION: java.net.SocketException: Software caused connection abort
2021-07-23 19:22:36.423 31236-11935/com.example.rfremote I/IOT SAYS: ON OPEN RECEIVED
2021-07-23 19:22:39.426 31236-11935/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:37:58.231 31236-11935/com.example.rfremote I/EXCEPTION: java.net.SocketException: Software caused connection abort
2021-07-23 19:38:00.065 31236-12098/com.example.rfremote I/IOT SAYS: ON OPEN RECEIVED
2021-07-23 19:38:02.417 31236-12098/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:38:07.417 31236-12098/com.example.rfremote I/MESSAGE: ON PING RECEIVED
2021-07-23 19:38:12.437 31236-12098/com.example.rfremote I/MESSAGE: ON PING RECEIVED

Please Note the timing of logs and change of ThreadID in the logcat after each reconnection!

Reminder: 1- Connection is from within a Foreground Service 2- App optimization for that app is disabled

Any ideas?

AKTanara
  • 230
  • 1
  • 11

1 Answers1

6

Knowledge Sharing:

After many hours of speculation found quite a few issues and going to share them in order of importance:

  1. For creation of intent to start a foreground service from an activity, always use getApplicationContext() and not this. Issue was that Foreground service was relying on the context provided to it from activity and after exiting the activity java GC would destroy the activity (and the corresponding context after almost a minute and this would interrupt service actions. (There is no need to use getApplicationContext() for launching that intent. this.startService(servInt); will do the job): This solution increased the active connection time after exiting the app and turning the screen off from 75 seconds to 200 seconds.
  2. In android 11 even though you might have disabled Battery Optimization, OS is eager to put to sleep almost every thing while screen is off even foreground services! It might look like the service is active but it is very very limited and wont be able to keep an effective network connection on. So if you want to have a really robust connection you'll have to go to Settings -> Apps -> Advanced -> Special Access -> Optimize Battery Usage -> All Apps -> Find Your App -> Disable Optimization. Strange! Ha? For example in Samsung phones with android 11 going to Settings -> Battery and adding your app to never sleeping list will have absolutely no effect! and android will choke those apps at will except if you had added it to the list of not optimized apps: This patch increased the active connection time after exiting app and turning screen off to unlimited!...

PS: There is a way to ask user for permission to Disable Battery Optimization for the application. But apparently Google Play is not at peace with it and will suspend the application.

AKTanara
  • 230
  • 1
  • 11
  • 1
    we noticed that having Settings > Apps > Special Access > Allowed to use data while Data saver is on > set ON for your App prevents disconnects for our Websocket background service (we moved to a an Bound Service with Messages - our "old" version was running fine till release 31, then suddenly lost connections) – lumo Sep 26 '22 at 13:39