new Timer.Timer(); Error: Permission Required ; Details: Module 'Toybox.Timer' not available to 'Data Field'

I'm writing a library (maybe it'll be a barrel) which I also use in a datafield (for on-device settings input) and in other types of apps.

It uses a timer, which isn't available in datafields. When I try to create a timer I get:

var timer = new Timer.Timer();

Error: Permission Required
Details: Module 'Toybox.Timer' not available to 'Data Field'

This is OK, the rest of the functionality is still useful, but I am not able to catch the error and "Timer has :Timer" returns true. Is there a way to know programmatically that I am running in a datafield or check for whatever this required permission is or that I can use Timer.Timer?

  • Did you ever figure out a successful way to test for this? I'm basically in the same situation.

  • there were multiple solutions in the previous comments

  • Neither of the suggested solutions seem to work though. For what it's worth my testing is using a widget vs a datafield on a simulated Edge 530; perhaps things are different on a watch.

    Application.getApp() has :getGlanceView returns false in both cases.

    Timer.Timer has :start returns true in the widget and just triggers the error in the datafield.

    The other suggested approaches are static checks where you know ahead of time what you're building. Clearly that approach works, but doesn't solve the problem in terms of a dynamic check, which is what I need.

    For what it's worth the one thing I found that did work is to do: Application.getApp().getInitialView()[0] instanceof WatchUi.DataField, which returns true in the datafield case. However, it's obviously pretty bad practice to just go calling getInitialView as the user, not least because the view's constructor might have side effects. I don't think there is a way of getting at the existing instance that the system creates. There is WatchUi.getCurrentView, but that won't necessarily return the view we want to test with instanceof, and anyway it's API 3.4.0+, which means it's not available on my Edge 530.

    Which solution did you end up going with? Have I missed something?

  • I use (the not too well documented) https://github.com/flocsy/garmin-dev-tools to generate monkey.jungle files, but you can also do it manually. In your case (guessing) you probably have 2 different monkey.jungle files already, in which case all you need is to add an annotation, and then your code can use it and have differences depending on the annotation.

    IMHO there's no advantage of having all your code in every device / app, even when some devices don't need the code for features that need some hardware or when your datafield doesn't have access to the Timer class. If you compile your datafield for older devices as well then it even becomes a problem on devices with very limited amount of memory, so I use these excludeAnnotations wherever I can.

  • Ah OK, makes sense. Definitely a better approach than having to pass a parameter to the library, at any rate. Thanks.