Simulator Won't Allow Watchface to Set Up Timer

As of SDK 1.1.2, the simulator will abort with a "Permission Required" error with the following code. Similar code still seems fine running on hardware.

class SandboxView extends Ui.WatchFace {
var myTimer;

function onLayout(dc) {
myTimer = new Timer.Timer();
myTimer.start(method(:myUpdate), 500, true);
}

function onUpdate() {
}

function myUpdate() {
Sys.println("Hello");
}

}
  • Former Member
    Former Member over 10 years ago
    The actual watch starts up a watchface in high power mode, while the simulator (now) starts up in low power mode.

    The actual watch will not call an onExitSleep at startup so if you assume the watch is in sleep mode you will not get your seconds hand running when the watchface is opened even though you could. While the simulator (now incorrectly) calls an on EnterSleep before the Watchface is even created in order to force the simulator to start in low power mode which is what is causing the errors.

    There are workarounds so that both the real watchface and the simulator will both run error free - but how lame is that to have to do.
  • You can only safely start a timer after onExitSleep() has been called and before onEnterSleep() has been called.


    While I can tell from the documentation that this is indeed a valid way of handling things, I can't tell that it is the only valid way. Is it written somewhere that this onExitSleep() is the only place a programmer can start a timer?

    The practical use case is a watch face that can't do all of its rendering at once and needs to duty cycle with a timer to avoid watchdog timeouts. If the power state on init is non-deterministic and out of programmer control then this would make this use case challenging.

    I have a watch face that does this, but the reason I am asking the questions is to better understand the contract between the API and the programmer. The API does happen to call onExitSleep() near init time, but to me this is counterintuitive: if the watch face starts in high-power mode, then why the call to onExitSleep()? I'm just looking for some clarity.
  • Is it written somewhere that this onExitSleep() is the only place a programmer can start a timer?

    Nobody said you can't start a timer outside of onExitSleep(). You can start a timer as long as the device is not in low power mode. i.e., after onExitSleep() and before onEnterSleep(). The User Experience Guide and the reference documentation for WatchFace indicate that this is the case. The fact that you get an exception when in low power mode doesn't hurt either.

    The API does happen to call onExitSleep() near init time, but to me this is counterintuitive: if the watch face starts in high-power mode, then why the call to onExitSleep()? I'm just looking for some clarity.

    Until one of the sleep functions is invoked, there is no way for the application to know if it is safe to start a timer or not. Once one of them has been called, you know the current device state, and you move on.

    I haven't put a great deal of thought into this but I think you are screwed. Assume the watch is just sitting on a desk face up and that your watch face takes two onUpdate() calls to completely render. At the top of the minute, the device will automatically call onUpdate(). You'll be able to draw half of the detail before you have to bail out. You can't start a timer because you're in low-power mode, and the next onUpdate() call is 60 seconds away. The only thing that you can do is just leave a partially rendered view until the full minute has passed. By the time you get invoked to finish rendering, a minute has passed. It is highly likely that the data you rendered a minute ago is now invalid and must be rendered again.

    Travis