(for details on these, see the programmer's guide in the SDK and the sample code)
There are a few different ways, and it depends a bit on what you need to do.
using resource overrides, you can just have different layouts based on the specific device. This can handle many things. If you still need a specific device, you can have a string in each override with details, such as:
<string id="device">Fenix3</string>
You load the "device" string at runtime and compare it, so if you built for a Fenix5, that would be in a string, vs Fenix3.
You can also use Build file Exclusions, have different source files based on device, or use annotations to decide what in the code gets built.
Another option (one that I often use) figures things out at runtime, The way I do that is in layout, I figure out the device I'm on (or at least as close as I need).
There you can get things like width (dc.getWidth()), height (dc.getHeight), screen shape (sys.getDeviveSettings().screenShape), etc.
if you only want to know f3 vs f5, both are round, but the f3 has a width/height of 218, while the f5, 240. 218x218 would also include the d2, f3-hr, etc but it would also include the Chronos and f5s, so you may have to refine the guess based on the height if a specific font, or the version of CIQ on the device (the f3/f3hr/d2 are CIQ 1.x.x, while the chronos and f5s, 2.x.x.)
This won't give to a specific device, but for example, on semi-rounds, you may not need to know, as the screens/fonts are all the same.
When it comes to specific things being available on a device, "has" is very useful. You can determine things like if ActMon.getHeartRateHistory() are available (it's only on devices with a WHR), so in the case of a f3 vs a f3hr, the screens and fonts are the same, but one has an OHRM and one doesn't.
Great post Jim. I had not thought of a couple of those ideas. It would be nice if there was somewhere that tips like this could be saved. We could do with some kind of connectiq wiki which people could contribute to.
Thanks gasteropod! (and I was still on my first cup of coffee for the day!)
One thing I didn't mention, is how to handle input, as you have things like touch vs non touch, and things like on the Oregon and Rino, no start/enter button. The simple answer is I don't really need to think about it.
For example, if you treat KEY_UP and KEY_DOWN the same as directional swipes, the same code works in both cases. In the case of the Oregon/Rino, I do have a test based on the things I mentioned doing in onLayout(), where I draw a screen button, and the delegate knows it's location, and if it sees a tap in that area, it gets treated like KEY_START/KEY_ENTER.
One other thing worth mentioning is the Fenix Cronos (at least today - might not be an issue with an SDK update that reflects the chronos with the f5s fonts and a min FW version that only allows the "f5s" version of the FW). The 2.x FW uses fonts like the f3, while the beta FW (It may become the production any day now) uses fonts like the f5s. The CIQ sim right now uses the f3 like fonts for the chronos, and with layouts, the .prg will assume the f3 fonts. Knowing that you're on a Chronos won't help (like putting a string in a resource override).
In that case, after I know I'm on a round with a 218x218 display (determined in onLayout()), and by checking the height of a single font, the code knows if it should be treated as if it has f3 like fonts or f5s like fonts. The specific version of CIQ possibly could be used, but the chonos is 2.x.x in both cases so it would have to be a more refined check that just 1 vs 2.
Today, if a user downloads one of my app on their chronos, that app adjusts for the difference, and if they update their FW, the same .prg should run just fine but with the different fonts.
I was a little surprised to see that they were going to be changing the fonts on the chronos mid life of the watch as I am sure this will break the layout of some apps. Thankfully I noticed this and was able to code my app in a way that it will look the same using either new or old font set.