Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

JPeg API quick question

ANSWERED

No examples are provided and I am doing some error tracing.  Is this line written correctly?  myImage.href is assigned a .jpg file.

 

 

 jpeg.decodeSync(myImage.href, "/resources/default.txi", delete=true);

Thanks

 

Best Answer
1 BEST ANSWER

Accepted Solutions

Yes. Here's snippets from something of mine:

function saveState() {
  let state = {"progressReadingFormat": progressReadingFormat, "heartReadingFormat": heartReadingFormat};
  filesystem.writeFileSync("state.txt", state, "json");
}

function loadState() {
  let state;
  try {
    state = filesystem.readFileSync("state.txt", "json");
  } catch(err) {
    return;
  }
  if (state.progressReadingFormat !== null) progressReadingFormat = state.progressReadingFormat;
  if (state.heartReadingFormat !== null) heartReadingFormat = state.heartReadingFormat;
  if (progressReadingFormat === readingFormatEnum.TRACK) {
    energyGauge.setTrackMode(true);
    distGauge.setTrackMode(true);
    activeGauge.setTrackMode(true);
  }
}

Obviously you want to call loadState() when your app starts (but after you've initialised relevant state variables to default initial values).

 

You probably want to call saveState() whenever any state variable changes. In theory, this could be deferred until your app is closed, but that slows down the app transition process which can make users complain.

 

In retrospect, I should probably just have kept all the state variables in the state object throughout the app, rather than creating and unpacking the state object as above.

 

And on terminology: I used the term 'state' to differentiate between 'settings' because the latter has a specific meaning. Some of your state variables may indeed correspond to companion-based settings, but others may only exist on the watch.

 

This would be a good candidate for a design pattern. I should tart it up and github it.

Peter McLennan
Gondwana Software

View best answer in original post

Best Answer
12 REPLIES 12

Also tried that with no luck as well. It also sucks that you can't dynamically load PNGs. JPEGs don't support alpha channels I was hoping converting it to TXI can do something about it.

Best Answer
0 Votes

You can do some simple transparency stuff like this:

https://dev.fitbit.com/build/guides/user-interface/svg/#mask

 

If your needs aren't too fancy, that may suffice.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Catplace,

 

Thank you for the suggestion, but I don't think that will do what I am trying. 

 

The background image of my clockface can be selected by the user.  The system re-loads the image on each start-up if the Ionic is talking to the phone.  The problem comes with the sync dependability or availability of the phone.  As a stand alone watch (no comms with the phone...like in airplane mode), I have a pre-defined image which loads up.  I was trying to come up with a way to store this image without converting from messaging to file transfer for data transfer.

Best Answer
0 Votes

If your predefined image is baked into your watch app, it shouldn't need storing separately. Even uploaded images (eg, done with file transfer) remain on the watch unless explicitly deleted or the app is uninstalled.

 

Perhaps you just need to save some state info on the watch so it knows what filename to look for (assuming that's variable), when comms are not available.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

That the last selected image would be retained on the watch was also my assumption.  I do store the  available images on the watch (under the resources folder).  What I have found is that if the watch does not have a connection with the phone (like in airplane mode), the watch fails to load the last selected background image.  Currently, I give it a default image that it 'fails' to.  What I was wanting to do was to use this function to convert the jpeg into "default.txi". 

Best Answer
0 Votes

Are you sure the issue is that the file is missing, and not that the chosen filename (presumably stored as a JS variable) is missing? Whenever an app restarts (eg, after any other app has been run), all its local variables will be undefined; in this regard, it's as though the app were being run for the first time. If you want any variable (eg, usersSelectedFilename) to pick up the value it had previously, you have to explicitly write code to do so.

 

Files are retained across restarts; variables are not.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

It is the variable defined in the settings that is losing its' value with the re-start.  That is why I am trying to create the .txi file from the returned variable (which contains the file name).

Best Answer
0 Votes

Then I think there are easier ways to do what you want. Perhaps easiest would be to rename the user-selected .jpg to something like chosen.jpg, then always display the file with that name.

 

But I still feel that the most elegant solution is to save any necessary state variables (eg, the chosen filename) in local storage whenever they change, and restore them from local storage (if found) whenever your app starts. This would avoid renaming files, which could get messy if the user changes their preference.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Okay...So then how do you save a variable to local storage?  Are you talking about using the writeFileSync or a different function?

Best Answer
0 Votes

Yes. Here's snippets from something of mine:

function saveState() {
  let state = {"progressReadingFormat": progressReadingFormat, "heartReadingFormat": heartReadingFormat};
  filesystem.writeFileSync("state.txt", state, "json");
}

function loadState() {
  let state;
  try {
    state = filesystem.readFileSync("state.txt", "json");
  } catch(err) {
    return;
  }
  if (state.progressReadingFormat !== null) progressReadingFormat = state.progressReadingFormat;
  if (state.heartReadingFormat !== null) heartReadingFormat = state.heartReadingFormat;
  if (progressReadingFormat === readingFormatEnum.TRACK) {
    energyGauge.setTrackMode(true);
    distGauge.setTrackMode(true);
    activeGauge.setTrackMode(true);
  }
}

Obviously you want to call loadState() when your app starts (but after you've initialised relevant state variables to default initial values).

 

You probably want to call saveState() whenever any state variable changes. In theory, this could be deferred until your app is closed, but that slows down the app transition process which can make users complain.

 

In retrospect, I should probably just have kept all the state variables in the state object throughout the app, rather than creating and unpacking the state object as above.

 

And on terminology: I used the term 'state' to differentiate between 'settings' because the latter has a specific meaning. Some of your state variables may indeed correspond to companion-based settings, but others may only exist on the watch.

 

This would be a good candidate for a design pattern. I should tart it up and github it.

Peter McLennan
Gondwana Software
Best Answer

Thank you.  I was able to use the FS API, using your sample, to get my clockface to work how I wanted it to.  Amaizingly enough, this also fixed my other problem located here https://community.fitbit.com/t5/SDK-Development/Extra-info-received-on-first-run-of-clockface-settin...

where I was getting extra junk back from the settings process. 

 

Of course...I still do not have a good example of how to use the JPEG API.

Best Answer
0 Votes

Well done.

 

Given the paucity of info on TXI, I can't help but wonder whether that format is really intended just for internal use. I have a suspicion that the watch creates TXI files automatically. That decodeSync() API call should perhaps not be public.

Peter McLennan
Gondwana Software
Best Answer
0 Votes