System 3: multiple views? present different settings?

Hi,

I am trying to adapt my app to System 3 devices, but I do not have any of those to physically test.

From the simulator it seems that System 3 only supports widgets with a single view, is that correct?

If that is the case, I'd like to present the user with only a subset of settings. I tried to put a different settings.xml in the resource folder (e.g. "resources-vivoactive3"), but that does not work, it still takes the settings.xml from the main resources folder. Is there a way to hide some settings for System 3 devices?

Regards, Robert

Top Replies

All Replies

  • You don't see a glance view, but otherwise are almost the same,  You can have multiple view.

    You can see if a glances involved with isGlanceModeEnabled in System settings.  Real example, if if there is no glance view, in my BLE widgets, I don't start scanning until the user presses select..

    In the top level view, you can't use up/down as that's grabbed by the widget loop to move through the widget loop.  but you can push a view and use up/down there.

  • Understand, thanks! How can I "push a view" in the simulator? I tried it with the Vivoactive 3, and neither clicking on the one button nor clicking on the screen seems to go into a mode where I can use up/down.

  • WatchUi.pushView() from the top level view.

    If you want to support devices without glances, you may want to pick up a second hand device on ebay.  You can probably get one pretty cheap.

    You may want to consider just not supporting devices without glances, as the number of users with a device like that is dropping.

  • If that is the case, I'd like to present the user with only a subset of settings. I tried to put a different settings.xml in the resource folder (e.g. "resources-vivoactive3"), but that does not work, it still takes the settings.xml from the main resources folder. Is there a way to hide some settings for System 3 devices?

    As you’ve found, device-specific resource folders are additive, they don’t completely override the default resources.

    If you want to have common resource folder(s) which are excluded for certain devices, you will have to hardcode those rules yourself, in your monkey.jungle file.

    e.g.

    # resources shared by all devices go in resources/

    # resources only for system 4 and higher go in resources_sys4/
    resources_sys4_paths = resources;resources_sys4

    # resources only for system 3 and lower go in resources_sys3/
    resources_sys3_paths = resources;resources_sys3


    # base.resourcePath applies to all devices unless otherwise overridden
    base.resourcePath = $(resources_sys4_paths)

    vivoactive3.resourcePath = $(resources_sys3_paths)

    How can I "push a view" in the simulator? I tried it with the Vivoactive 3, and neither clicking on the one button nor clicking on the screen seems to go into a mode where I can use up/down.

    It doesn’t happen automatically, as jim_m_58 said, your app has to do it in response to user input (usually the “select” action, which a tap of the screen in vivoactive 3, or a short press of the START button on 5 button watches.) I think the reason for this is that top-level view (with almost no user interaction) and the 2nd-level view (with full user interaction) are supposed to be different, both visually and functionally. However, you will see that on older watches with widget, a native widget’s the top-level view and its 2nd-level view are usually visually similar (sometimes with background/foreground colors reversed, so that the top-level is dark mode and the 2nd-level view is light mode, for example.)

    i.e.

    - top-level view = view returned by getInitialView()

    - in your app, associate the top-level view with a behavior delegate (by returning the view and delegate in getInitialView())

    - in the behavior delegate, implement onSelect() such that it calls WatchUi.pushView() with a second-level view and returns true. This newly pushed view will be able to handle full user interaction, including UP and DOWN swipes (or button presses, where applicable).

    The way I think of it is that the top-level view is a preview page for your widget (almost no user interaction possible), and the second-level view is the real “main page” for your widget (since it allows for full user interaction.)

    When comparing widgets to apps launched from a glance, I see it like this:

    widget          |  app launched from glance

    top-level view <=> glance view

    2nd-level view <=> top-level view

    (The top-level view of a widget is like an app’s glance view, and the 2nd level view of a widget is like the top level of the app that was launched from a glance.)

  • Back to the settings question.  Here's a monkey.jungle file I use in one of my watchfaces, specifically for screen colors.  The semioctgacon (instinct) watches are only black and white, while others have multiple colors

    resources is the common stuff - AppName, icon, etc.

    resources-basic are the properties and settings for most watches, where colors can be selected.

    resources-so are the properties and settings for B&W devices where only white or black background can be selected,

    project.manifest = manifest.xml
    
    project.typecheck = 0
    project.optimization = 2
    
    base.resourcePath=resources;resources-basic
    semioctagon.resourcePath=resources;resources-so

  • It doesn’t happen automatically, as jim_m_58 said, your app has to do it in response to user input (usually the “select” action, which a tap of the screen in vivoactive 3, or a short press of the START button on 5 button watches.)

    Thanks for the many inputs!

    So I’ll have to do a bit of a different implementation for the pre-glance watches. I remember reading somewhere here in the forum how to check the API version, but cannot find it anymore, also not in the documentation. 

    Could you give me a hint? Which method can I use to detect the API version?

  • On the Garmin, you can get it's CIQ version using monkeyVersion.  Search for it in the API doc.

    You can also use isGlanceModeEnabled to see if you were started from a glance.  You might want to use this instead of monKeyVersion, as there are devices where glances are optional and can be turned on or off by the user.;

  • EDIT: TL;DR In the absence of further info, isGlanceModeEnabled does *not* indicate that your app was started from a glance. It only tells you one of two things: your app was launched as a classic full-screen widget, or it wasn’t. (But on newer devices, the latter scenario includes either launching from glance or launching from activity/app launcher.)

    My reasoning:

    - If isGlanceModeEnabled is unavailable, it means you’re on an old device which doesn’t even support glances

    If isGlanceModeEnabled is false, it means you’re on a “glance-optional device” with glance mode disabled:  it doesn’t support super apps, it does support true widgets, and any widget will be launched in “classic widget mode” (as opposed to glance mode)

    - If isGlanceModeEnabled is true, it means one of two things: you’re on a newer super app device (so it’s always true), or you’re on a ”glance-optional device” with glance mode enabled (any widget will be launched in glance mode)

    So really, isGlanceModeEnabled (on its own) is only reliable for telling you whether your widget/app-with-glance was launched as a classic widget or not. To simplify:

    isGlanceModeEnabled = false (or unavailable) => your widget was launched as a classic widget (not a glance)

    isGlanceModeEnabled = true => (super app devices) no information; (non-super app devices) your widget was launched as a glance. In the absence of further checks, this only tells you that your app was *not* launched as a widget.

    You can also use isGlanceModeEnabled to see if you were started from a glance.

    You’ve used the phrasing before and it’s not quite right. On devices with super apps (CIQ 4+), any app with a glance can also be started from the activity/app launcher, which has no effect on the value of DeviceSettings.isGlanceModeEnabled, which means that it can’t actually be used to detect “if [your app was] started from a glance”.

    The actual situation is that isGlanceModeEnabled will be present and true if the device supports glances and glance mode is enabled, which is not quite the same thing as saying that a given app was started from a glance.

    Furthermore, isGlanceModeEnabled is actually not useful on devices which support super apps, since it will always be true for these devices (none of these devices has the ability to turn off glances and return to the old “true widget” mode; they don’t even support true widget app types.)

    isGlanceModeEnabled is really only useful on older devices which:

    - support actual widgets (as a distinct app type from device apps)

    - support glances

    - support the ability to turn off glances

    isGlanceModeEnabled is actually only 100% useful when you develop a widget for these older devices, or if you assume the user has no interest in launching your app-with-glance from the activity/app launcher (or you don’t care to distinguish between that scenario and the scenario where the app is actually launched from a glance.).

    As discussed in this thread which covers this very topic, the true way (on newer devices with super apps) to detect if your app was launched from a glance is:

    In the SDK, core topics file there is an example of how to check if an app was launched from the glance.

    https://developer.garmin.com/connect-iq/core-topics/application-and-system-modules/#launch

    you can check the state in the onStart function for the :launchedFromGlance object.  It if exists and is true, then the app was launched from the glance view, otherwise it was not.  The link above has an example or more detail in the onStart method in the API reference.

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Application/AppBase.html#onStart-instance_function

    To handle both old and new devices I think you’d need to use both approaches (the doc isn’t explicit on this, but it’s implied that :launchedFromGlance only applies to super app devices):

    - new devices (have super apps; there are no true “widget-only” apps — any app with a glance can also be launched from the app launcher):

    check :launchedFromGlance in onStart()

    - old devices (have true widgets, which can only be launched as a widget/glance):

    check isGlanceModeEnabled

    You might want to use this instead of monKeyVersion, as there are devices where glances are optional and can be turned on or off by the user.;

    I do agree with this. If isGlanceModeEnabled is missing (as per has check), then the device doesn’t support glances. If isGlanceModeEnabled is false, then glances are disabled, and if it’s true, glances are enabled.

  • Which method can I use to detect the API version?

    As discussed above, it’s probably not the correct approach for detecting whether your app was launched from a glance.

    But in general, use System.getDeviceSettings() and inspect monkeyVersion in the returned DeviceSettings object.

  • I do agree with this. If isGlanceModeEnabled is missing (as per has check), then the device doesn’t support glances. If isGlanceModeEnabled is false, then glances are disabled, and if it’s true, glances are enabled.

    Without having read your message, I already did the following check:

    if ( ! ( settings has :isGlanceModeEnabled ) || ! settings.isGlanceModeEnabled ) {
        // return overview widget
    }

    On devices that support glances but they are turned off, does it make sense to return this kind of "overview widget" as on the older devices without glances? Or can they directly display multiple views, so I can just proceed with presenting multiple views?