Test if running on simulator

Former Member
Former Member
Is there any way from monkeyc to test if the program is running on the simulator or on real hardware so I can initialize some data differently?

Thanks,

Dave.
  • But you need to do this for each app.

    The above only needs 1 manual action every time you reset the simulator

  • That's true, but potentially a positive if you need a switch on a per app basis. For my use case where my simulator detection dictates whether I use a fake BLE interface or the real one, sometimes I want to actually use the real one (with the nRF52840 dongle). If you were developing multiple apps and needed to sometimes turn the simulator detection off, it would be annoying/less convenient to have to reinstall the token app for one app and have to uninstall it for another.

    Anyway, come on Garmin, give us System.isSimulator()!

  • Yeah, but for that (sort of) I use const based on monkey.jungle. In my case my datafield connects to an ANT heart rate monitor. Which it does happily from the simulator using the USB ANT dongle, but sometimes I do want to do something where I prefer it to have a "mock", where the HR just changed by -1/0/+1 every second randomally. For this "occasion" I just change this mock annotation in the monkey.jungle.

    However if there would be something that would need to be always different in an app when I run it in the simulator, then probably I'd use the isAppInstalled trick.

  • Why can't you just set your own Boolean in your app?  You're saying that sometimes you want to simulate BLE and other times, you want to use BLE with the dongle, so that already means your app needs to change in some way.  By the way, in the years I've done BLE I always just use a real connection, as trying to simulate that can induce it's own problems IMHO.

  • Because if I just use a Boolean, then when I go to make a commit to source control I have to either be careful to exclude its changed value in the commit, or revert the change to its default. This is both annoying and potentially problematic if I forget. Also if it's a runtime setting, the same build that I test in the simulator can be side loaded to a real device; I don't need to rebuild and/or get mixed up over which build is for testing and which one is "real".

    Always connecting to a real device is all very well if physically possible, but in my case said device is basically permanently fixed to my bicycle, so unless I resort to coding on a laptop in my cramped garage, simulating the interface is the better option for me. Believe me, I would use the real thing all the time if I could.

  • If you were developing multiple apps and needed to sometimes turn the simulator detection off, it would be annoying/less convenient to have to reinstall the token app for one app and have to uninstall it for another.

    Anyway, come on Garmin, give us System.isSimulator()!

    Not to state the obvious, but the same argument about needing to turn off simulator detection with my method similarly applies to a hypothetical System.isSimulator() function. In the case of System.isSimulator(), in order to turn off simulator detection, you would probably need to comment out the function call in your app code. It's not like Garmin is going to give devs a checkbox in the simulator along the lines of "pretend this app is running on a real device".

    In other words, any reasonable implementation of System.isSimulator is most likely not going to give you what you say you want (a way to easily turn off simulator detection without changing code).

  • when I go to make a commit to source control

    The person you're replying to doesn't believe in source control. He's publicly said that ERA reports (crash logs) for old app versions are useless, because your source code might have changed between the old version and the current version....

    I have to either be careful to exclude its changed value in the commit, or revert the change to its default.

    How about this? Create a "transient" resource file which is *not* committed to source control - give it a distinctive name like resource-nocommit.xml, and add its name to .gitignore / exclude it from whatever source control provider you use.

    Add a boolean property with a name like "isTesting" to the resource file. Set this property to true when you want to put your app into testing mode.

    In your app code, implement isTesting() as follows:

    function isTesting() as Boolean {
        // Properties.getValue() throws an exception if the specified key does not exist
        // in properties xml.
    
        // Note that the API doc incorrectly says "settings xml",
        // but this is incorrect. See:
        // https://forums.garmin.com/developer/connect-iq/i/bug-reports/doc-sim-behavior-for-properties-getvalue-key-setvalue-key-is-inconsistent-regarding-whether-key-needs-to-be-present-in-app-properties-or-settings
    
        try {
            if (Properties.getValue("isTesting") == true) {
                return true;
            }
        } catch (Exception e) { }
    
        return false;
    }

    Ofc that doesn't help you when you want to sideload or deploy your app.

    A way around that could be to:

    - put the "transient" resource file in a special resource folder that is normally not included in the build [e.g. "resources-testing"]. It's ok to commit this folder and its contents to source control

    - create a script file [or makefile] which builds your project with an additional jungle file that overrides the resource to add "resources-testing"

    - whenever you want to build your app in "testing mode", run the script [or invoke the appropriate target in the makefile]

  • "In other words, any reasonable implementation of System.isSimulator is most likely not going to give you what you say you want (a way to easily turn off simulator detection without changing code)."

    It would be a part of the solution, and besides it would be useful for other purposes. It just seems like such a simple thing that would be trivial to implement, and there is evidently a demand for it.

    Your file token solution is a good one, although again, probably over-complicating things for my purposes; just using a Storage variable seems to be working out fine.