Wear OS https://theinshotproapk.com/category/app/wear-os/ Download InShot Pro APK for Android, iOS, and PC Thu, 18 Dec 2025 17:00:00 +0000 en-US hourly 1 https://theinshotproapk.com/wp-content/uploads/2021/07/cropped-Inshot-Pro-APK-Logo-1-32x32.png Wear OS https://theinshotproapk.com/category/app/wear-os/ 32 32 Bringing Androidify to Wear OS with Watch Face Push https://theinshotproapk.com/bringing-androidify-to-wear-os-with-watch-face-push/ Thu, 18 Dec 2025 17:00:00 +0000 https://theinshotproapk.com/bringing-androidify-to-wear-os-with-watch-face-push/ Posted by Garan Jenkin – Developer Relations Engineer A few months ago we relaunched Androidify as an app for generating ...

Read more

The post Bringing Androidify to Wear OS with Watch Face Push appeared first on InShot Pro.

]]>

Posted by Garan Jenkin – Developer Relations Engineer





A few months ago we
relaunched Androidify as an app for generating personalized Android bots. Androidify transforms your selfie photo into a playful Android bot using Gemini and Imagen.

However, given that Android spans multiple form factors, including our most recent addition, XR, we thought, how could we bring the fun of Androidify to Wear OS?

An Androidify watch face

As Androidify bots are highly-personalized, the natural place to showcase them is the watch face. Not only is it the most frequently visible surface but also the most personal surface, allowing you to represent who you are.


Personalized Androidify watch face, generated from selfie image

Androidify now has the ability to generate a watch face dynamically within the phone app and then send it to your watch, where it will automatically be set as your watch face. All of this happens within seconds!

High-level design

End-to-end flow for watch face creation and installation

In order to achieve the end-to-end experience, a number of technologies need to be combined together, as shown in this high-level design diagram.

First of all, the user’s avatar is combined with a pre-existing Watch Face Format template, which is then packaged into an APK. This is validated – for reasons which will be explained! – and sent to the watch.

On being received by the watch, the new Watch Face Push API – part of Wear OS 6- is used to install and activate the watch face.

Let’s explore the details:

Creating the watch face templates

The watch face is created from a template, itself designed in Watch Face Designer. This is our new Figma plugin that allows you to create Watch Face Format watch faces directly within Figma.


An Androidify watch face template in Watch Face Designer


The plugin allows the watch face to be exported in a range of different ways, including as Watch Face Format (WFF) resources. These can then be easily incorporated as assets within the Androidify app, for dynamically building the finalized watch face.

Packaging and validation

Once the template and avatar have been combined, the Portable Asset Compiler Kit (Pack) is used to assemble an APK.

In Androidify, Pack is used as a native library on the phone. For more details on how Androidify interfaces with the Pack library, see the GitHub repository.

As a final step before transmission, the APK is checked by the Watch Face Push validator.

This validator checks that the APK is suitable for installation. This includes checking the contents of the APK to ensure it is a valid watch face, as well as some performance checks. If it is valid, then the validator produces a token.

This token is required by the watch for installation.

Sending the watch face

The Androidify app on Wear OS uses WearableListenerService to listen for events on the Wearable Data Layer.

The phone app transfers the watch face by using a combination of MessageClient to set up the process, then ChannelClient to stream the APK.

Installing the watch face on the watch

Once the watch face is received on the Wear OS device, the Androidify app uses the new Watch Face Push API to install the watch face:

val wfpManager = 

    WatchFacePushManagerFactory.createWatchFacePushManager(context)

val response = wfpManager.listWatchFaces()


try {

    if (response.remainingSlotCount > 0) {

        wfpManager.addWatchFace(apkFd, token)

    } else {

        val slotId = response.installedWatchFaceDetails.first().slotId

        wfpManager.updateWatchFace(slotId, apkFd, token)

    }

} catch (a: WatchFacePushManager.AddWatchFaceException) {

    return WatchFaceInstallError.WATCH_FACE_INSTALL_ERROR

} catch (u: WatchFacePushManager.UpdateWatchFaceException) {

    return WatchFaceInstallError.WATCH_FACE_INSTALL_ERROR

}

Androidify uses either the addWatchFace or updateWatchFace method, depending on the scenario: Watch Face Push defines a concept of “slots” – how many watch faces a given app can have installed at any time. For Wear OS 6, this value is in fact 1.

Androidify’s approach is to install the watch face if there is a free slot, and if not, any existing watch face is swapped out for the new one.

Setting the active watch face

Installing the watch face programmatically is a great step, but Androidify seeks to ensure the watch face is also the active watch face. 

Watch Face Push introduces a new runtime permission which must be granted in order for apps to be able to achieve this:

com.google.wear.permission.SET_PUSHED_WATCH_FACE_AS_ACTIVE

Once this permission has been acquired, the wfpManager.setWatchFaceAsActive() method can be called, to set an installed watch face to being the active watch face.

However, there are a number of considerations that Androidify has to navigate:

  • setWatchFaceAsActive can only be used once.

  • SET_PUSHED_WATCH_FACE_AS_ACTIVE cannot be re-requested after being denied by the user.

  • Androidify might already be in control of the active watch face.

For more details see how Androidify implements the set active logic.

Get started with Watch Face Push for Wear OS

Watch Face Push is a versatile API, equally suited to enhancing Androidify as it is to building fully-featured watch face marketplaces.

Perhaps you have an existing phone app and are looking for opportunities to further engage and delight your users?

Or perhaps you’re an existing watch face developer looking to create your own community and gallery through releasing a marketplace app?

Take a look at these resources:

And also check out the accompanying video for a greater-depth look at how we brought Androidify to Wear OS!


We’re looking forward to what you’ll create with Watch Face Push!

The post Bringing Androidify to Wear OS with Watch Face Push appeared first on InShot Pro.

]]>
Designing with personality: Introducing Material 3 Expressive for Wear OS https://theinshotproapk.com/designing-with-personality-introducing-material-3-expressive-for-wear-os/ Tue, 09 Sep 2025 12:03:02 +0000 https://theinshotproapk.com/designing-with-personality-introducing-material-3-expressive-for-wear-os/ Posted by Chiara Chiappini – Android Developer Relations Engineer, and Kevin Hufnagle – Android Technical Writer This post is part ...

Read more

The post Designing with personality: Introducing Material 3 Expressive for Wear OS appeared first on InShot Pro.

]]>

Posted by Chiara Chiappini – Android Developer Relations Engineer, and Kevin Hufnagle – Android Technical Writer

This post is part of Wear OS Spotlight Week. Today, we’re focusing on creating modern, premium designs using the Material 3 Expressive design system.

When crafting the user interface for your Wear OS app or tile, consider how your experience expresses your brand while respecting the performance guidelines for watches, particularly battery use. With the new Material 3 Expressive design system, you can build performant UIs that truly shine on a wearable device.

A gallery of Wear OS screens that demonstrate Material 3 Expressive, including a curved edge button, a wavy progress circle, and different shapes for “cancel” and “confirm” buttons.

A gallery of Material 3 Expressive experiences on Wear OS

This blog post walks you through the key principles of this new design system and how you can implement them to create more engaging and intuitive user experiences.

What’s new in Material 3 Expressive?

As mentioned in our announcement at I/O earlier this year and our unveiling of Google Pixel Watch 4 last week, Material 3 Expressive introduces several fundamental improvements from previous Wear OS design guidance, which aim to give your apps and tiles more personality and help users feel confident that they’re successfully taking quick actions on a round screen.

The key design principles include the following:

    • Embrace the round form factor: Use the full screen with components like the edge-hugging button to complement the watch’s form factor. This makes the UI feel well-suited for a user’s wrist.
    • Apply the proper screen layout on each surface: Take advantage of the new layouts and components—such as the 3-slot tile PrimaryLayout and the TransformingLazyColumn – to create more consistent, glanceable, and fluid user experiences for tiles and apps.
    • Elevate your experience: The dynamic color system provides a richer palette for more vibrant themes in apps. Variable fonts allow for dynamic, customizable typography.
    • Show off expressive animations: Light up your Wear OS experience with meaningful movement, such as spring animations and shape morphing.

      Embrace the round form factor

      Material 3 Expressive for Wear OS differentiates itself from systems designed for rectangular screens, offering a framework of components that are designed specifically for round screens, using the entire circular canvas to its full potential.

      A button that appears near the bottom of the screen has a flat top but a curved bottom, forming a half-moon shape that better fits the circular screen.

      The edge-hugging button’s animated entrance and shape emphasizes the round form factor

      One of the most noticeable examples of this is the edge-hugging button. It features a curved bottom edge that perfectly complements the round display. It’s a small but significant detail that helps make Material 3 Expressive feel right at home on your users’ wrists.

      Apply the proper screen layout on each surface

      Apps

      For apps that let users scroll through content, Material 3 Expressive introduces the TransformingLazyColumn component. It provides built-in support for expressive and fluid scrolling animations that follow the side edges of the display. We’ve also added a new ScrollIndicator that provides a clear visual cue of the user’s position within a list. (This appears automatically when you use ScreenScaffold.) This, combined with the fluid animations of the TransformingLazyColumn, creates a more intuitive and engaging scrolling experience.

      When the user scrolls through the list, the items near the top and bottom shrink in width.

      When using a TransformingLazyColumn, elements appear to get smaller as they get close to the top and bottom edge of the screen

      For apps that don’t require scrolling, such as media players or confirmation dialogs, Material 3 Expressive provides templates that are optimized for glanceability and focus. These layouts rely on breakpoints and pagination to present a single task or set of controls to the user, minimizing distractions.

      Tiles

      The Material 3 Expressive design system also lets designers and developers create tiles that are both functional and visually engaging:

      The middle part of the tile shows information about the current number of glasses of water having been consumed today, and the bottom part includes a button that lets users add another glass.

      Tiles offer at-a-glance information and support quick actions to indicate progress on a task, such as drinking more water

      Tiles can show a static message about a recent update, invite users to get started, and show progress of an ongoing activity related to fitness, media, and more.

      The new 3-slot tile layout is designed to work for each of these use cases, as well as across a range of screen sizes, to provide a clear and consistent structure for your tile’s content.

      Elevate your experience

      Give your app or tile a signature look using extended color palettes and custom typography.

      Color

      The updated color system in Material 3 Expressive supports more colors—such as tertiary colors—to let you better reflect your brand’s personality and create a more immersive user experience. Use this color system to create themes that perfectly capture the mood of your brand, whether that’s a calming meditation app, the high-energy vibe of a fitness tracker, or something in between.

      With Material 3 Expressive, apps and tiles can either follow the dynamic system color or stick to the brand colors. We especially recommend following the dynamic system colors in your tiles, for higher cohesion with other tiles. You can embrace dynamic colors in your app as well, for instance exposing settings to the user.

      Based on the main colors in the user’s chosen watch face, the design system extracts the 2 most common hues and dynamically chooses several more complementary colors. These colors are applied to the tiles that appear on the user’s watch.

      Dynamic color theme derived from the user-selected watch face (left), applied to a tile (right)

      Typography

      Typography is another key element of expressive design. Material 3 Expressive moves beyond static font weights and styles and embraces the versatility of variable fonts.

      A single font contains adjustable axes, including weight and width. With Material 3 Expressive, you can tap into these customized looks to create dynamic and delightful typographic experiences.

      The text “book club” is thicker than normal, using a larger font weight.

      A font that uses an adjusted weight. If desired, you can also use a different width to s t r e t c h the text.

      Show off expressive animations

      A foundational pillar of Material 3 Expressive’s animation capabilities is the concept of fluid motion, made possible primarily through shape morphing.

      In the 3x3 grid of buttons 1 through 9, when the 9 button is pressed, its left edge moves to the left, and the 8 button shrinks its width to accommodate.

      When the “9” button is pressed, the “8” button moves out of the way to accommodate the expanded size of the “9” button.

      Components no longer have to be rigid – they can now dynamically change their shape in response to user input! Buttons, in particular, can transform shape and size to achieve eye-catching springy animation effects and provide more visual contrast between states such as “play” and “pause.” This not only makes the UI more visually interesting but also helps in guiding the user’s attention and providing clear feedback.

      An experience that’s ready for prime time!

      By adopting the Material 3 Expressive design system, you can create Wear OS apps and tiles that feel more dynamic, personal, and intuitive. By applying principles like rounded components, screen layouts, richer color palettes, and spring animations, you can build experiences that feel perfectly designed for use on a user’s wrist.

      To get you inspired, we’ve included some examples from some of Google’s apps below:

      On the left, the accept call button is a bottom edge-hugging button; on the right-hand side of each item in the list, there’s a toggle button to turn a given alarm on and off.

      Edge-hugging button for an incoming call using the Phone app (left); toggle buttons in the Alarms app (right)

      On the left, The tile includes selectable icons in the middle, such as navigating home, and a bottom edge-hugging button that lets you search for a particular destination; on the right A wavy progress bar moves around the play/pause button in the middle of the tile.

      At-a-glance actions within the tile for the Google Maps app (left); progress of ongoing audio playback in the Media Controls (right)

      Get started with Material 3 Expressive for Wear OS

      To learn more, explore the following resources:

      We can’t wait to see the designs that you create and share with the Wear OS community!

The post Designing with personality: Introducing Material 3 Expressive for Wear OS appeared first on InShot Pro.

]]>
Welcome to Wear OS Spotlight Week https://theinshotproapk.com/welcome-to-wear-os-spotlight-week/ Mon, 08 Sep 2025 12:03:49 +0000 https://theinshotproapk.com/welcome-to-wear-os-spotlight-week/ Posted by Chiara Chiappini – Android Developer Relations Engineer, and Kevin Hufnagle – Android Technical Writer Wear OS is rapidly ...

Read more

The post Welcome to Wear OS Spotlight Week appeared first on InShot Pro.

]]>

Posted by Chiara Chiappini – Android Developer Relations Engineer, and Kevin Hufnagle – Android Technical Writer

Wear OS is rapidly expanding its presence in the market, presenting a unique and significant opportunity for developers. With a growing number of users wearing and interacting with their smartwatches daily, building for Wear OS allows you to reach an even broader audience of Android users and boost your app’s engagement more than ever before. The introduction of new hardware like the Pixel Watch 4 is a key driver of this momentum, enabling developers to bring premium Wear OS experiences to this expanding user base.

This week, we’re putting a special focus on Wear OS: Welcome to Wear OS Spotlight Week!

Throughout the week, we’ll dive into the different Wear OS surfaces where you can develop on-the-watch experiences. This blog post will be updated throughout the week with links to new announcements and resources, so check back here daily for updates.

Day 1: Material 3 Expressive on Wear OS

Monday, August 25, 2025

Learn how you can build beautiful and tailored Wear OS apps and tiles using the Material 3 Expressive Design language and Jetpack libraries for Wear OS.

To further explore the key principles and main features of Wear OS’s new design system, consult our updated design guidance on the Android developer documentation website.

Day 2: Build apps, tiles, and complication on Wear OS

Tuesday, August 26, 2025

Discover how to build engaging experiences across Wear OS’s surfaces, including apps, tiles, complications, and notifications. Learn how to create quick, glanceable content using familiar tools like Jetpack Compose and the ProtoLayout library, all while leveraging the beautiful new Material 3 Expressive design system.

Next, understand how to build beautiful and effective Wear OS tiles using the Material 3 Expressive design system and a new collection of resources.

Dive deep into building complications that support data sources which helps you show useful information to the user directly on the watch face, and can drive engagement with your app.

Lastly, find out how Todoist has applied the latest updates on Wear OS including new integrations with Material 3 Expressive and Credential Manager. Improvements like these have helped Todoist become the world’s top task and time management app.

Day 3: Watch faces

Wednesday, August 27, 2025

Explore the wonderful world of watch faces! The Watch Face Push API for Wear OS 6 is here to unlock a world of dynamic watch faces. This powerful tool lets you create your own marketplace experience for the watch faces you create. Dive in and explore how you can promote your engaging watch faces today! 🎨.

Next, discover how Amoledwatchfaces, a leading creator, successfully migrated to the Watch Face Format for their 190+ watch faces. This switch led to faster development, improved battery life, and more customizable designs.

Lastly, learn about Watch Face Designer, a new Figma plugin that’s available for watch face designers and developers to create watch faces with greater ease.

Day 4: Credential Manager on Wear OS

Thursday, August 28, 2025

Discover how to streamline authentication on your Wear OS app by using Credential Manager.

We’ve got some great new resources to help you learn how everything works, and to help you get started crafting your own implementation:

Day 5: #AskAndroid

Friday, August 29, 2025

Join us for a live Q&A on Wear OS! Ask your questions at Android Developers on X and Android by Google at Linkedin using the tag #AskAndroid.

Explore and create your own experiences with Wear OS

Explore the latest updates for Wear OS, and delve into the wealth of resources shared during the week. We’re excited to see the results of your explorations with building apps, tiles and watch faces for Wear OS.

Happy coding!

The post Welcome to Wear OS Spotlight Week appeared first on InShot Pro.

]]>
Create delightful Wear OS Widgets using sample tile layouts https://theinshotproapk.com/create-delightful-wear-os-widgets-using-sample-tile-layouts/ Sun, 07 Sep 2025 12:01:01 +0000 https://theinshotproapk.com/create-delightful-wear-os-widgets-using-sample-tile-layouts/ Posted by Michael Stillwell – Developer Relations Engineer Golden Tile Templates This post is part of Wear OS Spotlight Week. ...

Read more

The post Create delightful Wear OS Widgets using sample tile layouts appeared first on InShot Pro.

]]>

Posted by Michael Stillwell – Developer Relations Engineer

Golden Tile Templates

Golden Tile Templates

This post is part of Wear OS Spotlight Week. Today, we’re focusing on creating engaging Wear OS tiles with new resources and updated design guidance.

Wear OS is all about providing users with the right information at the right time. While a full app is great for immersive experiences, sometimes users just need a quick glance at information or a simple way to take action.

Tiles are fast, predictable surfaces that users can access with a simple swipe from their watch face. They are designed for quick, frequent tasks like checking the weather, starting a timer, or tracking fitness goals.

To streamline your workflow from concept to launch, we’re pleased to announce a collection of resources to help you build beautiful and effective tiles using the Material 3 Expressive design system.

These layouts are an evolution of a previous version based on Material 2.5, now updated to Material 3 Expressive to create a modern, premium feel that makes your tile a more cohesive part of the Wear OS.

Material 2.5 and Material 3 Expressive side by side version comparison of goal, media, and ski tiles

Material 2.5 and Material 3 Expressive versions of the “Goal”, “Media”, and “Ski” tiles

We hope these resources serve as inspiration and a practical starting point, whether you’re new to Wear OS development or looking to add a tile to your existing app.

Get started with sample layouts

Tiles are built declaratively using the ProtoLayout library. Material 3 Expressive’s Primary Layout is organized around a slot-based architecture. Running from top to bottom, these slots are:

    • An optional titleSlot for a header.
    • A mandatory mainSlot for your core content.
    • An optional bottomSlot for supplemental actions.

Your app implements a TileService, which returns a layout when requested by the system. This layout is then used to build and render the tile. Learn how to get started with tiles.

As an example, here’s the “Goal” layout for visualizing step count. The titleSlot contains the “Steps” text, the mainSlot holds the graphic data card with a progress ring and step data, and the bottomSlot features the “Track” edge-hugging button. (The icon that appears at the top of the tile is specified in your app’s manifest is and drawn by the system.)

Daily steps goal tile on a round watch face

Daily steps goal tile

The code for this layout is structured logically around these slots:

fun layout(
    context: Context,
    deviceParameters: DeviceParameters,
    steps: Int,
    goal: Int
) =
    materialScope(
        context = context,
        deviceConfiguration = deviceParameters
    ) {
        val stepsString = NumberFormat.getNumberInstance().format(steps)
        val goalString = NumberFormat.getNumberInstance().format(goal)
        primaryLayout(
            titleSlot = { text("Steps".layoutString) },
            // Adjust margins to create more space when using fully rounded corners
            margins = PrimaryLayoutMargins.MIN_PRIMARY_LAYOUT_MARGIN,
            mainSlot = {
                graphicDataCard(
                    onClick = clickable(),
                    height = expand(),
                    colors = filledTonalCardColors(),
                    title = { text(stepsString.layoutString) },
                    content = { text("of $goalString".layoutString) },
                    horizontalAlignment = LayoutElementBuilders.HORIZONTAL_ALIGN_END,
                    graphic = {
                        constructGraphic(
                            mainContent = {
                                circularProgressIndicator(
                                    staticProgress = 1F * steps / goal,
                                    // On supported devices, animate the arc
                                    dynamicProgress =
                                    DynamicFloat.onCondition(
                                        PlatformEventSources.isLayoutVisible()
                                    )
                                        .use(1F * data.steps / data.goal)
                                        .elseUse(0F)
                                        .animate(
                                            CircularProgressIndicatorDefaults
                                                .recommendedAnimationSpec
                                        ),
                                    startAngleDegrees = 200F,
                                    endAngleDegrees = 520F,
                                )
                            },
                            iconContent = { icon(ICON_ID) },
                        )
                    },
                )
            },
            bottomSlot = {
                textEdgeButton(onClick = clickable()) { text("Track".layoutString) }
            },
        )
    }

With this simple function, you get a great-looking, responsive tile. The ProtoLayout Material3 library handles the heavy lifting, such as setting margins to avoid clipping on round screens and ensuring components adapt smoothly to different display sizes.

Create custom tile layouts

While our layouts cover many common use cases, you’ll sometimes need a unique layout. The Material 3 Expressive components provide a flexible foundation for building custom designs.

To translate designs into code, start with the most visually similar layout and modify it. The following sections explain how to modify an existing layout slot by slot.

Customize the title and bottom slots

The titleSlot is often a text() element. To verify that the tap targets of the other elements are interactive, you may wish to hide the title slot on smaller devices. Learn how to develop tiles for different screen sizes.

primaryLayout(
    titleSlot =
        if (isLargeScreen()) {
            { text("$tasksLeft mindful tasks left".layoutString) }
        } else {
            null
        },
    // ...
)

The bottomSlot provides users with a primary action, typically an EdgeButton. You can use a textEdgeButton() for a descriptive action. Alternatively, you can use an icon such as + by using an iconEdgeButton.

Using an icon is a two-step process:

  1. Define the iconEdgeButton in your layout, giving your icon a unique resource ID string:
  2. primaryLayout(
        // ...
        bottomSlot = {
            iconEdgeButton(
                onClick = clickable(),
                modifier = LayoutModifier.contentDescription("Add event"),
                iconContent = { icon("icon_plus_id") }
            )
        }
    )
    

  3. Provide the actual drawable resource in onTileResourcesRequest():
  4. override fun onTileResourcesRequest(
        requestParams: RequestBuilders.ResourcesRequest
    ) =
        Futures.immediateFuture(
            ResourceBuilders.Resources.Builder()
                .setVersion(requestParams.version)
                .addIdToImageMapping(
                    "plus_icon_id",
                    ResourceBuilders.ImageResource.Builder()
                        .setAndroidResourceByResId(
                            ResourceBuilders.AndroidImageResourceByResId.Builder()
                                .setResourceId(R.drawable.outline_add_2_24)
                                .build()
                        )
                        .build()
                )
                .build()
        )
    

See Alarm.kt for a full code sample demonstrating this approach.

Customize the main slot

The mainSlot is where the core content of your tile lives and where the most significant customization occurs. Let’s walk through a few examples.

Case study: Workout tile

example of a compact workout tile on a round watch face

A compact workout tile for smaller Wear OS devices.

example of an expanded workout tile on a round watch face

An expanded workout tile providing more information on larger screens.

This tile needs to adapt its layout for different screen sizes. For the smaller layout, three simple iconButton components are a perfect fit. In the larger layout, the central button displays more data (duration, unit, and an icon). Even though it’s semantically still a button, in this case the iconDataCard element is a better fit. It’s specifically designed to display multiple pieces of data, and we can easily adjust its width and height.

iconDataCard(
    title = { text("30".layoutString, typography = DISPLAY_MEDIUM) },
    content = { text("Mins".layoutString, typography = TITLE_MEDIUM) },
    secondaryIcon = { icon("icon_run_id") },
    shape = shapes.large, // adjust the corner shape
    onClick = clickable(),
    // make element more prominent on larger screens
    width = if (isLargeScreen()) weight(1.5f) else expand(),
    height = expand(),
    // ...
)

See Workout.kt for the full source code.

Case study: Skiing stats tile

example of a custom skiing tile on a round watch face

A custom tile for skiing stats

The design for this tile is built around a pill-shaped element that displays three lines of text, each with unique typography. A textDataCard() is perfect for this, offering slots for a “title” (the metric), “content” (the value), and “secondaryText” (the units). These slots come with default styling that you can override to match your design precisely.

fun MaterialScope.statTextButton(stat: Stat) =
    textDataCard(
        onClick = clickable(),
        width = expand(),
        height = expand(),
        shape = shapes.extraLarge,
        title = {
            text(
                stat.value.layoutString,
                typography =
                    if (isLargeScreen()) {
                        Typography.NUMERAL_SMALL
                    } else {
                        Typography.NUMERAL_EXTRA_SMALL
                    }
            )
        },
        content = {
            text(
                stat.unit.layoutString,
                typography =
                    if (isLargeScreen()) {
                        Typography.TITLE_MEDIUM
                    } else {
                        Typography.TITLE_SMALL
                    }
            )
        },
        secondaryText = {
            text(
                stat.label.layoutString,
                typography =
                    if (isLargeScreen()) {
                        Typography.TITLE_MEDIUM
                    } else {
                        Typography.TITLE_SMALL
                    }
            )
        }
    )

Notice how the typography constants are varied according to the screen size (TITLE_MEDIUM vs. TITLE_SMALL, for example). Given the variety of screen and font sizes on Wear OS, this is a key technique to keep text legible. Instead of trying to manually tweak your layout for every possible combination, focus on adjusting the typography by using different font size constants.

For a consistent look, try to stick to the same “category” of typography constant, such as BODY_MEDIUM on small screens and BODY_LARGE on larger ones. Avoid jumping between different categories, like from LABEL_LARGE to DISPLAY_SMALL, as these constants can vary in more than just size, affecting font weight and other visual properties.

See Ski.kt for the full source code.

Another approach to adapting a layout to different screen sizes is simply to add or remove elements depending on the display size, as demonstrated by the Weather.kt layout. While both versions display the same current conditions, the larger version adds more information to the forecast.

example of a glanceable weatehr tile on a round watch face

A glanceable weather tile for smaller Wear OS screens

example of an expanded weather tile on a round watch face

An enhanced weather tile with forecast details for larger displays.

Customize colors

You might notice that the templates don’t specify a color scheme, yet they adapt to the user’s chosen theme on Wear OS 6. This is due to dynamic theming, a system feature that automatically generates a color scheme by extracting seed colors from sources like the user’s watch face. For tiles, this is the default behavior.

examples of the same weather app featuring three different system-generated color themes

The same Weather tile under three different system-generated color themes

As a developer, this gives you two main options for your tile’s appearance:

Option 1 (recommended): Follow dynamic color theming. A dynamic theme is used by default. In this case, you should provide a defaultColorScheme to be used as a fallback if the user disables dynamic theming or if the device doesn’t support it. This approach creates a consistent and cohesive feel, allowing your tile to integrate seamlessly with the system.

val myColorScheme =
    ColorScheme(
        primary = ...
        onPrimary = ...
        // 27 more
    )

materialScope(
  defaultColorScheme = myColorScheme
) {
  // If the user selects "no theme" in settings, myColorScheme is used.
  // Otherwise, the system-provided theme is used.
}

Option 2: Use your brand colors. To ensure brand consistency, you can force your tile to always use your custom color scheme by setting allowDynamicTheme to false. In this case, the same colors will always be used, irrespective of the user’s selected color theme.

materialScope(
  allowDynamicTheme = false,
  defaultColorScheme = myColorScheme
) {
  // myColorScheme is *always* used.
}

See Theming for more information on the theming system.

Develop and debug

To speed up your development cycle, Wear OS provides several tools to help you debug and test your tiles directly in Android Studio and on the command line.

Dive in and start building

These resources are designed to make building high-quality Wear OS tiles easier and more inspiring. We can’t wait to see what you create with them.

Explore the layouts and get started today by checking out the Figma design kit or the code on GitHub.

The post Create delightful Wear OS Widgets using sample tile layouts appeared first on InShot Pro.

]]>
Ever-present and useful: Building complication data sources for Wear OS https://theinshotproapk.com/ever-present-and-useful-building-complication-data-sources-for-wear-os/ Sun, 07 Sep 2025 12:00:52 +0000 https://theinshotproapk.com/ever-present-and-useful-building-complication-data-sources-for-wear-os/ Posted by Garan Jenkin – Developer Relations Engineer This post is part of Wear OS Spotlight Week. Today, we’re focusing ...

Read more

The post Ever-present and useful: Building complication data sources for Wear OS appeared first on InShot Pro.

]]>

Posted by Garan Jenkin – Developer Relations Engineer

This post is part of Wear OS Spotlight Week. Today, we’re focusing on creating engaging experiences across the various surfaces available on the wrist.

Put your app’s unique information directly on a user’s watch face by building your own complications. These are the small, glanceable details on a watch face, like step count, date, or weather, that are used to convey additional information, beyond simply telling the time.

Watches such as the recently-launched Pixel Watch 4 feature watch faces with as many as 8 complications. These small, powerful display elements are a great way to provide quick, valuable information and keep users connected to your app.

Let’s look at how you can build your own complication data sources, surfacing useful information to the user directly on their watch face, and helping drive engagement with your app.

A round, analog Wear OS watch face showing 8 complications

A watch face showing 8 complications – 4 arc-style complications around the edge of the watch face, and 4 circular complications within the center of the watch face

Key principles of complications

In order to help understand complications, let’s first review some of the key architectural aspects of their design:

    • Apps provide only a complication data source – the watch face takes care of all layout and rendering.
    • Complication data is typed – both complication data sources and watch faces specify which types are supported respectively.
    • Watch faces define slots – these are spaces on the watch face that can host complications.

A flow chart illustrating the flow of requests and ComplicationData between the Wear OS system, watch face, and complication data source

The flow of requests and ComplicationData between the Wear OS system, watch face, and complication data source

What are complications good for?

Complications are great for providing the user with bite-size data during the course of the day. Additionally, complications can provide a great launch point into your full app experience.

Complications Data source types (full list) include SHORT_TEXT and SMALL_IMAGE. Similarly, watch faces declare what types they can render.

For example, if you’re building an app which includes fitness goals, a good choice for a complication data source might be one that provides the GOAL_PROGRESS or RANGED_VALUE data types, to show progress toward that goal.

Conversely, complications are less appropriate for larger amounts of data, such as the contents of a chat message. They’re also not suitable for very frequent updates, such as real-time fitness metrics generated by your app.

Creating a complication data source

Let’s look at creating a complication data source for that fitness goal mentioned above.

First, we create a service that extends SuspendingComplicationDataSourceService:

class MyDataSourceService : SuspendingComplicationDataSourceService() {
    override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? {
        // Handle both GOAL_PROGRESS and RANGED_VALUE
        return when (request.complicationType) {
            ComplicationType.GOAL_PROGRESS -> goalProgressComplicationData()
            ComplicationType.RANGED_VALUE -> rangedValueComplicationData()
            else -> NoDataComplicationData()
        }
    }

    // Apps should override this so that watch face previews contain
    // complication data
    override fun getPreviewData(type: ComplicationType) = createPreviewData()
}

To create the actual data to return, we create a ComplicationData object, shown here for GOAL_PROGRESS:

fun goalProgressComplicationData(): ComplicationData {
    val goalProgressText = PlainComplicationText
        .Builder("${goalProgressValue.toInt()} km")
        .build()
    return GoalProgressComplicationData.Builder(
        value = goalProgressValue,
        targetValue = goalTarget,
        contentDescription = goalProgressText
    )
    // Set some additional optional data
    .setText(goalProgressText)
    .setTapAction(tapAction)
    .setMonochromaticImage(...)
    .build()
}

Note: The GoalProgressComplicationData has numerous optional fields in addition to the mandatory ones. You should try to populate as many of these as you can.

Finally, add the data source to the manifest:

<service
    android:name=".WorkoutStatusDataSourceService"
    android:exported="true"
    android:directBootAware="true"
    android:label="@string/status_complication_label"
    android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
    <intent-filter>
        <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
    </intent-filter>

    <!--
      Supported data types. Note that the preference order of the watch face,
      not the complication data source, decides which type will be chosen.
    -->
    <meta-data
        android:name="android.support.wearable.complications.SUPPORTED_TYPES"
        android:value="GOAL_PROGRESS,RANGED_VALUE" />
    <meta-data
        android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
        android:value="300" />
</service>

Note: The use of the directBootAware attribute on the service lets the complication service run before the user has unlocked the device on boot.

Choosing your update model

Complications support both a push and a pull-style update mechanism. In the example above, UPDATE_PERIOD_SECONDS is set such that the data is refreshed every 5 minutes. Wear OS will check the updated value of the complication data source with that frequency.

This works well for a scenario such as a weather complication, but in other scenarios, it may make more sense for the updates to be driven by the app. To achieve this, you can:

  1. Set UPDATE_PERIOD_SECONDS to 0 to indicate that the app will drive the update process.
  2. Using ComplicationDataSourceUpdateRequester in your app code to signal to the Wear OS system that an update should be requested, for example in a WorkManager job, or in WearableListenerService.

Leveraging platform bindings for high-frequency data

Particularly for health-related complications, we can take advantage of platform data sources, to improve our goal progress complication. We can use these data sources with dynamic expressions to create complication content which is dynamically re-evaluated every second while the watch face is in interactive mode (that is, when it’s not in system ambient / always-on mode).

Let’s update the complication so that instead of just showing the distance, it shows a celebratory message when the target is reached. First we create a dynamic string as follows:

val distanceKm = PlatformHealthSources.dailyDistanceMeters().div(1000f)
val formatter = DynamicBuilders.DynamicFloat.FloatFormatter.Builder()
    .setMaxFractionDigits(2)
    .setMinFractionDigits(0)
    .build()
val goalProgressText = DynamicBuilders.DynamicString
    .onCondition(distanceKm.lt(distanceKmTarget))
    .use(
        distanceKm
            .format(formatter)
            .concat(DynamicBuilders.DynamicString.constant(" km"))
    )
    .elseUse(
        DynamicBuilders.DynamicString.constant("Success!")
    )

Then we include this text, and the dynamic value distanceKm, with the dynamic version of the complication builder.

In this way, the distance is updated every second, with no need for further requests to the data source. This means UPDATE_PERIOD_SECONDS can be set to a large value, saving battery, and the celebratory text is immediately shown the moment they pass their target!

Configuring complications

For some data sources, it is useful to let the user configure what data should be shown. In the fitness goal example, consider that the user might have weekly, monthly, and yearly goals.

Adding a configuration activity allows them to select which goal should be shown by the complication. To do this, add the PROVIDER_CONFIG_ACTION metadata to your service definition, and implement an activity with a filter for this intent, for example:

<service android:name=".MyGoalDataSourceService" ...>
  <!-- ... -->

  <meta-data
      android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
      android:value="com.myapp.MY_GOAL_CONFIG" />
</service>

<activity android:name=".MyGoalConfigurationActivity" ...>
  <intent-filter>
    <action android:name="com.myapp.MY_GOAL_CONFIG" />
    <category android:name="android.support.wearable.complications.category.PROVIDER_CONFIG" />
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>

In the activity itself, the details of the complication being configured can be extracted from the intent:

// Keys defined on ComplicationDataSourceService
// (-1 assigned when the ID or type was not available)
val id = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_ID, -1)
val type = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_TYPE, -1)
val source = intent.getStringExtra(EXTRA_CONFIG_DATA_SOURCE_COMPONENT)

To indicate a successful configuration, the activity should set the result when exiting:

setResult(Activity.RESULT_OK) // Or RESULT_CANCELED to cancel configuration
finish()

The ID is the same ID passed in ComplicationRequest to the complication data source service. The Activity should write any configuration to a data store, using the ID as a key, and the service can retrieve the appropriate configuration to determine what data to return in response to each onComplicationRequest().

Working efficiently with time and events

In the example above, UPDATE_PERIOD_SECONDS is set at 5 minutes – this is the smallest value that can be set for the update period. Ideally this value should be set as large as is acceptable for the use case: This reduces requests and improves battery life.

Consider these examples:

    • A known list of events – For example a calendar. In this case, use SuspendingTimelineComplicationDataSourceService.
    • This allows you to provide the series of events in advance, with no need for the watch face to request updates. The calendar data source would only need to push updates if a change is made, such as another event being scheduled for the day, offering timeliness and efficiency.

      ComplicationDataTimeline requires a defaultComplicationData as well as the list of entries: This is used in the case where none of the timeline entries are valid for the current time. For example, for a calendar it could contain the text “No event” where the user has nothing booked. Where there are overlapping entries, the entry with the shortest interval is chosen.

override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? {
    return ComplicationDataTimeline(
        // The default for when there is no event in the calendar
        defaultComplicationData = noEventComplicationData,
        // A list of calendar entries
        timelineEntries = listOf(
            TimelineEntry(
                validity = TimeInterval(event1.start, event1.end),
                complicationData = event1.complicationData
            ),
            TimelineEntry(
                validity = TimeInterval(event2.start, event2.end),
                complicationData = event2.complicationData
            )
        )
    )
}

    • Working with time or timers – If your complication data contains time or a timer, such as a countdown to a particular event, use built-in classes such as TimeDifferenceComplicationText and TimeFormatComplicationText – this keeps the data up-to-date while avoiding regular requests to the data source service.
    • For example, to create a countdown to the New Year:

TimeDifferenceComplicationText.Builder(
    TimeDifferenceStyle.SHORT_SINGLE_UNIT,
    CountDownTimeReference(newYearInstant)
)
.setDisplayAsNow(true)
.build()

    • Data that should be shown at a specific time and/or duration – use setValidTimeRange() to control when complication data should be shown, again avoiding repeated updates.
    • This can be useful in the case where it is not possible to use a timeline but where data can become stale, allowing you to control the visibility of this data.

Working with activation and deactivation

It can be very useful to track whether your complication is currently in use on the active watch face or not. This can help with:

  1. Avoiding unnecessary work – for example, if a weather complication has not been set in the active watch face, then there is no need to enable a WorkManager job to periodically fetch weather updates, saving battery and network usage.
  2. Aiding discovery – if onComplicationActivated has never been called, then the user has never used your complication on a watch face.
  3. This can be a useful signal to provide an educational moment in your phone or Wear OS app, drawing attention to this feature, and sharing potential benefits with the user that they may not be aware of.

To facilitate these use cases, override the appropriate methods in your complication service:

class MyDataSourceService() : SuspendingComplicationDataSourceService() {
    override fun onComplicationActivated(complicationInstanceId: Int, type: ComplicationType) {
        super.onComplicationActivated(complicationInstanceId, type)

        // Keep track of which complication has been enabled, and
        // start any necessary work such as registering periodic
        // WorkManager jobs
    }
    
    override fun onComplicationDeactivated(complicationInstanceId: Int) {
        super.onComplicationDeactivated(complicationInstanceId)

        // Complication instance has been disabled, so remove all
        // registered work
    }

Some additional points to consider when implementing your data sources:

    • Support multiple types to maximize usefulness and compatibility – Watch faces will support some complication data types, but likely not all of them.
    • Adding support to your data source for multiple types makes it most useful to the user. In the above example, we implemented both RANGED_VALUE and GOAL_PROGRESS, as both can be used to represent progress-type data.

      Similarly, if you were to implement a calendar complication, you could use both SHORT_TEXT and LONG_TEXT to maximize compatibility with the available slots on the watch face.

    • Use different data sources for different user journeys – Your app is not limited to providing one complication data source. You should support more than one if you have different use cases to cater for. For example, your health and fitness app might have a complication to provide your progress towards your goals, but also a separate complication to show sleep stats.
    • Avoid heavy work in onComplicationRequest() For example,if the progress toward a fitness goal involves intensive processing of a large number of workouts, do this elsewhere. The request to the complication data source should ideally just return the value with minimal computation.
    • Avoid your service having extensive dependencies on other app components – When in use, your data source service will be started when the Wear OS device starts up, and at other times during the day. You should avoid the service needing too many other components from within your app to be started in order to run, to maintain good system performance.
    • Consider backup and restore – If the complication is configurable, it might make sense to restore these settings – learn how to implement backup and restore for complication data sources.
    • Think about the discovery journey – Your complications will be available as an option on the user’s watch face when your app is installed on the watch. Consider how you can promote and educate the user on this functionality, both in your phone app and your Wear OS app, and leverage methods such as onComplicationActivated() to inform this process.
    • Resources for creating complications

      Complications are a great way to elevate your app experience for users, and to differentiate your app from others.

      Check out these resources for more information on creating complication data sources. We look forward to seeing what you can do.

      Happy Coding!

The post Ever-present and useful: Building complication data sources for Wear OS appeared first on InShot Pro.

]]>
Todoist’s journey to modernize Wear OS experience with Material 3 Expressive and Credential Manager https://theinshotproapk.com/todoists-journey-to-modernize-wear-os-experience-with-material-3-expressive-and-credential-manager/ Sat, 06 Sep 2025 12:17:08 +0000 https://theinshotproapk.com/todoists-journey-to-modernize-wear-os-experience-with-material-3-expressive-and-credential-manager/ Posted by Kseniia Shumelchyk – Engineering Manager, Android Developer Relations, and Rastislav Vaško – Head of Android at Doist Since ...

Read more

The post Todoist’s journey to modernize Wear OS experience with Material 3 Expressive and Credential Manager appeared first on InShot Pro.

]]>

Posted by Kseniia Shumelchyk – Engineering Manager, Android Developer Relations, and Rastislav Vaško – Head of Android at Doist

Since we expanded Android to smartwatches, Todoist has continually evolved their Wear OS experience. In the latest version of the platform, Wear OS 6, they leveraged Compose for Wear OS to bring Material 3 Expressive best practices to life, refreshing their app’s and tile’s appearance in the process.

Todoist and the Wear OS opportunity

Todoist is a popular task management application designed to help users organize, prioritize, and complete their tasks across their personal and professional lives the moment they come to mind. Its core philosophy embraces a clean, simple interface that provides a robust set of features, making it accessible for casual users while still being effective for power users and teams.

Here, Wear OS comes into frame – a smartwatch isn’t just a smaller phone, it’s an immediate, personal companion. The ability to glance at your wrist for timely information or quickly capture a task is a uniquely powerful experience. With the revitalization of Wear OS, driven by a modern toolkit and a unified platform, the opportunity to create these delightful experiences has never been greater.

Todoist on their Wear OS evolution

The Todoist team has always been committed to being wherever their users are, helping them organize their work and lives with minimal friction.

We’ve had a Wear OS app ever since Android Wear 1.0 came out in 2014! Since that time, our experience on Wear OS has evolved to become a perfect platform for quick interactions and easy data access,” said Rastislav Vaško, head of Android at Doist.

When Wear OS began its new chapter a few years ago, Todoist saw the chance to do more than just maintain their existing app, and instead completely reimagine what a task manager on your wrist could be. This marked an important milestone when they migrated the whole codebase to Jetpack Compose along with a UX refresh, and saw a solid user base growth rate increase by 50%.

Over the recent months, since Wear OS 6 Developer Preview came out, Todoist developers have been working on both visual and under-the-hood improvements of the Wear OS experience, specifically:

This time we didn’t add new experiences, but we wanted the existing ones to get better – through new UI patterns, dynamic theming, and simpler authentication,” Rastislav said.

moving image of Todoist Wear OS app after Material 3 EXpressive migration

Todoist Wear OS app after Material 3 Expressive migration

Implementing Material 3 Expressive redesign

On wearables, a highly-glanceable form factor, developers need to make every tap count, and Todoist’s design philosophy is built on this principle. As the team put it, “On Wear OS, we’re focusing only on the very essential actions. Each screen and each tap should be meaningful and provide value to the user”.

This focus on simplicity allowed Todoist to fully embrace the new design language and APIs that make modern Wear OS development so compelling, so they knew from the start that they wanted to adopt Material 3 Expressive:

Material 3 Expressive brings a lot of fluid interactions and delight to Wear OS, and we wanted to leverage these new patterns,” notes Rastislav. “It’s more than just a fresh coat of paint; it’s a design system built for the modern wearable experience”.

As a first step, Todoist design team has used Wear Material 3 Expressive Figma design kits and guiding principles to craft an updated UX for Todoist app and tiles that allowed them to understand the new design language and use relevant Material 3 elements.

Implementing the new design language was made significantly easier by the modern developer toolkit, as the Wear Compose Material 3 and Wear Protolayout Material 3 libraries provide updated and extended color schemes, typography, and shapes, as well as a full set of UI components, and layouts that come with built-in support for expressive motion.

Perhaps best of all, Todoist was able to implement an elegant solution that didn’t require lots of complicated code, as Jetpack Compose matched nicely to design elements in Figma kit. According to the team, “That was the best part – we didn’t need to solve any hard challenges… The APIs work, and they’re simple and intuitive!”.

moving image of Todoist Wear OS app showing edge hugging button after Material 3 EXpressive migration

The “edge hugging” button provides a sleek and fun experience for users

Todoist developers have taken advantage of the new components introduced in the Material 3 library. In particular, a combination of ScreenScaffold, which lays out the structure of a screen and coordinates transitions of the scroll indicator and time text label; EdgeButton, which has a special shape designed for the bottom of the screen; and TransformingLazyColumn for vertically scrolling lists—altogether creates a coherent user experience.

@Composable
private fun CreateItemLayout(
    state: CreateItemViewModel.Parsed,
    // ...
    scrollState: TransformingLazyColumnState = rememberTransformingLazyColumnState(),
) = ScreenScaffold(
    modifier = Modifier.background(MaterialTheme.colorScheme.background),
    scrollState = scrollState,
    contentPadding = rememberResponsiveColumnPadding(
        first = ColumnItemType.Button,
        last = ColumnItemType.EdgeButtonPadding,
    ),
    edgeButton = {
        EdgeButton(
            text = stringResource(id = R.string.action_home_create_item),
            colors = TodoistButtonDefaults.primaryButtonColors(),
            onClick = onSubmitClick,
            enabled = state.isReadyToSubmit,
        )
    },
) { contentPadding ->
    val transformationSpec = rememberTransformationSpec()
    TransformingLazyColumn(
        modifier = modifier.fillMaxSize(),
        contentPadding = contentPadding,
        verticalArrangement = Arrangement.spacedBy(
            space = 4.dp,
            alignment = Alignment.Top,
        ),
        horizontalAlignment = Alignment.Start,
        state = scrollState,
    ) {
       // ...
    }
}

Implementation example for ‘Add new task’ screen

This seamless integration between design and development extended to tiles, where the library provides a composable-like, declarative approach to building tiles, which made integration feel like a natural extension of the main app: “Technically, the new Tiles API resembles Compose, which we’re big fans of, so it felt very natural to use it right away”.

example of the glanceable ‘Day Progress’ tile

The ‘Day Progress’ Tile provides a delightful and glanceable experience

As an example, for the ‘Day Progress’ Tile, Todoist used one of the standard layouts that use a Slots-based approach:

class DayProgressTileRenderer(
    context: Context,
    private val onClickAction: Action,
) : SingleTileLayoutRenderer<DayProgressTileState, Unit>(context) {
    override fun renderTile(
        state: DayProgressTileState,
        deviceParameters: DeviceParametersBuilders.DeviceParameters,
    ) = materialScope(
        context = context,
        deviceConfiguration = deviceParameters,
        defaultColorScheme = state.theme.toTileColorScheme(context),
    ) {
        primaryLayout(
            titleSlot = { titleSlot(context) },
            mainSlot = { mainSlot(context, state, onClickAction) },
            labelForBottomSlot = { labelForBottomSlot(context) },
            bottomSlot = { bottomSlot(context, state) },
            margins = PrimaryLayoutMargins.MIN_PRIMARY_LAYOUT_MARGIN,
        )
    }

// ...

private fun MaterialScope.mainSlot(...) = graphicDataCard(...)

private fun MaterialScope.labelForBottomSlot(context: Context) = text(
    text = context.getString(R.string.tile_day_progress_goal).layoutString,
    typography = Typography.TITLE_SMALL,
)

The slots extend MaterialScope automatically, which means no extra work is needed for styling.

The protolayout-material3 library provides a large number of components designed according to the Material 3 Expressive specifications and user interface recommendations, which the Todoist team has taken advantage of. An example is the graphicDataCard, which Todoist used for the main slot on this tile.

Todoist’s Tile also supports dynamic color theming, which, implementation-wise, requires no effort from developers as the top-level materialScope function has the allowDynamicTheme flag set to true by default.

examples of the 'Day Progress' tile supporting dynamic color

The ‘Day Progress’ Tile supports dynamic color theming on Wear OS 6

Streamlining authentication with Credential Manager

To put the cherry on top of the update, Todoist also implemented a new user authentication experience with the new Credential Manager API on Wear OS.

Credential Manager provides a simplified, standardized user sign-in experience that can be implemented with minimal effort by reusing the same code as the mobile version.

Todoist especially appreciated the standardized UI: “…the [Credential Manager] UI is managed by the [Wear OS] library, which makes the work easy, freeing us up to concentrate on our app’s unique features, rather than reinventing the wheel…”.

moving examples of Todoist app authentication before migrating to Credential Manager on the left, and after on the right

Todoist authentication: before (left) and after (right) migrating to Credential Manager

Previously, Todoist had implemented its own UI that incorporated supported authentication methods, such as reusing an auth token from an existing mobile sign-in, legacy Google Sign-In, and OAuth 2.0, which allowed users to complete their sign-in on a connected phone.

After the migration, the Todoist authentication flow relies on the Credential Manager UI, which provides a single entry point for available sign-in methods and accounts, including passwords, passkeys, and federated identities like “Sign in with Google.” Users can now enjoy a streamlined experience with a single-tap sign-in on their watch.

For apps migrating to Credential Manager, we recommend keeping at least one backup authentication method in case a user taps “Dismiss.” The Todoist team reused their previous options: OAuth 2.0 and data layer token sharing.

And since they already had a mobile integration, Todoist was able to reuse their mobile code: “We were already using Credential Manager in Todoist for Android, so… it was a no-brainer to adopt it. We’re providing the same seamless experience in both apps while simplifying and reusing code.

Impact of the transformation

With their revamped experience completed, Todoist was thrilled with the results: “the Edge Hugging Button just feels delightful to use! But seriously, authentication is simpler and faster with Credential Manager”. Rastislav reports excellent user feedback, and the team is now preparing to make the updates available to all users in the coming weeks.

By leveraging the fluid interactions and delightful design of Material 3 Expressive, we've elevated the Todoist expreience on Wear OS. Our Wear OS users are not only more engaged, but also show a significantly higher conversion rate than average – a trend we expect to continue – Rastislav Vasko, Head of Android at Doist

With their robust user base on Wear OS, Todoist expects to continue growing as they invest further and see a strong business case to continue their commitment to wearables.

Rastislav also sums it up well with the final future-looking quote: “We’re invested in Wear! Currently we’re exploring new Tiles, but also AI features.

Todoist’s recommendations to Android and Wear OS developers

As an active member in the ever-growing Wear OS app ecosystem, Todoist was eager to provide some simple advice for other developers interested in Material 3 Expressive: “Just follow the docs and examples. The samples available for Wear OS are superb and always up-to-date”.

They also recommend embracing Wear OS as a whole: “It’s a mature yet fun platform to develop for! Your designers will need to focus on the essence of your product, your developers have a great testing ground to explore new patterns and APIs, and your users will appreciate having faster and easier access to your product.

Get started with Material 3 Expressive and Credential Manager

With its new features and modern elegance, Wear OS 6 with Material 3 Expressive provides a smartwatch platform that is delightful for users, and convenient for developers.

Learn more about the Material 3 Expressive for Wear OS design system, and get access to the Material 3 Expressive components and layouts using latest Wear Compose Material 3 and Wear Protolayout Material 3 Jetpack libraries.

For even more resources for developers visit:

To learn more about Credential Manager on Wear OS check out developer guidance and sample app.

The post Todoist’s journey to modernize Wear OS experience with Material 3 Expressive and Credential Manager appeared first on InShot Pro.

]]>
How Dashlane Brought Credential Manager to Wear OS with Only 78 New Lines of Code https://theinshotproapk.com/how-dashlane-brought-credential-manager-to-wear-os-with-only-78-new-lines-of-code/ Wed, 03 Sep 2025 18:06:00 +0000 https://theinshotproapk.com/how-dashlane-brought-credential-manager-to-wear-os-with-only-78-new-lines-of-code/ Posted by John Zoeller – Developer Relations Engineer, Loyrn Hairston – Product Marketing Manager, and Jonathan Salamon – Dashlane Staff ...

Read more

The post How Dashlane Brought Credential Manager to Wear OS with Only 78 New Lines of Code appeared first on InShot Pro.

]]>

Posted by John Zoeller – Developer Relations Engineer, Loyrn Hairston – Product Marketing Manager, and Jonathan Salamon – Dashlane Staff Software Engineer

Dashlane is a password management and provision tool that provides a secure way to manage user credentials, access control, and authentication across multiple systems and applications.

Dashlane has over 18 million users and 20,000 businesses in 180 countries. It’s available on Android, Wear OS, iOS, macOS, Windows, and as a web app with an extension for Chrome, Firefox, Edge, and Safari.

Recently, they expanded their offerings by creating a Wear OS app with a Credential Provider integration from the Credential Manager API, bringing passkeys to their clients and users on smartwatches.

Streamlining Authentication on Wear OS

Dashlane users have frequently requested a Wear OS solution that provides standalone authentication for their favorite apps. In the past, Wear OS lacked the key APIs necessary for this request, which kept Dashlane from being able to provide the functionality. In their words:

“Our biggest challenge was the lack of a standard credentials API on Wear OS, which meant that it was impossible to bring our core features to this platform.”

This has changed with the introduction of the new Credential Manager API on Wear OS.

Credential Manager provides a simplified, standardized user sign-in experience with built-in authentication options for passkeys, passwords, and federated identities like Sign in with Google. Conveniently, it can be implemented with minimal effort by reusing the same code as the mobile version.

The Dashlane team was thrilled to learn about this, as it meant they could save a lot of time and effort: “[The] CredentialManager API provides the same API on phones and Wear OS; you write the code only once to support multiple form factors.”

Credential selection Screenshot

Selecting Dashlane-provided credentials is simple for users

After Dashlane had planned out their roadmap, they were able execute their vision for the new app with only a small engineering investment, reusing 92% of the Credential Manager code from their mobile app. And because the developers built Dashlane’s app UI with Jetpack Compose for Wear OS, 60% of their UI code was also reused.

Quote from Sebastien Eggenspieler, Senior engineer at Dashlane

Developing for Wear OS

To provide credentials to other apps with Credential Manager, Dashlane needed to implement the Credential Provider interface on Wear OS. This proved to be a simple exercise in calling their existing mobile code, where Dashlane had already implemented behavior for credential querying and credential selection.

For example, Dashlane was able to reuse their logic to handle client invocations of CredentialManager.getCredential. When a client invokes this, the Android framework propagates the client’s getCredentialRequest to Dashlane’s CredentialProviderService.onBeginGetCredentialRequest implementation to retrieve the credentials specified in the request.

Dashlane delegates the logic for onBeginGetCredentialRequest to their handleGetCredentials function, below, which is shared between their mobile and Wear OS implementations.

// When a Credential Manager client calls 'getCredential', the Android
// framework invokes `onBeginGetCredentialRequest`. Dashlane
// implemented this `handleGetCredentials` function to handle some of
// the logic needed for `onBeginGetCredentialRequest`
override fun handleGetCredentials(
    context: Context,
    request: BeginGetCredentialRequest):
List<CredentialEntry> =
  request.beginGetCredentialOptions.flatMap { option ->
    when (option) {
      // Handle passkey credential
      is BeginGetPublicKeyCredentialOption -> {
        val passkeyRequestOptions = Gson().fromJson(
            option.requestJson, PasskeyRequestOptions::class.java)

        credentialLoader.loadPasskeyCredentials(
          passkeyRequestOptions.rpId,
          passkeyRequestOptions.allowCredentials ?: listOf()
        ).map { passkey ->
          val passkeyDisplayName = getSuggestionTitle(passkey, context)

          PublicKeyCredentialEntry.Builder(
            context,
            passkeyDisplayName,
            pendingIntentForGet(context, passkey.id),
            option
          )
          .setLastUsedTime(passkey.locallyViewedDate)
          .setIcon(buildMicroLogomarkIcon(context = context))
          .setDisplayName(passkeyDisplayName)
          .build()
// Handle other credential types

Reusing precise logic flows like this made it a breeze for Dashlane to implement their Wear OS app.

“The Credential Manager API is unified across phones and Wear OS, which was a huge advantage. It meant we only had to write our code once.”

Impact and Improved Growth

The team is excited to be among the first credential providers on wearables: “Being one of the first on Wear OS was a key differentiator for us. It reinforces our brand as an innovator, focusing on the user experience, better meeting and serving our users where they are.”

As an early adopter of this new technology, Dashlanes Wear OS app has already shown early promise, as described by Dashlane software engineer, Sebastien Eggenspieler: “In the first 3 months, our Wear OS app organically grew to represent 1% of our active device install base.”

With their new experience launched, Wear OS apps can now rely on Dashlane as a trusted credential provider for their own Credential Manager integrations, using Dashlane to allow users to log in with a single tap; and users can view details about their credentials right from their wrist.

app homescreen screenshot

Dashlane’s innovative design helps users manage their credentials

Dashlane’s Recommendations to Wear OS Developers

With their implementation complete, the Dashlane team can offer some advice for other developers who are considering the Credential Manager API. Their message is clear: “the future is passwordless… and passkeys are leading the way, [so] provide a passkey option.”

As a true innovator in their field, and the preferred credential provider for so many users, we are thrilled to have Dashlane support Credential Manager. They truly inspired us with their commitment to providing Wear OS users with the best experience possible:

“We hope that in the future every app developer will migrate their existing users to the Credential Manager API.”

Get Started with Credential Manager

With its elegant simplicity and built-in secure authentication methods, the Credential Manager API provides a simple, straightforward authentication experience for users that changes the game in Wear OS.

Want to find out more about how Dashlane is driving the future of end-user authentication? Check out our video blog with their team in Paris, and read about how they found a 70% in sign-in conversion rates with passkeys.

To learn more about how you can implement Credential Manager, read our official developer and UX guides, and be sure to check out our brand new blog post and video blog as part of Wear OS Spotlight week!

We’ve also expanded our existing Credential Manager sample to support Wear OS, to help guide you along the way, and if you’d like to provide credentials like Dashlane, you can use our Credential Provider sample.

Finally, explore how you can start developing additional experiences for Wear OS today with our documentation and samples.

The post How Dashlane Brought Credential Manager to Wear OS with Only 78 New Lines of Code appeared first on InShot Pro.

]]>
Further explorations with Watch Face Push https://theinshotproapk.com/further-explorations-with-watch-face-push/ Wed, 03 Sep 2025 12:01:21 +0000 https://theinshotproapk.com/further-explorations-with-watch-face-push/ Posted by Garan Jenkin – Developer Relations Engineer This post is part of Wear OS Spotlight Week. Today, we’re exploring ...

Read more

The post Further explorations with Watch Face Push appeared first on InShot Pro.

]]>

Posted by Garan Jenkin – Developer Relations Engineer

This post is part of Wear OS Spotlight Week. Today, we’re exploring the wonderful world of watch faces.

At Google I/O ‘25 we launched Watch Face Push, a new API aimed at enabling watch face marketplaces for watch and phone. Watch Face Push is now available to develop with and use on Wear OS 6 on devices such as the recently-launched Pixel Watch 4.

In this blog post, we’ll show how Watch Face Push (WFP) can be used in a whole host of other ways, including:

    • Dynamically theming a watch face from a photo
    • Presenting rich data or photos from online or connected data sources
    • Complementing a phone app to drive engagement

illustration of using Watch Face Push to build a watch face with dynamic colors, updated from the phone

Illustration of using Watch Face Push to build a watch face with dynamic colors, updated from the phone

The first example we’ll focus on is building a watch face with an accompanying phone app. It can apply a color theme based on a photo taken on the phone – perfect for matching your watch face to your outfit! And it’s perfect for demonstrating how Watch Face Push allows developers to bring dynamic data to the watch face.

Let’s go through some of the main techniques which combine together to make this possible:

The default watch face – bringing components together

A powerful feature of Watch Face Push is the default watch face feature. This allows the developer to provide a watch face that’s installed onto the Wear OS device at the same time as the overall app. This watch face is bundled as an APK and placed in the assets directory in the app.

The system checks for the presence of this APK as the app is being installed, and it checks for the validation key in the app’s manifest.

This enables you to deliver a single package that contains both the watch face and app components, whether that’s a full Wear OS app, where the app is the primary focus, or app components such as complication providers, where the watch face is the primary focus.

In our project structure, we define two modules, wear and watchface. By using a unified versionCode across both, we can keep the app and watch face versions in sync. We use Gradle to build the watch face and generate the validation token. This makes it easy to treat the watch face and the app as part of the same project.

Complication data sources – pipelines for data

Now that we’ve successfully supplied both watch face and app components together, we need a way to provide data.

The watch face is now able to rely on the presence of complication data sources provided by the app. For example, a surfing watch face could bundle with a water temperature complication. This can be set as the default on the watch face using DefaultProviderPolicy and is guaranteed to be present.

Taking it a step further, we can configure the complication to be non-customizable, so that the complication becomes more of a custom data source. We can then use the complication however the watch face may need:

<ComplicationSlot isCustomizable="FALSE" ... >
    <DefaultProviderPolicy
        defaultSystemProvider="NEXT_EVENT"
        defaultSystemProviderType="SHORT_TEXT"
        primaryProvider="<my_component_path>"
        primaryProviderType="SHORT_TEXT" />

   <!-- Rest of complication goes here -->

</ComplicationSlot>

In the case of our watch face, we define a SHORT_TEXT complication service PaletteComplicationService, which sends the following data:

TEXT: <space-delimited list of RGB hex values>
TITLE: CONFIGURED | NOT_CONFIGURED

By using two of the fields on SHORT_TEXT, we’re able to send our color palette to the watch face, along with an indicator of whether the app has been configured (more on why that is important later).

Extracting and manipulating complication data

We’ve demonstrated how using the guaranteed presence of the PaletteComplicationService allows us to ensure the watch face can receive our data, but we still need to define how to use and show the data within watch face elements.

Within the ComplicationSlot element on the watch face, these data items can be accessed as COMPLICATION.TEXT and COMPLICATION.TITLE respectively. The various functions such as abs() and subText() can be used to extract parts of these strings, or convert them into numeric types.

We combine this with the use of REFERENCE to define colors. We can retrieve these colors everywhere on the watch, including outside of the ComplicationSlot:

<ComplicationSlot ...
    isCustomizable="FALSE"
    x="0" y="0" width="1" height="1">
  <DefaultProviderPolicy
      defaultSystemProvider="NEXT_EVENT"
      defaultSystemProviderType="SHORT_TEXT"
    primaryProvider="com.example.palette/com.example.palette.complication.PaletteComplicationService"
      primaryProviderType="SHORT_TEXT" />
  <BoundingBox height="1" width="1" x="0" y="0" />
  <Complication> 

    <!-- Complication data source sends 3 RGB hex values, extract the first: -->
    <PartDraw x="0" y="0" width="1" height="1">
      <Transform target="tintColor" value="extractColorFromColors([COMPLICATION.TEXT], false, 0.0)" />
      <Reference source="tintColor" defaultValue="#000000" name="primary_color" />
      <Line startX="0" startY="0" endX="1" endY="1">
        <Stroke color="#000000" thickness="1" />
      </Line>
    </PartDraw>

    ...
  </Complication>
</ComplicationSlot>

This snippet illustrates creating a very small ComplicationSlot, which will simply serve as a pipeline for our data:

Within the complication, a placeholder PartDraw is created, and the extractColorFromColors() function is used to transform the PartDraw to the first color supplied by the complication. Using the Reference element, this color value is then available to the rest of the watch face as [REFERENCE.primary_color].

In the full example, two more PartDraw elements are used to provide the secondary_color and tertiary_color, simply providing the 0.5 and 1.0 index to the extractColorFromColors function instead of the 0.0 value.

Some of the samples illustrate how you can share different data types beyond just colors, such as numeric values.

Referencing complication data in the watch face

The primary_color, secondary_color and tertiary_color values can now be used elsewhere on the watch face, both in expressions and in transforms. In our example, we use the colors on the watch face hands:

<HourHand resource="hour" x="210" y="75" width="30" height="180" pivotX="0.5"
    pivotY="0.8333" tintColor="[REFERENCE.primary_color]">
</HourHand>

// Similar logic for the minute hand and second hand would refer to
// secondary_color and tertiary_color, respectively.

Keeping the watch face package up to date

A challenge with the default watch face approach is that if the app is updated, the watch face doesn’t automatically get updated with it, even if the new app bundle contains an updated watch face. To address that issue, the app uses a BroadcastReceiver to receive the MY_PACKAGE_REPLACED action. On receiving this, the app can then check whether the watch face is installed and is in need of an upgrade, using Watch Face Push to perform the upgrade if necessary.

For the MY_PACKAGE_REPLACED action to be received, the app must have been run at least once. For this reason, the sample watch faces include an example of ensuring the user launches the app: A “launch app” button is shown on the watch face if the app has not been launched before. This is achieved by using a Condition on the CONFIGURED or NOT_CONFIGURED status described earlier.

For many watch faces, this has an additional purpose: it allows the user to enable additional components, such as a photo downloader in the Photo Album example shown here. You can also use the “first launch” experience to prompt the user to grant permissions or to sign in.

three side-by-side watch faces illistrating the supporting download service from the watch face

Enabling the supporting download service from the watch face

Working with other app components

While the complication data source is the conduit for data, and is the common component in all the examples, the following Android APIs work with complications to achieve the desired functionality:

    • WearableListenerService – both the PaletteWatchFace and the FootballWatchFace have phone companion apps, and the Data Layer is used to send data to the watch. Once received by the WearableListenerService, you can proactively update the data on the watch face using ComplicationDataSourceUpdateRequester.
    • WorkManager – the PhotoAlbumWatchFace example demonstrates how to retrieve photos from an online photo service. WorkManager is used for this, using Constraints to only download images while the device is being charged.
    • ForegroundService – the DeviceDataWatchFace illustrates using a ForegroundService to obtain data from a connected Bluetooth device which is then visualized on the watch face.

samples made using WFP

Additional samples made using WFP, starting top left: Photo Album, Surfing, Connected Device, and Football Team watch faces

Check out the full source for these examples. We look forward to seeing what you can create!

The post Further explorations with Watch Face Push appeared first on InShot Pro.

]]>
Building experiences for Wear OS https://theinshotproapk.com/building-experiences-for-wear-os/ Wed, 03 Sep 2025 12:01:09 +0000 https://theinshotproapk.com/building-experiences-for-wear-os/ Posted by Michael Stillwell – Developer Relations Engineer This post is part of Wear OS Spotlight Week. Today, we’re focusing ...

Read more

The post Building experiences for Wear OS appeared first on InShot Pro.

]]>

Posted by Michael Stillwell – Developer Relations Engineer

This post is part of Wear OS Spotlight Week. Today, we’re focusing on creating engaging experiences across the various surfaces available on the wrist.

Developing for the growing ecosystem of Wear OS is a unique and rewarding challenge that encourages you to think beyond mobile patterns. Wear’s design philosophy focuses on crafting experiences for a device that’s always with the user, where meaningful interactions take seconds, not minutes. A successful wearable app doesn’t attempt to maximize screen time; it instead aims to deliver meaningful glanceable experiences that help people stay present and productive while on the go. This vision is now fully enabled by the next generation of hardware, which we explored last week with the introduction of the new Pixel Watch 4.

Wear OS devices also introduce constraints that push you to innovate. Power efficiency is critical, requiring you to build experiences that are both beautiful and battery-conscious. You’ll also tackle challenges like handling offline use cases and catering for a variety of screen sizes.

Despite these differences, you’ll find yourself on familiar technical foundations. Wear OS is based on Android, which means you can leverage your existing knowledge of the platform, architecture, developer APIs, and tools to create wearable experiences.

Wear OS surfaces

Wear OS offers a range of surfaces to inform and engage users. This allows you to tailor your app’s presence on the watch, providing the right information at the right time and scaling your development investment to best meet your users’ needs.

Watch faces display the time and are the first thing a user sees when they look at their watch. We’ll cover watch faces in more detail in other blog posts across Wear OS Spotlight week.

A round, analog Wear OS watch face

The Watch face is the first thing a user sees when they look at their watch

Apps provide a richer, more immersive UI for complex tasks that are too involved for other surfaces.

A scrollable app experience on a round, digital watch face showing daily goals for drinking water, vegtable consumption, and fiber intake

Apps support complex tasks and can scroll vertically

Notifications provide glanceable, time-sensitive information and actions.

A calendar notification for a dentist appointment on a round watch face

A notification provides glanceable, time-sensitive information

Complications display highly-glanceable, relevant data from your app directly on the user’s chosen watch face. Learn more about building complication data sources for Wear OS.

A complications display on a round watch face

Complications display glanceable data from your app directly on the user’s watch face.

Tiles (Widgets for Wear OS) offer fast, predictable access to information and actions with a simple swipe from the watch face.

An example of a tile conveying information for daily step count on a round watch face

Tiles offer fast, predictable information and actions

Whilst a variety of Wear OS surfaces let developers to engage with users in different ways, it may be overwhelming to get started. We recommend approaching Wear OS development in phases and scale up your investment over time:

illustration of the recommended 3-step Wear OS development process

Recommended Wear OS development phases: enhance the wearable experience of your Android app, build Tiles and complications, and then create a complete wearable experience.

    • Improve the wearable experience of your mobile app. You can improve the wearable experience with minimal effort. By default, notifications from your phone app are automatically bridged to the watch. You can start by enhancing these with wearable-specific actions using NotificationCompat.WearableExtender, offering a more tailored experience without building a full Wear OS experience.
    • Build a companion experience. When you’re ready for a dedicated UI, create a tethered app experience that depends on the phone app for its core features and data. This involves creating a tethered app that works in tandem with your phone app, allowing you to design a customized UI for the wrist and take advantage of surfaces like tiles and complications.
    • Graduate to a standalone app. Finally, you can evolve your app into a standalone experience that works independently of a phone, which is ideal for offline scenarios like exercising. This provides the most flexibility but also requires more effort to optimize for constraints like power efficiency.

Notifications

Notifications are a core part of the Wear OS experience, delivering glanceable, time-sensitive information and actions for the user. Because Wear OS is based on Android, it shares the same notification system as mobile devices, letting you leverage your existing knowledge to build rich experiences for the wrist.

From a development perspective, it helps to think of a notification not as a simple alert, but as a declarative UI data structure that is shared between the user’s devices. You define the content and actions, and the system intelligently renders that information to best suit the context and form factor. This declarative approach has become increasingly powerful. On Wear OS, for example, it’s the mechanism behind ongoing activities.

Alert-style notifications

One great thing about notifications is that you don’t even need a Wear OS app for your users to see them on their watch. By default, notifications generated by your phone app are automatically “bridged”, or mirrored, to a connected watch, providing an instant wearable presence for your app with no extra work. These bridged notifications include an action to open the app on the phone.

You can enhance this default behavior by adding wearable-specific functionality to your phone notifications. Using NotificationCompat.WearableExtender, you can add actions that only appear on the watch, offering a more tailored experience without needing to build a full Wear OS app.

// Prerequisites:
//
//   1. You've created the notification channel CHANNEL_ID
//   2. You've obtained the POST_NOTIFICATIONS permission

val channelId = "my_channel_id"
val sender = "Clem"
val subject = "..."

val notification =
    NotificationCompat.Builder(applicationContext, channelId)
        .apply {
            setContentTitle("New mail from $sender")
            setContentText(subject)
            setSmallIcon(R.drawable.new_mail_mobile)
            // Added for Wear OS
            extend(
                NotificationCompat.WearableExtender().apply {
                    setSmallIcon(R.drawable.new_mail_wear)
                }
            )
        }
        .build()

NotificationManagerCompat.from(applicationContext).notify(0, notification)

Prevent duplicate notifications

Once you build a dedicated app for Wear OS, you’ll need to develop a clear notification strategy to avoid a common challenge: duplicate notifications. Since notifications from your phone app are bridged by default, a user with both your phone and watch apps installed could see two alerts for the same event.

Wear OS provides a straightforward way to manage this:

  1. On the mobile app’s notification, assign a string identifier using setBridgeTag().
  2. In your Wear OS app, you can then programmatically prevent notifications with certain tags from being bridged using a BridgingConfig. This gives you fine-grained control, allowing you to bridge some notifications while handling others natively in your Wear OS app.

If your mobile and watch apps generate similar but distinct notifications, you can link them using setDismissalId(). When a user dismisses a notification on one device, any notification with the same dismissal ID on another connected device is also dismissed.

Creating interactive experiences

From a user’s perspective, apps and tiles may feel very similar. Both are full-screen experiences that are visually rich, support animations, and handle user interaction. The main differences are in how they are launched, and their specific capabilities:

    • Apps can be deeply immersive and handle complex, multi-step tasks. They are the obvious choice when handling data that must be synced between the watch app and its associated phone app, and the only choice for long-running tasks like tracking workouts and listening to music.
    • Tiles are designed for fast, predictable access to the information and actions users need most, providing glanceable content with a simple swipe from the watch face. Think of tiles as widgets for Wear OS.

Apps and tiles are built using distinct technologies. Apps can be built with Jetpack Compose, while tiles are defined declaratively using the ProtoLayout library. This distinction allows each surface to be highly optimized for its specific role – apps can provide rich, interactive experiences while tiles remain fast and power-efficient.

Building apps

Apps provide the richest experience on Wear OS. Jetpack Compose for Wear OS is the recommended UI toolkit for building them – it works seamlessly with other Jetpack libraries and accelerates development productivity. Many prominent apps, like Gmail, Calendar and Todoist, are built entirely with Compose for Wear OS.

Compose for Wear OS for beautiful UIs

If you’ve used Jetpack Compose for mobile development, you’ll find that Compose for Wear OS shares the same foundational principles and mental model. However, building for the wrist requires some different techniques, and the toolkit provides a specialized UI component library optimized for watches.

Wear OS has its own dedicated Material Design, foundation, and navigation libraries to use instead of the mobile Jetpack libraries. These libraries provide UI components tailored for round screens and glanceable interactions, and are each supported by Android Studio’s preview system.

    • Lists: On mobile, you might use a LazyColumn to display a vertical collection of items. On Wear OS, the TransformingLazyColumn is the equivalent component. It supports scaling and transparency effects to items at the edge of a round screen, improving legibility. It also has built-in support for scrolling with rotary input.
    • Navigation: Handling screen transitions and the back stack also requires a component that’s specific to Wear OS. Instead of the standard NavHost, you must use SwipeDismissableNavHost. This component works with the system’s swipe-to-dismiss gesture, ensuring users can intuitively navigate back to the previous screen.

Learn how to use Jetpack Compose on Wear OS to get started, including sample code.

Implementing core app features

Wear OS also provides APIs designed for power efficiency and the on-wrist use case, as well as Wear OS versions of mobile APIs:

    • Authentication: Credential Manager API unifies the user sign-in process and supports modern, secure methods like passkeys, passwords, and federated identity services (like Sign-in with Google), providing a seamless and secure experience without relying on a companion phone.
    • Health and Fitness (sensor data): While you can use the standard Android Sensor APIs, it’s not recommended for performance reasons, especially for long-running workouts. Instead, use Health Services on Wear OS. It acts as an intermediary to the various sensors, providing your app with batched, power-efficient updates for everything from heart rate to running metrics, without needing to manage the underlying sensors directly.

Building tiles

Tiles offer quick, predictable access to the information and actions users need most, accessible with a simple swipe from the watch face. By using platform data bindings to display sources like step count or heart rate, you can provide timely and useful information in your tile.

Tiles are built declaratively using the ProtoLayout libraries, which are optimized for performance and power efficiency—critical considerations on a wearable device. Learn more about how to get started with tiles and how to make use of sample tile layouts.

More resources for building experiences for Wear OS

    • Wear OS Documentation Hub: The essential resource for developers looking to create experiences for Wear OS, from design guidelines to code samples.
    • WearTilesKotlin sample app: Demonstrates the fundamentals of building a tile but also includes templates for common layouts, letting you quickly bootstrap your own designs while following best practices.

There has never been a better time to start building for Wear OS. If you have feedback on the APIs, please let us know using the issue trackers for Wear Compose and Tiles. We look forward to seeing what you build!

The post Building experiences for Wear OS appeared first on InShot Pro.

]]>
A comprehensive workflow from design to device: Introducing Watch Face Designer https://theinshotproapk.com/a-comprehensive-workflow-from-design-to-device-introducing-watch-face-designer/ Tue, 02 Sep 2025 12:33:11 +0000 https://theinshotproapk.com/a-comprehensive-workflow-from-design-to-device-introducing-watch-face-designer/ Posted by Anoushka Mazumdar – Product Manager, and Adam Soutar – Software Engineer This post is part of Wear OS ...

Read more

The post A comprehensive workflow from design to device: Introducing Watch Face Designer appeared first on InShot Pro.

]]>

Posted by Anoushka Mazumdar – Product Manager, and Adam Soutar – Software Engineer

This post is part of Wear OS Spotlight Week. Today, we’re exploring the wonderful world of watch faces.

Create simple no code watch faces or build complex ones quickly with this Figma plugin

We’re thrilled to introduce Watch Face Designer, a new design tool that can empower everyone, from seasoned designers to passionate enthusiasts, to craft watch faces directly in Figma. This Figma plugin works seamlessly on devices running Wear OS 4 or higher. Say goodbye to complex coding and hello to seamless design!

Watch Face Designer is built from the ground up to integrate with the Watch Face Format for Wear OS. It’s not only for designers looking to bring their visions to life without a single line of code; it’s also a powerful tool for developers who want to rapidly prototype and mock up watch faces before diving into more intricate functionality, such as animations, in Android Studio.

screenshot showing a recreation of the Concentric watch face alongside the Watch Face Designer UI

A screenshot showing a recreation of the Concentric watch face alongside the Watch Face Designer UI

Design at the speed of thought with Watch Face Designer

This initial version of Watch Face Designer has plenty of features to kickstart your watch face design journey:

    • Supports core Watch Face Format features: digital and analog time, interactive and ambient mode, custom fonts, complications, automatic theme creation from your Figma styles, and more.
    • Intuitive plugin window: The plugin window provides a streamlined interface to preview your designs in real-time and effortlessly edit individual elements to support watch face functionality.
    • Flexible export options: Once your design is complete, you can export your design in several ways:
        • Direct to Play Store (recommended for designers): Publish your watch face directly to the Google Play Store.
        • Export to Android Studio (recommended for developers) or Watch Face Studio: For developers or those seeking to add advanced functionality, seamlessly export your design to Android Studio or Watch Face Studio to build upon your foundation.
        • View on device: See your watch face come to life on your actual Wear OS device for a true-to-life preview.
        • screenshot showing the Watch Face Designer UI with a list of export options

          The Watch Face Designer UI displaying a list of export options

Get started today

Ready to start designing your next favorite watch face? Get started with the Watch Face Designer plugin. It can be found on the @androiddesign page on Figma’s Community tab. There you can also find our Playground file featuring sample watch faces, and handy complication templates. We’ve also included a comprehensive overview guide that walks you through the process, from concept to completion.

We can’t wait to see the incredible watch faces you’ll create with Watch Face Designer! Stay tuned for more updates and exciting new features coming soon.

The post A comprehensive workflow from design to device: Introducing Watch Face Designer appeared first on InShot Pro.

]]>