Downloading a workout to PersistedContent and using when offline

We have an widget which downloads workouts to a 2.x watch and then allows user to run them.

Users have (quite reasonably :) asked if it is possible for the widget to remember the last downloaded workout and offer to run it if no network is available.

I'm banging my head against the docs trying to find a way to do this. I've tried a number of approaches without luck

a) Remember downloaded intent

If the workout successfully downloads we obviously can call toIntent() to run it, but I the intent cannot be saved to an app property as it is not a string

b) Remember downloaded intent parameters and recreate intent

There do not appear to be any documented accessors to determine the parameters to recreate it.

c) Remember the download object and use it to recreate intent

Again, there object appears to be opaque with no way to serialise and recreate

d) Remember the name of the workout downloaded, then use iterate through PersistedContent to find a match

Its easy enough to save the downloaded workout name to an app property, then iterate through PersistedContent workouts, but while the object passed to the download callback has a getName() there does not appear to be any way to extract the name from a PersistedContent workout. So I can iterate through them and blindly call toIntent() on any of them but they are all completely opaque.

  • Update - it looks like I was fooled by a bug in the docs - I was calling PersistedContent.getWorkouts instead of PersistedContent.getWorkouts(), so it appears that 'd)' should work (albeit we'll end up picking the first returned workout with a matching name)
  • Maybe I'm missing something, but after you've downloaded a workout, can't you just go to the activity and select that workout? I'm not sure why it would need to be downloaded each time. Or if you want to use the widget, select on that's already been downloaded?
  • The workouts are generated by an AI training system, so every workout is unique to the runner's current situation.

    They can be adjusted for temperature and undulation, so nominally the same workout downloaded in the afternoon could be different from the morning, and if a user has performed a freestyle run since they looked at (downloaded) the workout, again it would be adjusted.

    Additionally the user can modify their training commitments (type of run, duration etc on a given day), general risk tolderance and other factors.

    So we always want to check the current next workout state from the server.

    Downloading a workout and then allowing the user to select it directly works perfectly.

    If the user switches away from the widget and then back then we want to check if the workout has changed on the server and only download if it has (to avoid filling the watch with the same workout - I managed to get my 735xt into a very strange state where it appeared to have an unlimited number of identical workouts which I could not remove via the UI). We're having the server modify the workout name every time it changes, so workout 405 would start as 'W405A ...', then 'W405B ...' etc (the ... is the workout type - Interval etc). The app can then make a JSON query before the download to tell if it has changed - that also works fine.

    This issue is when the activity has not changed, or we are unable to connect to the server. Now we need to allow the user to action the last workout downloaded via our app. So far the best option appears to be to iterate through the Persisted workouts on the device and look for one which matches the (saved) name of the last download.

    The only downside would be in the (admittedly) unlikely case when there are two workouts with the same specific name on the watch. In practice this is unlikely to be an issue, though my preference would always be for a genuinuely unique identifier.

    Thanks