https://kotlinlang.org logo
#compose-wear
Title
# compose-wear
a

amoledwatchfaces

10/26/2023, 8:04 AM
Hello, I'm developing a Tile for Favorite App Shortcuts using Horologist Tiles (check images). I'm currently struggling with one thing, when user selects favorite app in Activity, I'm using
Copy code
private fun refreshTileService(context: Context) {
    TileService.getUpdater(context)
        .requestUpdate(FavoriteAppsTileService::class.java)
}
to refresh Tile layout to see user preferred apps. (Screenrecord1) Tile refreshes correctly with right amount of shortcuts but the Images are not rendered. TileRequest is firing but ResourceRequest is not. Because of this, app shortcut works but Icon is not visible.(Screenrecord2). ResourceRequest sometimes comes after 1minutes, sometimes in 5 minutes, sometimes not at all. Only way to force request is to remove and add tile again. I have used MessagingTile example from wearos-samples. Is there any way to force refresh of resources? Any help is appreciated 🙂 Tomas
y

yschimke

10/26/2023, 9:19 AM
Most likely you aren't changing the resource version in the Tile you are sending back.
If you need it to fetch additional images, bump the version.
Or create the version using a combination of the ids?
It's not smart enough to request a missing image for the previous version string.
Horologist has a method to override
In SingleTileLayoutRenderer if you are using that
Copy code
public open fun getResourcesVersionForTileState(state: T): String = PERMANENT_RESOURCES_VERSION
Copy code
/**
 * A constant for non updating resources where each id will always contain the same content.
 */
public const val PERMANENT_RESOURCES_VERSION: String = "0"
a

amoledwatchfaces

10/26/2023, 9:49 AM
Hi Yuri, so something like this will work?
Copy code
override fun getResourcesVersionForTileState(state: UserPreferences): String {
    super.getResourcesVersionForTileState(state)
    return Random.nextInt(1001).toString()
}
Also, where I should bump the version normaly? Always by using getResourcesVersionForTileState? (I'm using SingleTileLayoutRenderer)
y

yschimke

10/26/2023, 9:55 AM
Yes, but be inefficient.
Ideally you would concatenate the ids of the resources to be fetched predictably.
listOf(id1, id2).sorted().joinToString("-")
It goes into the top level Tile (about a single Tile in the timeline).
Copy code
return Tile.Builder()
            .setResourcesVersion(
                if (debugResourceMode) {
                    UUID.randomUUID().toString()
                } else {
                    getResourcesVersionForTileState(state)
                },
            )
a

amoledwatchfaces

10/26/2023, 9:57 AM
Oh, that makes sense. It's working now 🤞🙂
@yschimke Thanks many times! 🙏
y

yschimke

10/26/2023, 10:32 AM
We have talked about making these choices explicit. Maybe some sealed types. Constant(0), Fixed(version:String), ResourceBased(list: List<String>),
👍 1
a

amoledwatchfaces

10/26/2023, 3:50 PM
Nice! 🙂 I've just finished UI, placeholders are really useful. Hopefully review team will approve app because I'm using QUERY_ALL_PACKAGES 🙄
🤞🏻 1
y

yschimke

10/26/2023, 4:46 PM
It's strange Flashlight is pushed over. is that basicMarquee modifier? And wouldn't it fit without marquee.
a

amoledwatchfaces

10/26/2023, 5:23 PM
@yschimke yes, its basicMarquee. No, actually, I've added basicMarquee and maxlines = 1 as for example Flashlight was showing 1row = Flashligh 2row=t I think it's because there is not much space left for text. On one side there is an Icon and on the other is checkbox.
@yschimke if you want, you try final app https://play.google.com/store/apps/details?id=com.weartools.favoriteappstile I recently moved from Horologist Suspending Tile Service to Tile Service and app works like 99% of time but may fail to render resources sometimes. Problem is that sometimes, 5 or 7 bytearrays are decoded to bitmap at once (7 icons from app drawer) and Tile Service throws Error getting tile resources ExecutionError: asr: Timed out. Hard to say how to improve it. I'm returning Futures.immediateFuture in onTileResourcesRequest
FavoriteAppsTile1.kt
y

yschimke

11/04/2023, 6:53 AM
I wonder whether you can put this behind Coil somehow and use it's caching to avoid doing it on each request. I'd try to make sure decoding is on background thread so you get 2 or 4 at once. Coil should do that automatically I hope
But otherwise enough logging to know how long each decide takes.
plus green 1
a

amoledwatchfaces

11/04/2023, 12:03 PM
Actually, with coil it was worse. I was using coil before for this, as Tile Example (Messaging Tile Service) is using coil to get Images. I changed it to straight bytearray to bitmap and it improved a lot. Hmm, so even If I'm creating resources version from prefs joined string, when it changes, all resources are computed again? I thought that only those added are being loaded and older ones are cached.
y

yschimke

11/05/2023, 11:25 AM
Yep. There is no partial resources request in practice. All resources are required in every response. Using a constant version just stops it from re-requesting when it doesn't change.
a

amoledwatchfaces

11/05/2023, 11:30 AM
I think I solved it in best possible way. I'm loading app icon drawable, converting it to bitmap and then decoding it to string. When res request happens, I'm decoding byteArray from the string and also specifying size. This works almost instantly
👍 1
I needed to switch from Horologist to Tile Service as MultiButtonLayout was not working solely (7 buttons) on Galaxy Watches.
y

yschimke

11/05/2023, 11:36 AM
How does Horologist affect that?
You definitely don't need Horologist for tiles. The main reason for those abstractions is support for compose previews for tiles. If you are not using that, then you don't get much from the abstraction
a

amoledwatchfaces

11/05/2023, 12:23 PM
Don't know, I was using Suspending Tile Service, and injecting datastore, initializing it in service onCreate. I was using two Tile layouts. When user selected 5 icons, MultiButtonLayout was used in PrimaryLayout so there was also small chip at the bottom of the tile. When user selected more than 5 icons, based od documentation, MultiButtonLayout layout was used alone (not inside PrimaryLayout). This was working fine on Pixel watch but on Galaxy Watches, only Primary Layout worked. MultiButtonLayout alone caused tile crash. So I moved from Horologist to Tile Service. Used same logic and MultiButtonLayout directly in root is working correctly also on Galaxy Watches.
y

yschimke

11/05/2023, 7:35 PM
If you are happy then whatever works. If you want the Horologist support then file a bug with repro code and I'll look.
❣️ 1
3 Views