Widget with Background not working on Fenix 7s, but in the simulator

Hello all,

I have a strange problem. I developed a Widget, that uses a background process to grab some data from the sensor.
In the simulator this works fine, but on my Fenix 7s the background process is not called automatically.
It's called, when I show the Widget, either in glance mode or if I go to the full view.
Using SDK 4.0.10, but tried it also with 4.1.0 beta, same effect.
The firmware of the watch is 7.35

I tried to reproduce it with a simple Widget, that only writes a counter to the properties and increases that counter in the background process and write it back in "onBackgroundData"
Same effect, in the simulator it works fine, but not on the watch.

I tought a background process should be called automatically in the background?
For this widget, my expectation was, that the counter increases automatically every about 5 min by one, even if I don't show the widget in the meantime.

Here is my source code, maybe I'm doing something wrong? Any help is very welcome?
Or is there something on the watch to configure, to allow background processing?
App:

(:background)
class MyWidgetApp extends Application.AppBase {

    function initialize() {
        AppBase.initialize();
    }

    function onStart(state as Dictionary?) as Void {
    }

    function onStop(state as Dictionary?) as Void {
    }

    function getInitialView() as Array<Views or InputDelegates>? {
        return [ new MyWidgetView() ] as Array<Views or InputDelegates>;
    }

    function onBackgroundData(data) {

        System.println("onBackgroundData");
        getApp().setProperty("MYBG_DATA", data);
        WatchUi.requestUpdate();
    }

    function getServiceDelegate() {
        return [new BgbgServiceDelegate()];
    }

(:glance)    
	function getGlanceView() 
	{
    	if (Toybox.System has :ServiceDelegate)	{
    		Background.registerForTemporalEvent(new Time.Duration(5 * 60));
    	} 
    	else {println("no background available");}
	
        return [ new MyGlanceView() ];
    }     
}

Delegate:

(:background)
class BgbgServiceDelegate extends Toybox.System.ServiceDelegate 
{
	function initialize()	{
		ServiceDelegate.initialize();
	}
	
    function onTemporalEvent()  {

		var counter = getApp().getProperty("MYBG_DATA");
		if (counter == null) {
			counter = 0;
		} 
		else {
			counter ++;
		}
		
        Background.exit(counter);
    }
}

Thanks a lot

  • In the sim, widgets don't time out, so onBackgroundData() will run each time the background runs.  On the real device, widgets time out after about 2 minutes, and if the background runs twice before the widget runs again, the widget only sees it ran once.

    I suspect the background is running as it should, but the widget itself isn't seeing it because it's not running, and therefore the new value doesn't get saved.

    Look at using

    lastData=Background.getBackgroundData() in onTemporalEvent(), and if  lastData is not null, use that instead of reading the property

  • So, 

        function onTemporalEvent()  {
            var counter=Background.getBackgroundData();
            if(counter==null) {     //widget has run since last time background ran
    		    counter = getApp().getProperty("MYBG_DATA");
    		    if (counter == null) {
    			    counter = 0;
    		    } 
    		}
    		counter ++;
    		
            Background.exit(counter);
        }

  • Hi Jim,

    you are a real expert and very helpful! Thanks a lot.

    I think I see the problem now. I thought, even if the widget is timed out, all the background functions will run.
    But now it's clear, "onBackgroundData()" is running only if the widget is active.

    Let me try your solution