Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Make time count with Wear OS 🤖⌚️

Make time count with Wear OS 🤖⌚️

This talk will teach you about building Wear OS applications with Compose and Material Design. I will discuss my process of creating a countdown application with Jetpack Compose, Tiles and the Horologist APIs. You will also learn how to test your application on a Wear emulator.

You will leave this talk ready to (re)build your Wear OS applications with Jetpack Compose and Material Design.

Moyinoluwa Adeyemi

November 28, 2022
Tweet

More Decks by Moyinoluwa Adeyemi

Other Decks in Technology

Transcript

  1. Lagos Moyin Adeyemi Android GDE Make time count with Wear

    OS
  2. Lagos Moyin Adeyemi Android GDE Make time count with Wear

    OS
  3. “This talk will teach you about building Wear OS applications

    with Compose and Material Design. I will discuss my process of creating a countdown application with Jetpack Compose, Tiles and the Horologist APIs. You will also learn how to test your application on a Wear emulator. You will leave this talk ready to (re)build your Wear OS applications with Jetpack Compose and Material Design.”
  4. Case Study: Confetti https://github.com/joreilly/Confetti

  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. None
  13. None
  14. None
  15. What is important for Confetti Wear?

  16. “Focus on one or two needs of your target users

    rather than a full app experience. Don't migrate an entire mobile codebase and put a Wear OS user interface on top. Instead, find critical tasks that work well on the wrist and streamline the experience on Wear OS.” https://developer.android.com/training/wearables/design/getting-started
  17. P0 What talk is happening now? What talk is happening

    next? Confetti Wear
  18. P1 Tell me more about this talk Confetti Wear

  19. P1 Tell me more about this talk Confetti Wear P2

    Tell me more about the speakers
  20. P3 Navigate to the conference venue Confetti Wear

  21. P0 What talk is happening now/next?

  22. https://developer.android.com/training/wearables/principles#appropriate-surface Now called “Apps”

  23. An entrypoint into your application. Like app widgets, but for

    Wear OS
  24. Confetti Wear A tale of two tiles Next Current Session

  25. None
  26. Horologist Horologist is a group of libraries that aim to

    supplement Wear OS developers with features that are commonly required by developers but not yet available. https://github.com/google/horologist#-tiles
  27. Horologist

  28. Android Studio 2021.3.1 or newer

  29. Jetpack Compose?

  30. Jetpack Compose? ❌ (not for tiles 🥲)

  31. SuspendingTileService class ConfettiWearTileService : SuspendingTileService() { override suspend fun resourcesRequest(

    requestParams: RequestBuilders.ResourcesRequest ): ResourceBuilders.Resources {} override suspend fun tileRequest( requestParams: RequestBuilders.TileRequest ): TileBuilders.Tile {} }
  32. SuspendingTileService class ConfettiWearTileService : SuspendingTileService() { override suspend fun resourcesRequest(

    requestParams: RequestBuilders.ResourcesRequest ): ResourceBuilders.Resources {} override suspend fun tileRequest( requestParams: RequestBuilders.TileRequest ): TileBuilders.Tile {} }
  33. SuspendingTileService class ConfettiWearTileService : SuspendingTileService() { override suspend fun resourcesRequest(

    requestParams: RequestBuilders.ResourcesRequest ): ResourceBuilders.Resources {} override suspend fun tileRequest( requestParams: RequestBuilders.TileRequest ): TileBuilders.Tile {} }
  34. tileRequest() override suspend fun tileRequest( requestParams: RequestBuilders.TileRequest ): TileBuilders.Tile {

    ... return TileBuilders.Tile.Builder() .setResourcesVersion(RESOURCES_VERSION) .setTimeline(singleTileTimeline) .build() }
  35. singleTileTimeline val singleTileTimeline = TimelineBuilders.Timeline.Builder() .addTimelineEntry( TimelineBuilders.TimelineEntry.Builder() .setLayout( LayoutElementBuilders.Layout.Builder() .setRoot(

    tileLayout(...) .build() ...
  36. tileLayout() tileLayout( context = this, deviceParameters = requestParams.deviceParameters, currentSessionClickable =

    launchActivityClickable( clickableId = "current_session", androidActivity = openCurrentSession() ), nextSessionClickable = launchActivityClickable( clickableId = "next_session", androidActivity = openNextSession() ), )
  37. tileLayout() private fun tileLayout( context: Context, deviceParameters: DeviceParametersBuilders.DeviceParameters, currentSessionClickable: ModifiersBuilders.Clickable,

    nextSessionClickable: ModifiersBuilders.Clickable ): LayoutElementBuilders.LayoutElement { return PrimaryLayout.Builder(deviceParameters) ...
  38. tileLayout() return PrimaryLayout.Builder(deviceParameters) .setContent( CompactChip.Builder( context, "Happening Now!", currentSessionClickable, deviceParameters

    ) .setChipColors(ChipColors.primaryChipColors(ConfettiTileTheme.colors)) .build() ).setPrimaryChipContent( CompactChip.Builder(context, "Next talk", nextSessionClickable, deviceParameters) .setChipColors(ChipColors.secondaryChipColors(ConfettiTileTheme.colors)) .build() ) .build()
  39. return PrimaryLayout.Builder(deviceParameters) .setContent( CompactChip.Builder( context, "Happening Now!", currentSessionClickable, deviceParameters )

    .setChipColors(ChipColors.primaryChipColors(ConfettiTileTheme.colors)) .build() ).setPrimaryChipContent( CompactChip.Builder(context, "Next talk", nextSessionClickable, deviceParameters) .setChipColors(ChipColors.secondaryChipColors(ConfettiTileTheme.colors)) .build() ) .build() tileLayout()
  40. Register the Service in the AndroidManifest.xml file <service android:name=".presentation.ui.tile.ConfettiWearTileService" android:description="@string/description"

    android:exported="true" android:icon="@drawable/icon" android:label="@string/label" android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER"> <intent-filter> <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" /> </intent-filter> <!-- The tile preview shown when configuring tiles on your phone --> <meta-data android:name="androidx.wear.tiles.PREVIEW" android:resource="@drawable/tile_preview_icon" /> </service>
  41. Session Info Screen

  42. None
  43. Jetpack Compose ✅

  44. Session Info Card AppCard( modifier = Modifier .fillMaxWidth() .padding(bottom =

    8.dp), appName = { Text("Main Room") }, time = { Text("40m") }, title = { Text("Make time count with Wear OS") }, onClick = TODO() ) { Text("Moyin") }
  45. Curved “Happening Now!” Text if (LocalConfiguration.current.isScreenRound) { val happeningNow =

    stringResource(R.string.happening_now) val primaryColor = MaterialTheme.colors.primary CurvedLayout( anchor = 90F, anchorType = AnchorType.Center, modifier = Modifier.fillMaxSize() ) { curvedRow { ... }
  46. curvedRow() curvedRow { curvedText( text = happeningNow, angularDirection = CurvedDirection.Angular.CounterClockwise,

    style = CurvedTextStyle( fontSize = 18.sp, color = primaryColor ), modifier = CurvedModifier .radialGradientBackground( 0f to Color.Transparent, 0.2f to Color.DarkGray.copy(alpha = 0.2f), 0.6f to Color.DarkGray.copy(alpha = 0.2f), 0.7f to Color.DarkGray.copy(alpha = 0.05f), 1f to Color.Transparent ) )
  47. Navigating from the tile to the app

  48. None
  49. Remember the TileLayout? tileLayout( context = this, deviceParameters = requestParams.deviceParameters,

    currentSessionClickable = launchActivityClickable( clickableId = "current_session", androidActivity = openCurrentSession() ), nextSessionClickable = launchActivityClickable( clickableId = "next_session", androidActivity = openNextSession() ), )
  50. tileLayout() tileLayout( context = this, deviceParameters = requestParams.deviceParameters, currentSessionClickable =

    launchActivityClickable( clickableId = "current_session", androidActivity = openCurrentSession() ), nextSessionClickable = launchActivityClickable( clickableId = "next_session", androidActivity = openNextSession() ), )
  51. launchActivityClickable() internal fun launchActivityClickable( clickableId: String, androidActivity: ActionBuilders.AndroidActivity ) =

    ModifiersBuilders.Clickable.Builder() .setId(clickableId) .setOnClick( ActionBuilders.LaunchAction.Builder() .setAndroidActivity(androidActivity) .build() ) .build()
  52. openCurrentSession() internal fun openCurrentSession() = ActionBuilders.AndroidActivity.Builder() .setConfettiWearActivity() .addKeyToExtraMapping( MainActivity.EXTRA_SESSION, ActionBuilders.stringExtra(MainActivity.EXTRA_CURRENT_SESSION)

    ) .build()
  53. openCurrentSession() internal fun openCurrentSession() = ActionBuilders.AndroidActivity.Builder() .setConfettiWearActivity() .addKeyToExtraMapping( MainActivity.EXTRA_SESSION, ActionBuilders.stringExtra(MainActivity.EXTRA_CURRENT_SESSION)

    ) .build()
  54. setConfettiWearActivity() internal fun ActionBuilders.AndroidActivity.Builder.setConfettiWearActivity() : ActionBuilders.AndroidActivity.Builder { return setPackageName("com.devfestlagos.wearapp") .setClassName("com.devfestlagos.wearapp.presentation.MainActivity")

    }
  55. Debugging

  56. Debugging 1. Debug over Bluetooth https://developer.android.com/training/wearables/get-started/debugging

  57. Debugging 1. Debug over Bluetooth 2. Debug over Wi-Fi https://developer.android.com/training/wearables/get-started/debugging

  58. Debugging 1. Debug over Bluetooth 2. Debug over Wi-Fi 3.

    Wireless Debugging
  59. Wireless Debugging 1. Enable Developer Options on the watch

  60. 1. Enable Developer Options on the watch Settings Wireless Debugging

  61. 1. Enable Developer Options on the watch System > About

    Settings Wireless Debugging
  62. 1. Enable Developer Options on the watch System > About

    Settings Build number x7 Wireless Debugging
  63. 1. Enable Developer Options on the watch System > About

    Settings “You are now a developer!” Build number x7 Wireless Debugging
  64. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network Wireless Debugging
  65. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network Settings Wireless Debugging
  66. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network Settings Wireless Debugging Connectivity > Wi-Fi
  67. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network Settings Wireless Debugging Connectivity > Wi-Fi Connect to a network (it must be the same network the development machine is connected to)
  68. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch Wireless Debugging
  69. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch Wireless Debugging Settings
  70. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch Wireless Debugging Settings Developer Options > Wireless Debugging
  71. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch Wireless Debugging Settings Developer Options > Wireless Debugging Wireless Debugging > Pair New Device
  72. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch 4. Pair using the pairing code in Android Studio Wireless Debugging
  73. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch 4. Pair using the pairing code in Android Studio Wireless Debugging
  74. 1. Enable Developer Options on the watch 2. Connect the

    watch to a Wi-Fi network 3. Retrieve Wi-Fi pairing code from the watch 4. Pair using the pairing code in Android Studio Wireless Debugging
  75. Resources • Ataul - androiddev.social/@ataulm • d.android.com/wear • github.com/android/wear-os-samples/tree/main/ComposeAd vanced

  76. Questions?

  77. Feedback androiddev.social/@moyheen twitter.com/moyheen

  78. Lagos Moyin Adeyemi Android GDE Thank you!