onBackgroundData is not called on real device but it works in the simulator

Hi, on my Fenix 7S Pro with the latest firmware and CIQ 7.3.1, I found that on my watch face, onBackgroundData is not called on my device but it works in the simulator. Being harder to debug on a real device, I've added println statement in onBackgroundData, onTemporalEvent and onExitSleep. I see the println in onTemporalEvent  just before the Background.exit call and followed by one in onExitSleep (not related but it's to see if the watch is running in full power, which is when I believe onBackgroundData is called) but the one in onBackgroundData is never called. I've enclosed the Background.exit call within a try/catch clause to see it's because it asserts and it doesn't. I'm returning a dictionary made of two keys made of a few subkeys themselves for a total of just over 200 bytes.

In the simulator, in both high power and standby mode, the onBackgroundData is called right after the Background.exit call without any issues.

Any reason why this is happening? It's frustrating trying to debug something that works well in the simulator but not on the real device.

  • When you do a Background.exit(data)

    and if data=null

    onBackgroundData() won't be called.

    This could be the case if you are doing a makeWebRequest but the status isn't 200 and you are trying to return that data.

  • No, I checked and there is a dictionary being returned.

  • Here's an example of what is returned

    1:28:31 : onTemporalEvent: Exiting with {TeslaInfo=>{VehicleState=>offline, VehicleID=>1493038771190796}, OpenWeatherMapCurrent=>{humidity=>89, cod=>200, lat=>xxx, temp=>-2.970000, dt=>1733207008, icon=>04n, name=>xxx, lon=>xxx}}
    1:29:04 : onExitSleep:Checking pending requests

    This is the code in inTemporalEvent

    try {
        /*DEBUG*/ logMessage("onTemporalEvent: Exiting with " + _bg_data);
        Bg.exit(_bg_data);
    }
    catch (e) {
        /*DEBUG*/ logMessage("onTemporalEvent exit assertion " + e);
    }

  • I found why it didn't work. I was calling back onTemporalEvent from the callback of makeWebRequest to call out another web request (ie, got error 401 so I cleared my token and called back onTemporalEvent  which did a makeWebRequest oauth2/v3/token to receive a new access token and then from that callback I called back onTemporalEvent to retry the request that failed with 401. Looks like it doesn't like it when you call back onTemporalEvent  on the real device while the simulator accepts it. 

    I now call a new makeWebRequest directly from the callback. I know there is a time limit the background code can run but it fits into it.  The code isn't as cleaned as before, but at least it works now. However, I have to read the data returned from the makeWebRequest as HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN since the returned data is too big to fit in a dictionary (I assume because of a dictionary overhead?) returned from makeWebRequest. Hopefully, the issue from two years ago with iOS and HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN has been fixed by now. I have an Android so I can't test it for that platform.