Check if access to WatchUi is permitted?

Hi,

I have a background service, that shares code with my foreground app. In that code, can I check somehow if access to WatchUi is permitted? It seems that using "has" on a method of WatchUi already counts as illegal access and I cannot use it. Also the "Permission Required" error from the SDK is not catchable.

Is there any other way? Or do I have to implement my own method to remember if it is the background executing the code?

Regards, Robert

  • What I do is this:

    (:background)
    function isRunningInForeground() as Boolean {
        return $ has :getApp;
    }
    
    function getApp() as MyApp {
        return Application.getApp() as MyApp;
    }

    Instead of getApp you can use any class, function that you only need in foreground and isn't annotated with (:background)

  • Thanks, that's a good idea!

    Btw, what is the purpose of this getApp() function? I saw it in some examples, but in others it is not there. I did not include it in my app, and it seems to work fine without it.

  • In some apps I don't need it. Here I use it as: 

    getApp().getView();
    (getView returns the same (saved) view as getInitialView())
    and in most apps it's used for get/setProperty:
    getApp().setProperty(key, val);
    Although there's a trick that can shave off a few bytes from the code, but then you need to use the proper app class:
    ((MyApp as Object?) as MyApp).setProperty(key, val);
  • Understand that your AppBase runs for both the main app and the background service, while some of the functions are called for both (initialize(), onStart(), onStop() for example), some only for the main app (getInitialView(), onSettingsChanged(), onBackgroundData() for example) and some only for the background (getServiceDelegate for example.

    Class and even global variables are not shared between the main app and the background.  They each have their own copy.  So what you can do is have a variable

    var inBackground=false;

    and then in getServiceDelegate(), set

    inBackground=true;

    You can then check inBackground to see if you are running in the main app or a background service. 

    One place I'll use this in in onStop().  For example, if the main app is exiting, I may want to do a deleteTemporalEvent(), but I don't want to do that if it's the background service that's ending.

    In this thread from years ago I posted a very simple sample that shows a variation on this.

    https://forums.garmin.com/developer/connect-iq/f/discussion/5287/very-simple-sample-of-a-watch-face-with-a-background-process

  • Thanks, I came to the same conclusion and implemented it like this:

    (:background :glance) class myApp extends Application.AppBase {
        private static var _isInBackground = false;
        static function isInBackground() as Boolean { return _isInBackground; }
    
        function getServiceDelegate() {  
            _isInBackground = true;
            // other code
        }    
    }

    Note to myself: I am still following old habits. In context of Monkey C, the isInBackground() function is probably a waste of code space and I should access the variable directly ...

  • on some newer devices, you can check what's passed to onStart, but doing it this way works on all devices, even if they don't support backgrounding.

    And remember, as AppBase is used by both the main app as well as the background service, it's size impacts how much memory is left for the background service, so you want to keep your AppBase as small as you can.

    Here's a blog post I did on backgrounding when it was first introduced:

    https://developer.garmin.com/connect-iq/connect-iq-faq/how-do-i-create-a-connect-iq-background-service/#howdoicreateaconnectiqbackgroundservice

  • Understood, and thanks for the link!