Refresh the data field

Hello,

I'm new in the Garmin world, so perhaps my question is a litle but stupid... Let me know...

I have wrote a DataField that made exactly want I want on my new fenix 6x pro and I wanted the add some custonization.

For that, I add the the AppBase a function getSettingsView that allows the user to change some settings, as color for example. I put the color choosen in the Storage

My question is, how it's possible to refresh the data field to have the new color choosen ? The onSettingsChange function in the AppBase is never called...

And make, in the data field onUpdate method, a call to get from the Storage the new color is, I think, not a good idea...

Somebody can help me ?

Thanks you

Frédéric

  • In the sim, under settings is "trigger app settings".

    Understand the way you are doing only works on CIQ 3.2 devices  You can use traditional app settings, where you use a phone or Garmin Express to make changes - that can be used on all devices that support CIQ.

  • The "trigger app settings" is used in the simulator to open the view setted in the getSettingsView I guess. So, for that, it's ok. The problem is after, how can I refresh the data field when my choice is done ?

    Do you have an example with the traditional app settings ?

    Thanks you

  • The objest store same in the sdk shows it, or if you pick a watch face in the eclipse templates ("New>Ciq Project in eclipse), you can pick "With settings" and you can see it there.  That's the onlu way "OnSettingsChaged" is called.  Not by using on-device settings.

    As far as what you are doing, sounds like you need to read storage in your nain view to pick up the change.

  • I think the idea here is Fredo doesn't want to read storage in the main view because that might be slow.

    To avoid reading storage once per second in the data field's main view, I would:

    1) Store a copy of settings in the app class. (This could either be in primitive member variables or in a dedicated settings class, depending on how much memory you have to play with, and how "nice" you want the code to be). (Classes consume more memory, obviously). Initialize this copy of settings from storage, when the app starts.

    2) in the view returned by getSettingsView(), when saving the new color, also save it to the copy in app class. You could access the app instance by using getApp(), or maybe getSettingsView() could pass in the settings class to the settings view (if you decided to go that route).

    3) In onSettingsChange(), the code which reads the new color should also save it to the copy in the app class.

    4) In the data field view's onUpdate() implementation, read the current color from the app class.

    This should avoid reading from storage every second -- it will only read from storage when settings have actually changed.

  • 3) OnSettingsChanged is not called for on device settings.

    On top of that, on device settings in the sim works differently that on a real device. in that there, the app actually gets restarted after the change is applied.

  • What I do for on device settings is this.  I have a classs  that loads and maintains the settings at start up.  Then in the delegate for the setting menu, I have things like this:

    if(id.equals("mov")) {
    MySettings.showMove=!MySettings.showMove;
    MySettings.writeKey(MySettings.showMoveKey,MySettings.showMove);

    }

    Then in onUpdate, I just check the value of MySettings.showMove.

    No real need to read storage each time, but for a new dev, might be easier.

    The

    MySettings.showMove=!MySettings.showMove;

    handles the local value and the call to MySettings.writeKey() takes care of updating Application.Storage.

  • 3) OnSettingsChanged is not called for on device settings.

    I understand that. I am talking about writing an app that can handle both CIQ 3.2 and non-3.2 devices. Sorry I didn't make that clear.

    On top of that, on device settings in the sim works differently that on a real device. in that there, the app actually gets restarted after the change is applied.

    EDIT: The crossed-out text below is based on a misreading of the above quote ^.

    Does the app *always* get restarted after onSettingsChanged() (i.e. for a data field)? If that's the case, then:

    - I don't see the point of the existence of onSettingsChanged() at all. (If the app restarts, it'll most likely read settings at init time anyway). Why have an event handler which is going to get called just before the app unconditionally restarts?

    - I don't see how a data field could properly handle settings changes during an activity (if you push a settings change, that could mess up the internal state of the data field. For example, suppose you have a data field which is calculating lap or average metric data; if that gets restarted during the activity, that information would be wiped out.)

    - Why do settings changes result in a data field memory spike, which sometimes causes the settings to not be applied? (Which is a well-known issue.) If the data field always restarts, wouldn't it make more sense to apply the change in between shutdown and restart, which would avoid the memory spike and associated bug?

    What I do for on device settings is this.  I have a classs  that loads and maintains the settings at start up.  Then in the delegate for the setting menu, I have things like this:

    if(id.equals("mov")) {
    MySettings.showMove=!MySettings.showMove;
    MySettings.writeKey(MySettings.showMoveKey,MySettings.showMove);

    }

    Then in onUpdate, I just check the value of MySettings.showMove.

    No real need to read storage each time

    Yep, that's pretty much what I suggested.

    but for a new dev, might be easier

    But the OP was specifically asking for a solution that does not read from storage every time because they don't think it's a good idea. (And I don't either, assuming that Storage is slow and reads aren't cached.)

  • onSettingsChanged is used with traditional all settings.  Using the code I show above, there I would have

    function onSettingsChanged() {

      MySettings.load();

      Ui.requestUpdate()

    }

    So I load the settings into the MySettings Class if they have changed.

    The initialize() function for MySettings is just basically

    function initialize() {

      load();

    }

  • Yes, reading from storage each time onUpdate() is not a good idea, but it will work.  I myself would probably stick with traditional app settings for a DF, both for compatibility with devices, and to eliminate the chunk of code needed for on device settings.

  • onSettingsChanged is used with traditional all settings.

    Thanks, but my question referred to this:

    On top of that, on device settings in the sim works differently that on a real device. in that there, the app actually gets restarted after the change is applied.

    Now I realize I misread what you said. I thought you were saying that the app restarts after onSettingsChanged() (which would make no sense), but now I see that you're saying the app restarts after on device settings are changed, which isn't great IMO.

    Are you saying that the restart happens in the sim or on the real device? If it happens on the real device, then it seems like it would really limit the usefulness of on device settings. For example, I wanted to use it to implement an interactive lap history view, but that obviously won't work if the app restarts once the view is exited.