How to make an alert when mobile data is not available?

Hello.

Is there a way to make a short message on the watch when I turn off the connection (mobile data)?

I'm using OWM data, currently I'm using

if (!System.getDeviceSettings().phoneConnected) , but this only solves the problem with BLE.

I still need to solve

var Settings = System.getDeviceSettings();

if (Settings has : connectionAvailable) {.

Or if there is a better way, for example Communications.makeWebRequest?

Then please give an example of how to solve this problem.

Thank you

  • Is the problem here that connectionAvailable is only available starting with CIQ 3.0?

    Afaik the only LTE-enabled CIQ watches are fr945lte and vivactive3mlte, both which have CIQ > 3.0.

    So it seems that you can use DeviceSettings.connectionAvailable or DeviceSettings.connectionInfo for your use case, without any problems.

    If you're looking for a solution that also involves makeWebRequest, it seems you could also check the status code in the callback for BLE_CONNECTION_UNAVAILABLE. Despite the name of the enum, I assume that it refers to *any applicable* connection being unavailable, including BLE, Wi-FI, and LTE.

  • Hello, is it possible to please suggest - show a part of the source code that would solve my question? As I mentioned, what I am currently using does not work very well for me and it evaluates the connection via BLE rather than a shutdown, a data connection failure.

    I would like to implement this via Communications.makeWebRequest when, for example, I am calling a weather update at regular time intervals.

    Thank you for your help

  • You already posted the beginning part of your own solution, which is why I was kind of confused about what exactly your problem is. You identified that connectionAvailable is the solution to your problem, which it is.

    btw, it's interesting that you are asking for example source code to a solution while not really providing too many details about what you are doing and how you are doing it. For example, I have to make an educated guess that this is a watchface.

    Correct me if I'm wrong, but you already have code which looks like the following *somewhere*. [Maybe in onUpdate()? Again, you didn't say anything, so I have to guess.]

    if (!System.getDeviceSettings().phoneConnected) {
      // do something to alert user
      ...
    }

    Like I said, connectionAvailable  is available starting with CIQ 3.0.

    You also mentioned that you want to detect when mobile data (LTE) is turned off. Again, the only Garmin watches that I know of which support mobile data are 945 LTE and VA3 music LTE, which both have CIQ >= 3.0, which means they both have connectionAvailable. In other words, every watch which has LTE connectivity should also have connectionAvailable.

    So all you have to do is modify your original code to use either connectionAvailable, when it exists.

  • For example, you could replace the original code above with something like this:

    Note that I don't know exactly when your original code checks phoneConnected, and I don't know what it does when phoneConnected is false (since you didn't tell us either of those things), so my solution assumes you will simply replace the original check with new check, without changing any of the other logic.

    Or if there is a better way, for example Communications.makeWebRequest?

    It's hard to say which way is "better":

    - you didn't describe exactly what you are currently doing. Yes, you said you look at phoneConnected, but you don't explain *when* you look at it or exactly what you do when it's false.

    - you didn't explain what your goal is: do you want to inform the user immediately, when the connection is lost? or do you want to inform them only when makeWebRequest fails? how would you inform the user? would you show a toast? change an icon on the watchface? draw some text on the watchface? Again, you didn't even say whether this is a watchface or not

    - you don't explain exactly how you are using makeWebRequest. Yes, obviously you are using it retrieve OpenWeatherMap data, and assuming it is a watchface (again, I don't know if it is), then makeWebRequest must be called in a background process. If it is called in a background process, the code in your background process must have a way to return the OWM data to the foreground. Does your background code also have a way to return errors to the foreground?

    Without a slightly more detailed example of *your* code, and an explanation of exactly what you want to accomplish, it's hard to give advice or examples here.

    For example, I could say that maybe it would be better to check the status code returned by makeWebRequest in the callback, to see if it's equal to BLE_CONNECTION_FAILED. As a matter of fact, I already said that above. However, I have no idea whether that's better for you.

    Maybe I could give you example source code, but again I'm not sure how much that would help you, given that it might not resemble your own code at all.

    If you would post a stripped-down example of your source code which shows how you are using makeWebRequest in the background, how you return the data to the foreground, and how the foreground handles the data it receives from the background.

    TL;DR it would actually be easier if you:

    - gave some idea of what you want

    - gave an example of *your* code (doesn't have to contain too many details), so we could try to help you modify it to do what you want

  • Sorry for the incomplete information and I will try to fix it. This is a watch face (WF), for Garmin F6. when do I want to check?

    I have the source code Weather.drawable in Layout, where I get weather data, for example the current temperature. What I would need is that before the weather data is loaded, some function evaluates whether the phone is connected to a data connection. If so, the weather data is loaded via the draw.weather(dc) function. I call the weather data via:

    function onBackgroundData(data) { so the WF.App file.

    I have it like this. I am not at the PC right now, so I can't write more about it...

  • function onReceive(responseCode as Number, data as Dictionary) {
    if (responseCode == 200) {
    Background.exit(data);
    } else {
    Background.exit(null);
    }
    }

    }

  • Thanks for the clarification!

    From what you've shown, your background process will only return data if the OWM request was successful. (If you pass null to Background.exit(), onBackgroundData won't be called in the foreground.)

    So it seems that you are already able to display weather data in that case. Is that correct?

    It seems that what is missing is the ability to alert the user when the OWM request fails, due to lack of connection.

    What you could do is have the background process return an object that contains both the data and the responseCode from onReceive (makeWebRequest's callback). The foreground process would look at responseCode to determine if anyone went wrong.

    e.g.

    (I assume that a response code of BLE_CONNECTION_UNAVAILABLE would also apply to Wi-Fi and LTE, since there's no other enum which refers to an unavailable connection.)

  • Here's a trick I've used for years.

    Where you have

    Background.exit(null);

    (which means onBackgroundData won't get called) I have

    Background.data(respsonseCode);

    Then in onBackgroundData, I use

    if(data instanceof Number) ....

    to see if there was an error, and if there was, I have the actual code and can react accordingly, with a -104 being there's no connection, but there are others - for example, if the server is down or there was a timeout

    I also use the same logic in the background service for things like OWM when I don't have a location or a bad or missing APIKEY, which then will show in the main app.

  • So I'll try to summarize and put things in the right place.

    Now I know that there are multiple solutions to evaluate the connection status (mobile data, Wi-Fi).

    Is what user jim_m_58 said meant like this?

    Code:

    It's a shame that more details aren't given about this solution, so that one can see an example and the difference compared to what user FlowState described.

    But the question remains how to solve it so that it is possible to trigger a message based on the responseCode, for example:

    responseCode == 404,

    msg = InvalidLocation.

    some concrete example would really help me.

  • No, what jim_m_58 meant was something like this:

    The two solutions are similar, except my solution always returns the same type of object (a dictionary with keys :responseCode and :data), whereas jim_m_58's solution returns a different type based on the outcome (on failure, the error code is returned as a number, and on success, the data from OWM is returned as a dictionary).

    But the question remains how to solve it so that it is possible to trigger a message based on the responseCode, for example:

    responseCode == 404,

    msg = InvalidLocation.

    some concrete example would really help me.

    But again you are asking for concrete examples of a solution without showing us concrete examples of *your code*, or describing exactly what you want to do.

    When makeWebRequest fails:

    - do you want to display a message on the watchface itself? if so, will the message cover the whole watchface temporarily (perhaps a bad user experience), or will it perhaps be displayed in the part of the screen which would normally display weather info (so there's not much room to display an error message)

    - do you want to perhaps display some kind of error icon where the weather info would be?

    - do you want to display a toast? (perhaps also a bad user experience, especially if the error happens regularly). I think a toast would only be appropriate for a very rare error message which either the user really needs to know about and/or there is something they can do to address it.

    some concrete example would really help me.

    Do you want us to write your code for you?

    The idea is fairly simple:

    - onBackgroundData() receives the responseCode and the OWM data from the background process

    - Clearly you already know how to convey the OWM data to the watchface view, so that the view can display weather information

    - Use the same or similar technique to convey the responseCode to the view

    It's confusing to me that you say you already have stuff that works, but you cannot extend the already working code to handle new, but similar functionality. For example you make it sound like you are already displaying weather data on your watchface, but you seemingly cannot display an error on your watchface without a concrete example. It's the same idea except *you* have to decide how to display the error. If you cannot even describe how you want the error to be displayed (and in what situations), others cannot even begin to provide concrete examples with details.

    Here's an *outline* of the solution. It's up to you to fill in the details.