Permissions problem using Toybox.Communications

Former Member
Former Member

I have the following permissions in my manifest.xml, copied directly from the Analog sample:

        <iq:permissions>
            <iq:uses-permission id="Background"/>
            <iq:uses-permission id="Communications"/>
        </iq:permissions>

I'm trying to make a web request, using the sample code found here:

https://developer.garmin.com/connect-iq/api-docs/Toybox/Communications.html#makeWebRequest-instance_function

but I get the following exception when I make the request:

Error: Permission Required
Details: Module 'Toybox.Communications' not available to 'Watch Face'
Stack:
  - makeRequest() at C:\Etc\Dev\Garmin\TravelWatch\source\TravelWatchWeb.mc:27 0x10001425
  - onUpdate() at C:\Etc\Dev\Garmin\TravelWatch\source\TravelWatchView.mc:154 0x100008b2
Encountered an app crash.

Can someone explain why I don't have permission to use Communications when it's explicitly granted in manifest.xml?

  • Hi,

    Do you use a background process to use webrequest ? 

  • Yes, that's why in order to set the comm permission, you must enable the background permission

    To do comm, you need a background service to do comm in a watch face.  It's actually odd the analog sample has those permissions, as it doesn't have a background service or do any comm.

  • Former Member
    0 Former Member over 4 years ago in reply to Shent-Aurkhan (SHN)

    Since nothing is annotated, I get the following warning from the compiler:

    WARNING: venusq: The background permission was enabled but no source code was annotated.  The entire application will be loaded as a background process. (background application)

    Therefore it should be running as a background process already.  Or is there something I need to do explicitly for this?

    -- Edit --

    I just now say your reply jim_m_58, I'd left the page open overnight, and it took a refresh to make it show.

    Looks like I'll be studying the BackGroundTimer sample, since that uses the :background annotation.   Thanks for the help.

  • Are you set up to run a background?  And you really do want to annotate what's needed as background have a limited size. (32k on some devices and that would limit the size of your WF without annotations.

    Are you registering a temporal event, have things like getServiceDelegate and onBackground data?

    Here's a whole thread about doing backgrounding: https://forums.garmin.com/developer/connect-iq/f/discussion/5287/very-simple-sample-of-a-watch-face-with-a-background-process

    And a blog post about backgrounding: https://developer.garmin.com/connect-iq/connect-iq-faq/how-do-i-create-a-connect-iq-background-service/

  • Former Member
    0 Former Member over 4 years ago in reply to jim_m_58

    Definitely making progress on the issue.  I took your vsbgwf code from the thread you mentioned, that was an immense amount of help - thanks for making it available.

    By adding a call to my http request code in the onTemporalEvent() callback, I've sort of got it working.  The request is made, I can see it working correctly in the simulator HTTP log. However I get an:

    Encountered an app crash.

    error right after the request is made and nothing else: my response callback isn't getting called.  So there's some sort of disconnect between receiving the response from the server, and actually calling the callback.

    I just can't find any further information about it, I don't get a stack trace, no logs, nothing.  I stongly suspect the crash is in the background logic, because the main watchface continues to operate, I can see the onUpdate counter ticking over.

  • Encountered an app crash.

    Is that when you first start a run?  Are you using Eclipse or VS Code?  Have you added the (:background) annotations where needed?

  • Former Member
    0 Former Member over 4 years ago in reply to jim_m_58

    The error occurs at the time the onTemporalEvent() callback is made in bgbg.mc.  You can see my modifications at https://scruffy.org/bgbg.mc  .  I know it's a direct result of the attempt to make the https:// request because if I comment out the call to makeRequest() at line 18, the problem goes away.

    The exact sequence of events is:

    1.  makeRequest() is called, and issues the makeWebRequest() call.

    2.  I can see the request being made: CTRL-H pops open the HTTP request log, and it's visible there.

    3. I do not receive a callback via onReceive(), but this is where the app crash happens.

    I'm not using Eclipse, since I could not for the life of me get the "Build for device" dialog to acknowledge that I had the 3.2.5 SDK installed. Trust me, I tried everything, including the usual uninstall / reinstall operation on both Eclipse and the SDKs and SDK Manager.

    I was not aware that VS code was available as an option, after the disaster that Eclipse turned into, I found a blog post from someone who was using makefiles under Linux.  I was easily able to adapt them to work under Windows.  So it's just edit up the source in Notepad++, "make" and then "make test" and I'm running.  Simulator console output appears right in the console window I'm using, so I can easily use System.println() for debugging.

    Unless Eclipse / VS Code provide source level debugging, I can't see an engaging case to use them.  If it makes a difference, I grew up on Unix in the pre-Linux days, so I'm completely comfortable at the command line.

  • Ok, first thing is here:

        function onTemporalEvent() {
        	var now = Sys.getClockTime();
            makeRequest();
        	var ts=now.hour.format("%02d") + ":" + now.min.format("%02d");
            Sys.println("bg exit: "+ts);
            //just return the timestamp
            Background.exit(ts);
        }

    You dont want to do anthing after the makeRequest

    The Background.exit should be in your receive callback, as that's what you want to pass on and the background to end.

  • Former Member
    0 Former Member over 4 years ago in reply to jim_m_58

    Ahh - *TOTAL* misunderstanding on my part.  Looking more closely at the console output, I now see that it's like a whole new invocation of the app, but with a "Background:" prefix on all log lines.  And that's presumably where the (:background) annotation comes into play, this second process only loads classes that explicitly have that annotation.  Which is what that 32K limit you mentioned is all about.

    And that one background process is responsible for both making the request *and* handling the response, which in turn is why things were breaking.  There wasn't a process left to handle the response when it finally arrived from the server, because it had already exited.

    It's working now, as In I can get the data from the web server, and display it on screen.  I'll need to go over the code and do a ton of cleanup, but I've cracked the main problem which was to get a web request happening.

    Thanks again for all your help.

  • Hi Jim,

    I hope you are still following this old thread. My son and I have been trying to write code for a watch face that gets tide data from Stormglass.io. I am not a programmer, but my son has a little bit of Python knowledge and managed to get it working as a "widget", but you had to press 'menu' or 'select' to make the request.

    Then when I changed the manifest.xml to "watch face", I got the IQ/exclamation mark crash. I read that it was because button presses to make web requests weren't allowed in watch faces. So I've just spent a week learning (from Claude.ai) how to change from button pressing to a time based web request.

    The time based web request works fine as a widget, but still crashes as a watch face. I get this Error: Permission Required Details: Module 'Toybox.Communications' not available to 'Watch Face' 

    Is it really true that watch faces can't use Toybox.Communications?