In App Device Detection

Former Member
Former Member
Is it possible to detect which device the app is running on? I would like to change on screen text prompts so that they reflect correct input methods for the given watch.
  • Yes, but I'm not sure that is the right solution to the problem, but it is in the right area.

    If you want the screen prompts to vary by device, just create a device-specific resource file and put string resources in there. For example, in resources-fr920xt/strings.xml, you could do this...

    <resources>
    <string id="Instructions">Press Up/Down to Navigate</string>
    </resources>


    and in resources-vivoactive/strings.xml, you could use...

    <resources>
    <string id="Instructions">Swipe Left/Right to Navigate</string>
    </resources>


    Then in your code, you just do this

    class MyView extends Ui.View
    {
    var instructions;

    function onLayout(dc) {
    instructions = Ui.loadResource(Rez.Strings.Instructions);
    }
    }


    That said, if you use a layout, you can hard-code the label strings and their on-screen positions on a per-device basis. If you really feel that you need to know what device you are using, just make a string entry that is the name of the device model, and then check for that in your code...

    class MyView extends Ui.View
    {
    function onLayout(dc) {
    var device = Ui.loadResource(Rez.Strings.Device);

    if ("fr920xt".equals(device)) {
    // this is a 920
    }
    }
    }


    That said, I'd recommend against doing it this way unless you really have to. It requires various parts of your code to know what device they are running on, which can be problematic when adding support for additional devices. If you use layouts, everything that is specific to the device ends up in the device-specific layout file. Unfortunately, the cost of using a layout is pretty high (4kB for a layout with a background, some lines and 8 labels in my testing). IMO the cost is worth the benefit in many cases, since porting to a new device requires only editing a single file.
  • Former Member
    Former Member over 10 years ago
    Currently there isn't an API to do this. You can override a string using device qualifiers similar to how you would use language qualifiers. If you include the device prompt strings as string resources you could override them for each device.

    resources-fenix3/strings.xml <- base language strings for fenix 3
    resources-fenix3-spa/strings.xml <- Spanish strings for fenix 3
    resources-fr920xt/strings.xml <- base language strings for 920
    resources-fr920xt-spa/strings.xml <- Spanish strings for 920
  • Ken - feature request - what if there was a way to know in something like system>device settings. A simple method with an ENUM, with that value being negative, to indicate that you're also in the simulator?
  • That said, I'd recommend against doing it this way unless you really have to. It requires various parts of your code to know what device they are running on, which can be problematic when adding support for additional devices. If you use layouts, everything that is specific to the device ends up in the device-specific layout file. Unfortunately, the cost of using a layout is pretty high (4kB for a layout with a background, some lines and 8 labels in my testing). IMO the cost is worth the benefit in many cases, since porting to a new device requires only editing a single file.


    I tend to avoid specific tests against device types where possible, but do have a generic resource string "DeviceForm" (values rectangle or round) that I test against in my onUpdate code. I have taken the opposite approach than Travis, and calculate the position and size of all display elements on the fly (or in the onLayout method). This way I don't have to maintain multiple layouts but the downsize is that I cannot small the small pixel adjustments for specific devices.

    /Tonny
  • Former Member
    Former Member over 10 years ago
    Ken - feature request - what if there was a way to know in something like system>device settings. A simple method with an ENUM, with that value being negative, to indicate that you're also in the simulator?


    I'm guessing we won't add a flag that says if you're running on the simulator or not but if you can make a strong argument for having this flag I'll certainly file a request to do so. We'd rather improve the simulator to match the device as close as possible so there really shouldn't be a reason to have one.
  • Ken - right now, there is no way to toggle phoneConnected in the simulator (it's always false). I have a widget that uses that to avoid calling makeJsonRequest() and display a simple message instead. If the widget knew it was in the simulator, it would know that it had to work a bit differently.

    Granted that the simulator will probably change to allow toggling phoneConnected, but there could be other things like this, and waiting weeks for the simulator to be fixed could be a pain.
  • Former Member
    Former Member over 10 years ago
    If the widget knew it was in the simulator, it would know that it had to work a bit differently.

    The point behind this would be to add code to your project which - in production - shouldn't be there. I think I saw in the other thread you started that someone proposed a solution to accomplish what you're trying to do. That's probably your best bet for now.

    Granted that the simulator will probably change to allow toggling phoneConnected, but there could be other things like this, and waiting weeks for the simulator to be fixed could be a pain.

    There is an issue open to add phoneConnected to the simulator (on top of some other settings). Adding this flag in would ultimately take time away from other improvements which is why I don't see it being added.

    Ultimately I think you have a point and I'll file a request but I wouldn't hold my breath if I were you.
  • Thanks Ken. I think it would be useful until the simulator matures a bit more. And using the method to set a local boolean should have little impact, even if it's left in a production version.
  • class MyView extends Ui.View
    {
    function onLayout(dc) {
    var device = Ui.loadResource(Rez.Strings.Device);

    if ("fr920xt".equals(device)) {
    // this is a 920
    }
    }
    }


    Does this work on the simulator?
    I am going down a rothole on this and I don't want to use Layouts.xml (i've already hardcoded the layout into the code and I rather not do thing again :-p tho it would theoretically be better in the long run)

    I tried the above trick in the simulator (still run a a Vivoactive) but the device string is a fenix3 and it the sim still comes up as a VA device. (is it cause I specifically specified it to be run as a VA?)

    I want to know if it will do the same thing on an actual device.

    currently my code is looking at the height / width as the differntiator for the layout.
    BUT... there is a snag which is pixel by pixel placement is not possible due to the diff fonts that's used across the diff devices.

    VA
    <font id="xtiny">Roboto 12</font>
    <font id="tiny">Roboto 12</font>
    <font id="small">Roboto 12</font>
    <font id="medium">Roboto 17</font>
    <font id="large">Roboto 20</font>
    <font id="numberMild">Roboto 20 Number</font>
    <font id="numberMedium">Roboto 32</font>
    <font id="numberHot">Roboto 38</font>
    <font id="numberThaiHot">Roboto 62</font>

    920xt
    <font id="xtiny">Digi 12</font>
    <font id="tiny">Digi 12</font>
    <font id="small">Digi 12</font>
    <font id="medium">Digi 17</font>
    <font id="large">Digi 20</font>
    <font id="numberMild">Digi 20</font>
    <font id="numberMedium">Digi 32</font>
    <font id="numberHot">Digi 38</font>
    <font id="numberThaiHot">Digi 62</font>

    Epix
    <font id="xtiny">Roboto 12</font>
    <font id="tiny">Roboto 12</font>
    <font id="small">Roboto 12</font>
    <font id="medium">Roboto 17</font>
    <font id="large">Roboto 20</font>
    <font id="numberMild">Black Diamond 20</font>
    <font id="numberMedium">Black Diamond 32</font>
    <font id="numberHot">Black Diamond 38</font>
    <font id="numberThaiHot">Black Diamond 62</font>

    F3
    <font id="xtiny">Roboto 12 Bold</font>
    <font id="tiny">Roboto 14 Bold</font>
    <font id="small">Roboto 17</font>
    <font id="medium">Roboto 19</font>
    <font id="large">Roboto 24 Bold</font>
    <font id="numberMild">Steelfish 22</font>
    <font id="numberMedium">Steelfish 40</font>
    <font id="numberHot">Steelfish 54</font>
    <font id="numberThaiHot">Steelfish 75</font>
  • Does this work on the simulator?

    Yes, it works on the simulator. I have noticed that the value for Device will be incorrect for the first time the simulator has executed, but running the sim again will resolve that issue. Other than that, if it doesn't work for you, then you're doing it wrong.

    If It doesn't work, the problem is most likely that you don't have resources for each device that you support. You need to define Device in a resource file in resources-vivoactive and in resources-fenix3. It is probably a good idea to define it in a resource file in the resources folder as well.

    Travis