VERY Simple sample of a watch face with a background process.

This one really doesn't do much. It displays the time, an indication if it's on a device that supports background processes (you can see how that's checked in the App Class), The count of the times the background process has run, and the data returned from the background. It does cache data in the object store, so after the first time the background runs, it will have data.


The background process is a Temporal event, and runs every 5 minutes. All the background does is return a string with a time stamp (HH:MM). There are a number of Sys.println() calls to see what's going on. If you have a watch that supports background processes (f5's,chronos,935,735,va-hr), create a <myapp>.txt in logs to catch the println() calls, as you see kind of a neat thing where those that come from the background are marked as such!

This runs in the sim can you can use the code to build a sideload. In addition to devices that support background processes, I included the fenix 3 as a target so you can see how it works on a watch that doesn't.

if you have questions about the code, just ask!
  • Hi Jim, I have a widget already that publish data through a BG process so I could have my watch face to subscribe to that data. However, my biggest problem with background processing is that it can only execute once every 5 mins, and the aplication I have relies on having access to very recent datal. I assume the 5-minute limitiation also applies to BG processing in widgets?   

  • Any background service for any app type can run at most every 5 minutes, and when it runs, it can run for at most, 30 seconds.

  • yep, that's what I thought. So would not solve my problem with web calls in my WF then. Another big problem is that the BG process terminates after 30s, even though it has not received a responbse from the web request. This is a very poorly chosen design since a TCP connection will not always time-out within 30s if there is a connecivity problem. this prevents the foreground app to do any meaningful information to the user or take any action based on the result. I filed a bug ticket about it a long time ago but was never touched by Garmin AFAIK.   

  • I started using a background service on the flight home after it was announced at one of the CIQ summits.  In my experience, if a webRequest didn't complete within 30 seconds, there was a problem with either the cell service or the server I was using.

    The 5 minute/30 second rules were stated when it was announced.  It has to do with both battery and resources.  Only one background can run at a time, so if you have two apps with a background set to run every 5 minutes at the exact same time, one will run and when it's done, the second will run.  There are also times a background may not run for a much longer time.  For example, on some devices, if you are running a ciq device app, no background services will run during the time that app is running.

  • In my experience, if a webRequest didn't complete within 30 seconds, there was a problem with either the cell service or the server I was using.
    This is a very poorly chosen design since a TCP connection will not always time-out within 30s if there is a connecivity problem. this prevents the foreground app to do any meaningful information to the user or take any action based on the result
  • If it's in a background service, the makeWebRequest may not complete in 30 seconds (again based on the connection or server), but the background terminates.  In a foreground process you don't have the 30 second limit.

    And the same applies to other things, say using ANT or BLE (or natively with Sensor) in a background service.  How long should a background run while waiting for a sensor that's miles away, blocking all other background services during that time?

  • Exactly, if a server does not reply within 30s, you either have a connection issue or a web server issue. The poinmt is that the time for a TCP connection to fail (with an error code) differs between different servers and OS, windows use a default setting of 75s. Which means that the BG process would terminate without any error code to the application, so the application cannot handle these error cases in a good way. Again, I feel this is a very poor design (you should not always assume connections and servers are behaving well). A better option would be to either extend the BG service timeout to >75s, or set the TCP_USER_TIMEOUT to <30s (AFAIK this would kill the TCP connection before 30s and return with error to the BG process)  

    A TCP socket should always be allowed to return with a proper error code before the process gets killed, it's best practice for networking apps.

  • But you still have the case where running something else blocks all background services from running at all, And background services can be used for things other than makeWebRequests.

    When this was first introduced, I looked at using a Tempe in the background service for a watch face.  It's kind of a different sensor, in that the way it worked, it can take a minute or more to connect, and the background would terminate after 30 seconds.

    Since you can't use a timer in a background service, I tried a hack where I counted the times that the callback for enableSensorEvents was called, which is normally about once a second.  It kind of worked but there was no data much of the time, and just letting the background time out was cleaner.....

    You could do something similar, and call Background.exit() with an error code after say after 28 seconds. (the callback called 28 times), but you still got the case where the background is blocked from running at all.

    ----------

    update

    ----------

    Another thing to consider, and something I do in a background service be it stand-alone, using makeWebRequest. or a sensor, is include a time stamp with the data you return if it worked.  The calling app can display that, and if the background is having an issue (or not running at all), it's easy to see even if you don't have an error code to display.   You can also compare the timestamp in the data and display an error if it's too old, if you don't want to display the timestamp all the time..

  • Hi Jim, sorry for being slow to respond, been on the road. Counting the number of times a callback is called could be a possible work around (thanks for the tip, I will investigate it further). The point is, we should not have to do these work arounds in the first place. 

  • I tried the counting callbacks within the first couple weeks after background services were introduced, and it didn't really work in the case of the Tempe.

    Now, I'll include a timestamp when I have good data, so the main app can check it's too old and indicate what's happening - such as running a CIQ device-app for an hour, blocking the background from running at all