Membuat Kartu pertama di Wear OS

1. Pengantar

Tiga kartu: kebugaran, pesan, kalender.

Kartu Wear OS menyediakan akses mudah ke informasi dan tindakan yang dibutuhkan pengguna untuk menyelesaikan berbagai hal. Hanya dengan menggeser dari tampilan jam, pengguna dapat mengetahui perkiraan cuaca terbaru atau memulai timer.

Kartu berjalan sebagai bagian dari UI sistem, bukan berjalan di container aplikasinya sendiri. Kita menggunakan Service untuk mendeskripsikan tata letak dan konten kartu. UI sistem kemudian akan merender kartu saat diperlukan.

Yang akan Anda lakukan

656045bed9c45083.png

Anda akan membuat kartu untuk aplikasi pesan, yang menampilkan percakapan terbaru. Dari platform ini, pengguna dapat langsung melakukan tiga tugas umum:

  • Membuka percakapan
  • Menulis pesan baru

Yang akan Anda pelajari

Dalam codelab ini, Anda akan mempelajari cara menulis Kartu Wear OS Anda sendiri, termasuk cara:

  • Membuat TileService
  • Menguji kartu di perangkat
  • Melakukan pratinjau UI untuk kartu di Android Studio
  • Mengembangkan UI untuk kartu
  • Menambahkan gambar
  • Menangani interaksi

Prasyarat

  • Pemahaman dasar tentang Kotlin

2. Mempersiapkan

Pada langkah ini, Anda akan menyiapkan lingkungan dan mendownload project awal.

Yang akan Anda butuhkan

Jika Anda tidak terbiasa menggunakan Wear OS, membaca panduan cepat ini sebelum memulai akan membantu. Panduan ini berisi petunjuk untuk menyiapkan emulator Wear OS dan menjelaskan cara bernavigasi di dalam sistem.

Mendownload kode

Jika sudah menginstal git, Anda dapat menjalankan perintah di bawah ini untuk meng-clone kode dari repositori ini.

git clone https://github.com/android/codelab-wear-tiles.git
cd codelab-wear-tiles

Jika tidak memiliki git, Anda dapat mengklik tombol berikut untuk mendownload semua kode untuk codelab ini:

Membuka project di Android Studio

Pada jendela "Welcome to Android Studio", pilih c01826594f360d94.png Open an Existing Project atau File > Open, lalu pilih folder[Download Location].

3. Membuat kartu dasar

Titik entri untuk kartu adalah layanan kartu. Pada langkah ini, Anda akan mendaftarkan layanan kartu dan menentukan tata letak kartu.

HelloWorldTileService

Class yang menerapkan TileService harus menentukan dua metode:

  • onTileResourcesRequest(requestParams: ResourcesRequest): ListenableFuture<Resources>
  • onTileRequest(requestParams: TileRequest): ListenableFuture<Tile>

Metode pertama menampilkan objek Resources yang memetakan ID string ke resource gambar yang akan kita gunakan dalam kartu.

Metode kedua menampilkan deskripsi kartu, termasuk tata letaknya. Di sini,kita menentukan tata letak kartu dan cara data terikat dengannya.

Buka HelloWorldTileService.kt dari modul start. Semua perubahan yang akan Anda buat ada dalam modul ini. Ada juga modul finished jika Anda ingin melihat hasil codelab ini.

HelloWorldTileService memperluas SuspendingTileService, yaitu wrapper yang cocok untuk coroutine Kotlin dari library Kartu Horologist. Horologist adalah sekumpulan library dari Google yang bertujuan melengkapi developer Wear OS dengan fitur yang umumnya diperlukan oleh developer, tetapi belum tersedia di Jetpack.

SuspendingTileService menyediakan dua fungsi penangguhan yang merupakan coroutine yang setara dengan fungsi dari TileService:

  • suspend resourcesRequest(requestParams: ResourcesRequest): Resources
  • suspend tileRequest(requestParams: TileRequest): Tile

Untuk mempelajari lebih lanjut coroutine, lihat dokumentasi untuk coroutine Kotlin di Android.

HelloWorldTileService belum selesai. Kita harus mendaftarkan layanan dalam manifes dan juga perlu menyediakan implementasi untuk tileLayout.

Mendaftarkan layanan kartu

Setelah layanan kartu didaftarkan dalam manifes, layanan akan muncul dalam daftar kartu yang tersedia untuk ditambahkan oleh pengguna.

Tambahkan <service> di dalam elemen <application>:

start/src/main/AndroidManifest.xml

<service
    android:name="com.example.wear.tiles.hello.HelloWorldTileService"
    android:icon="@drawable/ic_waving_hand_24"
    android:label="@string/hello_tile_label"
    android:description="@string/hello_tile_description"
    android:exported="true"
    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_hello" />
</service>

Ikon dan label digunakan (sebagai placeholder) saat kartu dimuat untuk pertama kalinya, atau jika terjadi error saat memuat kartu. Meta-data di bagian akhir menentukan gambar pratinjau yang ditampilkan dalam carousel saat pengguna menambahkan kartu.

Menentukan tata letak kartu

HelloWorldTileService memiliki fungsi bernama tileLayout dengan TODO() sebagai isi. Sekarang, mari ganti fungsi tersebut dengan implementasi yang dapat kita gunakan untuk menentukan tata letak kartu:

start/src/main/java/com/example/wear/tiles/hello/HelloWorldTileService.kt

fun tileLayout(
    context: Context,
    deviceConfiguration: DeviceParametersBuilders.DeviceParameters,
    message: String,
) =
    materialScope(
        context = context,
        deviceConfiguration = deviceConfiguration,
        allowDynamicTheme = false,
    ) {
        primaryLayout(mainSlot = { text(message.layoutString) })
    }

Dan itu adalah Kartu Wear OS pertama Anda yang dibuat. Mari kita instal kartu ini dan lihat bagaimana tampilannya.

4. Menguji kartu di perangkat

Dengan modul awal yang dipilih di dropdown konfigurasi run, Anda dapat menginstal aplikasi (modul start) di perangkat atau emulator dan menginstal kartu secara manual, seperti yang dilakukan pengguna.

Namun, Android Studio memiliki pintasan untuk melakukannya: dengan mengetuk ikon "run service" (▷) di gutter, lalu memilih "Run 'HelloWorldTileService'", tindakan ini akan menginstal dan meluncurkan kartu di perangkat terhubung.

ded9f9355abd02f3.png

Pilih "Run 'HelloWorldTileService'" untuk membangun dan menjalankan kartu di perangkat terhubung. Tampilannya akan terlihat seperti screenshot di bawah.

693c130912097be6.png

Ikon "tangan melambai" yang muncul di bagian atas layar disediakan oleh sistem. Untuk mengubahnya, ubah properti android:icon elemen <service> kartu di manifes.

Untuk memudahkan, proses ini juga akan membuat "HelloWorldTileService" "run configuration" untuk penggunaan mendatang.

b3335148771abbeb.png

5. Menambahkan fungsi pratinjau

Kita dapat melihat pratinjau UI kartu di Android Studio. Hal ini mempersingkat feedback loop saat mengembangkan UI, sehingga meningkatkan kecepatan pengembangan.

Tambahkan pratinjau kartu untuk HelloWorldTileService di akhir file HelloWorldTileService.kt.

start/src/main/java/com/example/wear/tiles/hello/HelloWorldTileService.kt

@Preview(device = WearDevices.SMALL_ROUND, name = "Small Round")
@Preview(device = WearDevices.LARGE_ROUND, name = "Large Round")
internal fun helloLayoutPreview(context: Context): TilePreviewData {
    return TilePreviewData {
        TilePreviewHelper.singleTimelineEntryTileBuilder(
            helloLayout(context, it.deviceConfiguration, "Hello, preview tile!")
        )
            .build()
    }
}

Gunakan mode editor "Split" (Terpisah) untuk melihat pratinjau kartu:

tampilan layar terpisah Android Studio dengan kode pratinjau di sebelah kiri dan gambar kartu di sebelah kanan.

Perlu diperhatikan bahwa anotasi @Composable tidak digunakan—meskipun Kartu menggunakan UI pratinjau yang sama seperti Fungsi composable, Kartu tidak menggunakan Compose, dan bukan merupakan composable.

6. Membuat kartu pesan

cf18db0f604b1999.png

Kartu pesan yang akan kita buat lebih mirip dengan kartu di dunia nyata. Tidak seperti contoh HelloWorld, contoh ini menunjukkan komponen Material 3 Ekspresif, menampilkan gambar, dan menangani interaksi untuk membuka aplikasi.

MessagingTileService

MessagingTileService memperluas class SuspendingTileService yang telah kita lihat sebelumnya.

7. Menambahkan Komponen UI

Library ProtoLayout menyediakan komponen dan tata letak bawaan, sehingga Anda dapat membuat kartu yang menggunakan desain Material 3 Ekspresif terbaru untuk Wear OS.

Tambahkan dependensi Tiles Material ke file build.gradle Anda:

start/build.gradle

implementation "androidx.wear.protolayout:protolayout-material3:$protoLayoutVersion"

Tambahkan kode tata letak ke fungsi tileLayout(), sebagai isi fungsi materialScope(). Tindakan ini akan membuat tata letak yang terdiri dari dua baris (masing-masing dengan dua tombol), dan tombol tepi.

Temukan baris "TODO() // Add primaryLayout()" dan ganti dengan kode di bawah ini.

start/src/main/java/com/example/wear/tiles/messaging/tile/Layout.kt

primaryLayout(
    mainSlot = {
        // This layout code assumes "contacts" contains at least 4 elements, for sample code
        // that can handle an arbitrary number of contacts, and also shows different numbers
        // of contacts based on the physical screen size, see
        // <https://github.com/android/wear-os-samples/tree/main/WearTilesKotlin>.
        Column.Builder()
            .apply {
                setWidth(expand())
                setHeight(expand())
                addContent(
                    buttonGroup {
                        buttonGroupItem { contactButton(contacts[0]) }
                        buttonGroupItem { contactButton(contacts[1]) }
                    }
                )
                addContent(DEFAULT_SPACER_BETWEEN_BUTTON_GROUPS)
                addContent(
                    buttonGroup {
                        buttonGroupItem { contactButton(contacts[2]) }
                        buttonGroupItem { contactButton(contacts[3]) }
                    }
                )
            }
            .build()
    },
    bottomSlot = {
        textEdgeButton(
            onClick = clickable(), // TODO: Launch new conversation activity
            labelContent = { text("New".layoutString) },
        )
    },
)

Fungsi contactButton() dalam file yang sama akan membuat setiap tombol kontak. Jika kontak memiliki gambar terkait, gambar tersebut akan muncul di tombol. Jika tidak, inisial kontak akan digunakan.

Pada tahap ini, Anda mungkin melihat bahwa meskipun tata letak umumnya sudah benar, gambarnya tidak ada:

809bdb9d1213c376.png

Anda akan melihat hal yang sama jika men-deploy kartu ke perangkat:

4671bb2eafdcc528.png

Pada langkah berikutnya, kita akan memperbaiki gambar yang hilang.

8. Menambahkan gambar

Pada level tinggi, Kartu terdiri dari dua hal: tata letak (yang mereferensikan resource berdasarkan ID string) dan resource itu sendiri (yang dapat berupa gambar).

Saat ini, kode kita menyediakan tata letak, tetapi bukan resource itu sendiri. Untuk memperbaiki pratinjau, kita perlu memberikan "resource" gambar. Untuk melakukannya, temukan "TODO: Add onTileResourceRequest" dan tambahkan kode di bawah sebagai argumen bernama tambahan ke TilePreviewData():

start/src/main/java/com/example/wear/tiles/messaging/tile/Layout.kt

// Additional named argument to TilePreviewData
onTileResourceRequest = { resourcesRequest ->
    Resources.Builder()
        .setVersion(resourcesRequest.version)
        .apply {
            contacts.forEach {
                if (it.avatarSource is AvatarSource.Resource) {
                    addIdToImageMapping(
                        it.imageResourceId(),
                        it.avatarSource.resourceId
                    )
                }
            }
        }
        .build()
}

Gambar kini akan muncul di pratinjau:

e77d746268f293f2.png

Namun, jika kartu di-deploy ke perangkat, gambar tidak ada. Untuk memperbaikinya, ganti fungsi resourcesRequest() di Service.kt dengan yang berikut:

start/src/main/java/com/example/wear/tiles/messaging/tile/Service.kt

override suspend fun resourcesRequest(
    requestParams: ResourcesRequest
): Resources {
    // resourceIds is a list of the ids we need to provide images for. If we're passed an empty
    // list, set resourceIds to all resources.
    val resourceIds =
        requestParams.resourceIds.ifEmpty {
            contacts.map { it.imageResourceId() }
        }

    // resourceMap maps (tile) resource ids to (Android) resource ids.
    val resourceMap =
        contacts
            .mapNotNull {
                when (it.avatarSource) {
                    is AvatarSource.Resource ->
                        it.imageResourceId() to
                            it.avatarSource.resourceId
                    else -> null
                }
            }
            .toMap()
            .filterKeys {
                it in resourceIds
            } // filter to only the resources we need

    // Add images in the resourceMap to the Resources object, and return the result.
    return Resources.Builder()
        .setVersion(requestParams.version)
        .apply {
            resourceMap.forEach { (id, imageResource) ->
                addIdToImageMapping(id, imageResource)
            }
        }
        .build()
}

Sekarang gambar juga ditampilkan saat kartu di-deploy ke perangkat:

cf18db0f604b1999.png

Pada langkah berikutnya, kita akan menangani klik pada setiap elemen.

9. Menangani interaksi

Salah satu hal paling berguna yang dapat kita lakukan dengan kartu adalah menyediakan pintasan ke perjalanan penting pengguna. Ini berbeda dengan peluncur aplikasi yang hanya membuka aplikasi - di sini, kita memiliki ruang untuk menyediakan pintasan kontekstual ke layar tertentu dalam aplikasi Anda.

Sejauh ini, kita telah menggunakan tindakan dummy yang disediakan oleh clickable() tanpa argumen untuk chip dan setiap tombol. Tindakan ini tidak masalah untuk pratinjau yang tidak interaktif, tetapi mari kita lihat cara menambahkan tindakan untuk elemen tersebut.

LaunchAction

LaunchAction dapat digunakan untuk meluncurkan aktivitas. Mari ubah Layout sehingga mengetuk tombol "Baru" untuk memulai perjalanan pengguna "percakapan baru".

Temukan baris "TODO: Launch new conversation activity" dan ganti clickable() dengan:

start/src/main/java/com/example/wear/tiles/messaging/tile/Layout.kt

clickable(
    id = "new_button",
    action =
        launchAction(
            ComponentName(
                "com.example.wear.tiles",
                "com.example.wear.tiles.messaging.MainActivity",
            ),
            mapOf(
                MainActivity.EXTRA_JOURNEY to
                    ActionBuilders.stringExtra(
                        MainActivity.EXTRA_JOURNEY_NEW
                    )
            ),
        ),
)

Deploy ulang kartu. Sekarang, alih-alih tidak melakukan apa pun, mengetuk "Baru" akan meluncurkan MainActivity dan memulai perjalanan pengguna "percakapan baru":

a08c28b4a142fb8f.png

Demikian pula, ubah Layout sehingga mengetuk tombol kontak akan memulai percakapan dengan pengguna tertentu.

Temukan baris "Launch open conversation activity" dan ganti clickable() dengan:

start/src/main/java/com/example/wear/tiles/messaging/tile/Layout.kt

clickable(
    id = contact.id.toString(),
    action =
        launchAction(
            ComponentName(
                "com.example.wear.tiles",
                "com.example.wear.tiles.messaging.MainActivity",
            ),
            mapOf(
                MainActivity.EXTRA_JOURNEY to
                    ActionBuilders.stringExtra(
                        MainActivity
                            .EXTRA_JOURNEY_CONVERSATION
                    ),
                MainActivity.EXTRA_CONVERSATION_CONTACT to
                    ActionBuilders.stringExtra(
                        contact.name
                    ),
            ),
        ),
)

Deploy ulang kartu. Sekarang, Anda dapat memulai percakapan dengan kontak dengan mengetuk kontak tersebut:

b684a1ced0b226f9.png

10. Selamat

Selamat! Anda telah mempelajari cara membuat kartu untuk Wear OS.

Apa selanjutnya?

Untuk informasi selengkapnya, lihat penerapan Golden Tiles di GitHub, panduan Kartu Wear OS dan panduan desain.