Android XR

Membangun pengalaman yang ditambatkan ke dunia nyata untuk kacamata XR berkabel

Speaker

Tentang

Tentang konferensi

Melampaui ruang layar dan menambatkan aplikasi Anda di dunia nyata dengan Android XR. Sesi ini mengajarkan cara membangun pengalaman Android XR yang mendukung geospasial menggunakan Jetpack Compose Glimmer dan Geospatial API ARCore. Kita akan mulai dengan membahas cara mendapatkan pose geospasial perangkat dengan ARCore. Kemudian, Anda akan melihat cara komponen UI minimal Glimmer dapat ditambatkan ke lokasi dunia nyata melalui Visual Positioning System (VPS). Kita akan menggabungkan semua ini untuk membangun pengalaman spasial sederhana yang mendukung lokasi.

Ringkasan

  • Android XR menghadirkan pengalaman digital ke lingkungan fisik di berbagai perangkat, mulai dari kacamata AI hingga kacamata XR berkabel. Aplikasi Android 2D yang ada berfungsi di headset XR dan kacamata XR berkabel dengan sedikit modifikasi.
  • Jetpack Compose Glimmer menyediakan komponen dan gaya yang disesuaikan untuk layar tembus pandang optik. Fungsi bantuan bawaan menyesuaikan warna merek ke nuansa yang aman untuk kacamata guna mempertahankan visibilitas dan kontras di berbagai kondisi pencahayaan.
  • Library Glimmer menambahkan komponen baru seperti pager dan grup tombol. Depth API membantu memisahkan elemen bertumpuk pada layar tembus pandang yang menampilkan warna hitam sebagai transparan.
  • Composable subruang menempatkan antarmuka di ruang 3D dan dapat mengikuti anchor ARCore melalui target yang diikuti, seperti kode QR yang dilacak.
  • Geospatial API di ARCore menggabungkan data Street View dan pengukuran GPS untuk memosisikan perangkat secara akurat di area yang didukung. Anda dapat memasang komponen Glimmer ke anchor geospasial dunia nyata menggunakan koordinat dari kueri Places API.

Resource

Gemini Notebook

Topik

  • android-xr
  • jetpack-compose
  • glimmer
  • arcore
  • geospatial-api
  • augmented-reality

Transkrip

Pengantar Android XR

  • Halo semuanya, selamat datang di sesi pertama Anda di jalur Android XR di Android Developer Summit.

  • Ya!

  • Kami sangat senang melihat banyak dari Anda yang mempelajari Android XR.

  • Nama saya Yasmine Quintana Evjen, dan saya ditemani oleh Paul Hoover dan Dereck Bridie, dan mereka akan bergabung dengan kita seiring berjalannya percakapan.

  • Topik sesi ini adalah Android XR, dan cara Anda dapat membangun pengalaman dunia nyata yang ditambatkan secara spasial dengan Jetpack Compose Glimmer dan ARCore untuk Jetpack XR.

  • Namun sebelumnya, mari kita bahas pengantar singkat tentang Android XR.

  • Android XR adalah platform baru yang mendefinisikan ulang cara pengguna berinteraksi dengan aplikasi Anda, melampaui layar dan masuk ke ruang di sekitar mereka.

  • Kami mendesain platform ini untuk menghadirkan pengalaman digital langsung ke lingkungan fisik.

  • Baik itu berarti overlay sekilas yang meningkatkan kehadiran di dunia nyata atau lingkungan imersif tanpa batas.

  • Ini adalah ekosistem Android terbuka yang sama dengan yang telah kita bangun bersama selama bertahun-tahun, dan kini kanvasnya seluas ruangan dan seluas imajinasi Anda.

  • Kami melihat XR sebagai spektrum perangkat, mulai dari kacamata pintar, yang memungkinkan pengalaman augmented yang ringan pada kacamata audio dan kacamata pintar dengan layar, hingga headset imersif dan kacamata XR berkabel, yang menghadirkan kemampuan fokus, produktivitas, dan hiburan imersif.

  • Perangkat terbaru dalam rangkaian Android XR adalah XREAL AURA, yang kini tersedia untuk dibeli.

  • Perangkat ini ringan dan andal, sehingga memungkinkan pengalaman XR dengan Android yang sudah dikenal.

  • Visi kami untuk platform ini adalah jika Anda sudah mengembangkan aplikasi untuk Android, Anda siap mengembangkan aplikasi untuk XR.

  • Dengan menggunakan model aplikasi, library, dan alat yang sama yang sudah Anda kenal, kami ingin memudahkan Anda membangun aplikasi di Android XR.

  • Dengan sedikit atau tanpa modifikasi, aplikasi 2D yang kompatibel dengan Android yang ada akan berfungsi di headset Android XR dan kacamata XR berkabel.

Jetpack XR SDK dan alat developer

  • Untuk menciptakan pengalaman XR yang luar biasa dan terasa nyaman, kami menyediakan serangkaian library yang dibuat khusus untuk platform XR.

  • Bagi developer yang terbiasa membangun pengalaman di platform imersif lainnya, Anda dapat membangun dengan OpenXR dan dukungan mesin 3D kami, seperti Unity, Godot, dan Unreal.

  • Mari kita bahas cara membangun dengan library Android.

  • Kami menyediakan Jetpack XR SDK, serangkaian library Kotlin yang membantu Anda memperluas aplikasi ke XR di seluruh pengalaman imersif dan augmented.

  • Mari kita lihat library imersif kita.

  • Library Jetpack XR kami mencapai versi beta dan stabil tahun ini, sehingga memberi Anda keyakinan yang diperlukan untuk mulai membangun pengalaman XR yang imersif.

  • Lapisan persepsi adalah ARCore untuk Jetpack XR.

  • Library ini memberikan informasi tentang dunia nyata, seperti lokasi permukaan datar seperti meja, dan posisi tangan pengguna.

  • API ini dapat melacak titik dalam ruang 3D, dan memberikan informasi tersebut ke aplikasi jika diberi izin yang tepat.

  • Kemudian ada Jetpack XR SceneCore, yang menyediakan grafik tampilan untuk menempatkan konten spasial Anda.

  • Library ini mampu menampilkan entity dalam ruang 3D, memberikan perilaku spasial untuk penempatan grafik scene yang akurat.

  • Jetpack Compose untuk XR menyediakan composable subruang baru yang dibuat khusus untuk 3D.

  • Developer Android yang sudah memahami tata letak Compose, seperti membuat dengan baris dan kolom, akan merasa bahwa tata letak UI spasial terasa intuitif.

  • Dengan membuat baris spasial, Anda dapat menata letak beberapa panel spasial secara deklaratif secara berdampingan tanpa harus menghitung posisi atau ukurannya secara manual.

  • Dengan menggunakan composable subruang seperti panel spasial atau orbiter, Anda dapat dengan mudah memperluas komponen 2D ke ruang 3D baru ini.

  • Tentu saja, composable subruang mampu melakukan lebih dari sekadar menampilkan konten 2D.

  • Compose untuk XR mendukung video spasial serta model 3D melalui platform eksternal spasial dan model glTF spasial.

Membangun UI dengan Jetpack Compose Glimmer

  • Sekarang, mari kita bahas aplikasi yang ditingkatkan.

  • Dengan library Jetpack Projected, Anda dapat meningkatkan kualitas aplikasi seluler yang ada untuk memanfaatkan hardware kacamata cerdas, seperti sensor dan layar.

  • Terakhir, Jetpack Compose Glimmer, toolkit UI untuk membangun pengalaman Android XR yang dioptimalkan untuk kacamata.

  • Jetpack Compose Glimmer terdiri dari gaya dan komponen siap pakai untuk membangun pengalaman XR Anda.

  • Kami meluncurkan Glimmer tahun lalu dan terus memperluas kemampuannya, termasuk kemampuan agentic untuk membantu Anda membangun aplikasi kacamata pintar dengan layar menggunakan Glimmer.

    android skills add display-glasses-with-jetpack-compose-glimmer
  • Sejak peluncuran, kami telah mendengarkan masukan Anda.

  • Kami mendengar bahwa Anda ingin kami memperluas Jetpack Compose Glimmer di luar kacamata AI.

  • Kami dengan senang hati mengumumkan bahwa kami telah melakukan perubahan untuk mendukung pengalaman yang ditambatkan secara spasial dengan Glimmer, yang akan kita bahas lebih lanjut nanti dalam presentasi ini.

  • Upaya kami untuk mengoptimalkan Glimmer dimulai dengan membuat platform baru untuk ditampilkan di berbagai faktor bentuk XR, mulai dari layar hingga Kacamata XR Berkabel.

  • Penambahan platform baru ini memberikan lebih banyak fleksibilitas untuk menyesuaikan UI Anda.

  • Dan untuk meningkatkan keunikan brand aplikasi Anda, kami telah menambahkan warna kustom ke komponen Glimmer.

  • Gunakan ini untuk mengekspresikan gaya brand Anda di seluruh aplikasi XR.

  • Library Glimmer Jetpack Compose kami menyediakan fungsi bantuan yang mengonversi warna target dan warna merek Anda menjadi warna yang aman untuk kacamata.

  • Hal ini untuk memastikan visibilitas yang optimal pada layar tembus pandang optik.

  • Jadi, mari kita lihat penerapannya.

  • Kita ingin mengubah warna tombol yang difokuskan untuk aplikasi kacamata ini, yang akan saya pi-- pilih salah satu warna favorit saya yang luar biasa.

    val brandColor = Color(0xFFFFAABB)
    val focusedColor = ButtonDefaults.focusedColor(brandColor)
    
    Column(…) {
       LeadingImageCard(
           focusable = false,
           …
       ) {
           …
       }
       ButtonGroup(...) {
           Button(
               onClick = {},
               leadingIcon = { … },
               focusedColor = focusedColor,
           ) { Text("Add to cart") }
    
           /* Rest of the buttons */
       }
    }
  • Perhatikan bahwa saat warna ditambahkan ke kode, fungsi bantuan Glimmer akan menyesuaikannya menjadi warna yang aman untuk kacamata agar visibilitasnya optimal.

  • Semua ini dibangun dalam library Glimmer Jetpack Compose kami, sehingga memastikan Anda membangun pengalaman yang terlihat bagus di berbagai lingkungan.

  • Di Android Studio, Anda dapat menggunakan emulator untuk memvisualisasikan tampilan UI kacamata Anda di berbagai latar belakang, seperti lingkungan terang, gelap, atau ramai.

  • Pembaruan ini hanyalah permulaan.

  • Oke, tidak.

  • Tim saya bilang Anda tidak akan tertawa mendengarnya, tapi saya tetap menyimpannya.

  • Namun, sekarang saya akan menyerahkan acara kepada Paul untuk memberi tahu Anda lebih lanjut tentang Jetpack Compose Glimmer.

Prinsip desain UI untuk kacamata pintar dengan layar

  • Pengujian, oke!

  • Saya harus menekan tombol berikutnya.

  • Baiklah, terima kasih Yasmine.

  • Oke.

  • Jadi, seperti yang dikatakan Yasmine, Jetpack Compose Glimmer menyediakan elemen penyusun dasar untuk mengembangkan aplikasi yang disesuaikan untuk kacamata pintar dengan layar.

  • Komponen kami mengintegrasikan praktik terbaik yang dibuat untuk layar tembus pandang optik, dan kami membangunnya langsung ke dalam API untuk Anda, sehingga memberdayakan semua developer untuk membangun pengalaman tembus pandang optik yang indah dan fungsional.

  • Saat mendesain dan membuat aplikasi untuk perangkat optical see-through seperti ini, Anda perlu mengingat beberapa hal.

  • Pertama, layar ini transparan, yang berarti tidak ada warna hitam.

  • Saat dunia terlihat, warna hitamnya transparan.

  • Jadi, Anda tidak dapat mengandalkan latar belakang gelap untuk mempertahankan kontras UI, teks, dan konten Anda.

  • Meskipun hitam tidak terlihat, Anda dapat menggunakannya untuk mengaburkan konten digital lainnya.

  • Dalam framework UI Glimmer, kami memiliki API kedalaman yang memungkinkan Anda memisahkan elemen UI dengan mudah satu sama lain dan memberikan kesan hierarki.

  • Di sini, Anda dapat melihat bagaimana kedalaman pada kartu dalam tumpukan ini membantu kartu tetap terpisah satu sama lain.

  • Ilmuwan penglihatan kami telah memberikan rasio kontras target untuk teks dan ikon yang terlihat dalam sebagian besar kondisi pencahayaan.

  • Seperti yang ditunjukkan Yasmine, kita dapat membangun ini atau kita membangun ini ke dalam framework sehingga saat Anda menyesuaikan warna platform, Anda dapat yakin bahwa antarmuka Anda akan dapat dibaca oleh pengguna.

  • Kami telah menerapkan praktik terbaik ini dan praktik terbaik lainnya ke dalam library komponen kami yang terus berkembang.

  • Kami telah mengirimkan banyak komponen baru baru-baru ini.

  • Salah satu edisi terbaru kami adalah komponen pager dengan transisi gerakan dan gestur yang halus dan terintegrasi.

    val pagerState =
      rememberGlimmerPagerState(pageCount = { 10 })
    
    GlimmerHorizontalPager(pagerState) { page ->
       /* Card Content */
    }
  • Jika Anda sudah memahami pager horizontal Compose, komponen ini akan sangat mudah dipahami.

  • Kami juga telah memperkenalkan empat varian kartu baru yang dirancang untuk integrasi yang lancar dengan pager, stack, dan lainnya, serta bersama UI Glimmer lainnya.

  • Kartu gambar di awal dan kartu gambar di akhir menampilkan teks dan gambar secara berdampingan.

  • Jadi, gunakan varian kartu ini jika Anda memiliki jumlah informasi teks dan visual yang sama.

  • Kami telah memisahkan kartu gambar menjadi varian kartu tersendiri.

  • Tata letak ini paling cocok digunakan saat Anda memiliki gambar besar dengan mungkin satu baris teks atau teks, seperti pemilih video ini.

  • Varian kartu tindakan menyematkan satu tombol ke dalam kartu.

  • Gunakan ini jika Anda ingin pengguna mengetahui dengan pasti apa yang akan terjadi saat mereka mengaktifkan kartu, seperti dalam pemilih tujuan ini.

  • Grup tombol memungkinkan Anda mengemas banyak tombol ke dalam ruang kecil.

    ButtonGroup {
       Button(onClick = {}) { Text("Button 1") }
       Button(onClick = {}) { Text("Button 2") }
       Button(onClick = {}) { Text("Button 3") }
       Button(onClick = {}) { Text("Button 4") }
       Button(onClick = {}) { Text("Button 5") }
    }
  • Hanya dengan kode sederhana ini, Anda akan mendapatkan transisi yang indah, perilaku scroll, scrim yang menyembunyikan tepi, dan hanya ditampilkan saat diperlukan, serta input yang otomatis dirutekan dari kacamata ke kontrol.

  • Grup tombol juga dapat berisi tombol ikon dan tombol beralih baru kami.

    var buttonChecked by remember { mutableStateOf(false) }
    
    ToggleButton(
      checked = buttonChecked,
      leadingIcon = { Icon(FavoriteIcon) },
      onCheckedChange = { buttonChecked = it }
    ) {
      Text(if (buttonChecked) "On" else "Off")
    }
  • Anda dapat melihat semua jenis tombol kami yang digunakan di sini untuk membuat kontrol media ini.

  • Dan sekarang, Anda dapat dengan mudah menguji UI di berbagai latar belakang.

  • Emulator kacamata ini memungkinkan Anda memasukkan foto 360 dan menggesernya sehingga Anda dapat mengujinya di berbagai latar belakang, latar belakang yang ramai, dan, Anda tahu, terang, gelap.

  • Grup tombol sangat cocok digunakan dalam tampilan detail seperti ini untuk menampilkan tindakan kontekstual.

  • Saat diketuk, Anda dapat menggunakan transisi elemen bersama untuk membuka status pelihat yang mendetail, lalu menggunakan gestur kembali sistem untuk kembali ke tampilan sebelumnya.

  • Bagus sekali.

  • Selain itu, kami telah menambahkan indikator input suara dan dialog pemberitahuan.

  • Jadi, ya, banyak hal baru.

  • Namun, setelah kita melihat beberapa hal baru, mari kita buat sesuatu.

Ringkasan anchor berbasis lokasi

  • Selain menggunakan Glimmer untuk membuat kacamata AI, kita dapat menggunakan Glimmer untuk membuat pengalaman bagi kacamata XR berkabel.

  • Kami juga ingin Anda membangun pengalaman yang memperluas dunia di sekitar Anda, dimulai dengan anchor berbasis lokasi di dunia nyata.

  • Bayangkan Anda berada di kota baru, mungkin sedang bepergian untuk menghadiri konferensi developer, dan Anda ingin mencari makanan di kota di sekitar Anda.

  • Anda dapat meminta aplikasi navigasi favorit Anda untuk menemukan restoran terdekat dan ratingnya.

  • Informasi dapat dihamparkan langsung di lokasi, sehingga memberikan konteks, kecerdasan, dan panduan.

  • Di sini, Anda dapat melihat komponen Glimmer terbaru kami yang disebut Penanda Ikon.

  • Komponen ini memungkinkan Anda menyoroti elemen penting di dunia fisik dan memasangkannya dengan komponen Glimmer lainnya seperti kartu ini.

  • Dalam contoh ini, aplikasi akan menganotasi lokasi menarik menggunakan Google Maps, Places, dan Geospatial API.

  • Hei, Dereck, mari kita tunjukkan cara menyiapkannya.

  • Ayo kita mulai.

  • Oke.

  • Oke.

  • Jadi, seperti yang disebutkan Paul sebelumnya, mari kita mulai membangun.

  • Jadi, kita akan menggunakan dokumentasi developer di developer.android.com/xr, dan kita akan melihat library komponen Glimmer Jetpack Compose.

  • Jadi, Anda akan dapat menemukan ringkasan visual dari semua komponen yang tersedia di Glimmer.

  • Mari kita mulai dengan bagian UI yang ditunjukkan Paul sebelumnya.

  • Jadi, kita akan menggunakan Glimmer UI untuk membuat indikator spasial dan kotak info.

  • Jadi, mari kita mulai dengan mengidentifikasi komponen yang akan kita gunakan.

  • Di sebelah kiri, Anda akan melihat penanda ikon, dan di sebelah kanan, kita akan menggunakan kartu yang akan mendeskripsikan tempat.

  • Jadi, jika Anda membuka Android Studio, Anda akan dapat melihat pratinjau panel ini seperti komponen Compose lainnya, dan Anda dapat melihat perubahan secara real time.

  • Jadi, seperti yang disebutkan sebelumnya, Anda dapat melihat pratinjau UI di berbagai jenis lingkungan latar belakang dan memastikan bahwa kontras UI Anda memadai dalam berbagai jenis skenario, seperti lingkungan gelap dan terang.

  • Setelah kanvas disiapkan, kita akan membuat baris, menempatkan penanda ikon di dalamnya dengan beberapa spasi, dan kartu dengan beberapa contoh teks.

  • Dan, selesai.

  • Jika Anda puas dengan pratinjau 2D, kita dapat mulai menandai sesuatu di dunia nyata, dan kita akan melakukannya dengan melakukan spasialisasi UI.

  • Artinya, kita akan menatanya dalam 3D, bukan 2D.

  • Jadi, UI spasial terdapat dalam sub-ruang, yang merupakan ruang 3D di depan pengguna.

    Subspace {
      SpatialPanel {
        VideoPlayer()
      }
    }
  • Secara default, subruang sebenarnya menata kontennya pada jarak yang nyaman dari pengguna.

  • Jadi, sebelum kami menunjukkan cara menggunakan Geospatial API, mari kita tempatkan sesuatu di sekitar terlebih dahulu.

  • Jadi, composable subspace yang saya bahas sebelumnya memiliki parameter opsional yang memungkinkan Anda menentukan target ikuti.

    val state by
      qrCode.state.collectAsState()
    Subspace(FollowTarget.anchor(anchor)) {
      SpatialPanel {
        Row {
          IndicatorDot()
          Spacer()
          QrCodeCard(state)
        }
      }
    }
  • Jadi, untuk melampirkan sesuatu ke dunia nyata, pertama-tama, Anda akan membuat anchor yang diperoleh dari ARCore untuk Jetpack XR.

  • Dalam contoh ini, saya menggunakan fitur pengenalan kode QR.

  • Dengan begitu, Anda dapat membaca dan melacak kode QR, sehingga konten Anda dapat mengikuti kode QR tersebut di ruang, dan kami akan melampirkan UI yang kita lihat sebelumnya.

Integrasi Geospatial API dan Google Maps Platform

  • Oke.

  • Jadi, saya telah menunjukkan cara menempatkan konten digital di dunia nyata di sekitar.

  • Mari kita kembali ke contoh Paul.

  • Saya sendiri berasal dari Belanda.

  • Saya tidak terlalu familier dengan Mountain View.

  • Jadi, setelah acara ini, saya ingin membantu Anda membuat aplikasi yang akan membantu Anda menemukan beberapa tempat kopi yang menyenangkan.

  • Jadi, mari kita lihat cara membantu pengguna menemukan beberapa tempat dengan Geospatial API yang kini berada di ARCore untuk Jetpack XR.

  • Jadi, Geospatial API yang awalnya diluncurkan di smartphone kini juga tersedia di Android XR.

  • VPS menggunakan data dari Google Street View dan menggabungkannya dengan pengukuran GPS untuk memosisikan perangkat di area yang didukung.

  • Jadi, pada kacamata AI, Geospatial API dapat digunakan untuk menentukan lokasi dan arah pengguna secara akurat, serta memungkinkan kasus penggunaan navigasi belokan demi belokan yang sangat presisi.

  • Dan di perangkat imersif seperti kacamata XR berkabel, Geospatial API memungkinkan Anda membangun pengalaman yang diposisikan secara akurat di dunia nyata.

  • Misalnya, Anda dapat menambatkan konten spasial pada bangunan atau membuat tur kota khusus.

  • Jadi, mari kita mulai menggunakan Geospatial API dengan tiga langkah ini.

  • Pertama, Anda akan membuat project Google Cloud Platform dan mengonfigurasi autentikasi di aplikasi Anda.

  • Kemudian, saat Geospatial API dikonfigurasi dan diaktifkan di aplikasi, Anda akan meminta izin kepada pengguna untuk mengambil lokasi mereka menggunakan perincian yang akurat.

  • Kemudian, setelah mengonfigurasi sesi untuk menggunakan Geospatial API, Anda sudah siap.

  • Jadi, Anda akan dapat menemukan semua detail tentang dokumentasi developer kami terkait Geospatial API di halaman developer Android XR yang baru diperbarui.

  • Jadi, mari kita mulai dengan menggunakan lokasi pengguna untuk meminta Places API dari Google Maps Platform menemukan beberapa kafe yang bagus di dekat pengguna.

  • Jadi, pertama-tama, di mana pengguna berada?

  • Kita akan meminta Geospatial API untuk mendapatkan update berkelanjutan tentang lokasi pengguna.

    produceState<AppStatus>(Initializing) {
      val geospatial = Geospatial.getInstance(session)
    
      val wait = geospatial.state.onEach {
         value = WaitingForGeospatial(it.geospatialTrackingState)
      }.first {
         it.geospatialTrackingState == Geospatial.GeospatialTrackingState.RUNNING
      }
    
      val accuracyWait = geospatial.state.onEach {
         value = WaitingForGeospatialAccuracy(it)
      }.first { it.horizontalAccuracy < horizontalAccuracyRequirement }
    
      value = WaitingForPlacesResults
      val result = client.findNearby(context, accWait.geospatialPose)
      value = Done(result)
    
    }
  • Jadi, kita akan mengakses objek geospasial melalui sesi XR.

  • Setelah itu, kita akan menunggu Geospatial aktif dan berjalan saat menginisialisasi sensor pusat yang diperlukan dan terhubung ke Cloud API.

  • Kemudian, kita akan menunggu tingkat akurasi tertentu.

  • Jadi, tingkat akurasi dapat meningkat saat pengukuran GPS masuk atau saat sistem pemosisian visual menemukan kecocokan di lokasi pengguna.

  • Menunggu tingkat akurasi yang tinggi penting untuk memastikan bahwa pengalaman lokasi didasarkan pada tempat yang tepat dan bahwa hasil berasal dari area di sekitar pengguna.

  • Kemudian, kita akhirnya siap melakukan penelusuran dengan Places API menggunakan nilai lokasi dari Geospatial API.

    val bounds = CircularBounds.newInstance(
      LatLng(pose.latitude, pose.longitude),
      100.0, // radius, in meters
    )
    val placeFields = listOf(
      Place.Field.ID, Place.Field.DISPLAY_NAME,
      Place.Field.RATING, Place.Field.LOCATION,
    )
    return placesClient.searchNearby(
      SearchNearbyRequest.builder(bounds, placeFields)
        .setIncludedTypes(listOf(PlaceTypes.CAFE))
        .setMaxResultCount(10)
        .build()
    ).await()
  • Jadi, kita akan menggunakan SearchNearbyRequest dengan Places API untuk mengkueri tempat-tempat di sekitar posisi pengguna yang kita peroleh sebelumnya, dan kita akan menemukan hasil dalam radius 100 m.

  • Kita akan mendapatkan ID tempat, nama tampilan, rating, dan, tentu saja, lokasinya.

  • Terakhir, kita akan melakukan penelusuran dengan parameter yang ditentukan, termasuk filter jenis tempat.

  • Jadi, itu saja untuk data, dan mari kita kembali ke UI.

  • Jadi, kita perlu mencari tahu cara menempatkan penanda dan kotak info dari sebelumnya, dan untuk itu, kita akan menggunakan anchor geospasial.

  • Jadi, kembali ke kode, sekali lagi, kita akan mengakses Geospatial API menggunakan sesi XR, lalu kita akan membuat anchor geospasial menggunakan lintang dan bujur tertentu yang diperoleh dari hasil penelusuran sebelumnya.

    val anchorResult by produceState<AnchorResult?>(null) {
     val geospatial = Geospatial.getInstance(session)
     value = geospatial.createAnchorOnSurface(
       place.location.latitude, place.location.longitude,
       surface = GeospatialSurface.TERRAIN,
       altitudeAboveSurface = 3.0,
       eastUpSouthQuaternion = Quaternion()
     )
    }
  • Jadi, dalam contoh ini, kita telah menentukan ketinggian 3 m di atas permukaan tanah pada koordinat tersebut, tetapi Anda juga dapat melampirkannya ke atap yang didukung, yang berarti nilai ketinggian akan ditentukan relatif terhadap atap bangunan di lokasi tersebut.

  • Jadi, Anda juga dapat memutar anchor menggunakan quaternion, yang menentukan nilai rotasi anchor.

  • Namun, kita akan menggunakan setelan default dalam contoh ini karena kita akan membuat UI berputar menghadap pengguna.

  • Kemudian, kita akan memasang UI Glimmer dari sebelumnya ke anchor ini, dan itu benar-benar memberi Anda elemen penyusun untuk pengalaman yang di-anchor secara spasial.

    when (anchorResult) {
     is AnchorCreateSuccess ->
       Subspace(FollowTarget.anchor(anchorResult.anchor)) {
         SpatialPanel(SubspaceModifier.rotateToLookAtUser()) {
           PlaceIndicator(place)
         }
       }
    
     else ->
       Log.e("Demo", "Failed to create anchor $anchorResult")
    }
  • Jadi, kami yakin bahwa Geospatial API dapat memungkinkan pengalaman pencarian jalan yang luar biasa, dan mendesain dengan Glimmer akan membantu menciptakan pengalaman pengguna yang mudah dipahami dan dibuat khusus untuk layar tembus pandang Anda.

  • Untuk mengetahui informasi selengkapnya tentang Geospatial API, kunjungi developer.android.com/xr yang baru saja diperbarui.

  • Saya akan menyerahkan kembali kepada Yasmine untuk mengakhiri sesi ini.

Kesimpulan dan referensi developer

  • Dalam sesi ini, kami membahas beberapa kemampuan Android XR: ARCore untuk Jetpack XR dan Jetpack Compose Glimmer.

  • Kami sangat antusias dengan fitur baru yang akan dihadirkan Android XR ke kacamata XR berkabel.

  • Developer sudah mulai membangun untuk Android XR, dan kami berharap dapat melihat karya kreatif Anda di Google Play Store.

  • Untuk membantu Anda memulai, lihat dokumentasi developer kami, dapatkan inspirasi dari eksperimen XR kami, dan pelajari codelab-nya.

  • Kami telah merencanakan banyak sesi, demo, dan workshop XR yang luar biasa untuk Anda semua.

  • Jadi, silakan ikuti dan pelajari cara membangun aplikasi untuk Android XR di berbagai pengalaman imersif dan augmented reality.

  • Atas nama tim Android XR, terima kasih banyak atas kehadiran Anda, dan kami harap Anda menikmati sisa waktu Anda di Android Developer Summit.

  • Jadi, terima kasih.

Kode

Cuplikan kode

Cuplikan shell pada 04:39 di "Membangun UI dengan Jetpack Compose Glimmer"
android skills add display-glasses-with-jetpack-compose-glimmer
Cuplikan Kotlin pada menit 05:49 di "Membangun UI dengan Jetpack Compose Glimmer"
val brandColor = Color(0xFFFFAABB)
val focusedColor = ButtonDefaults.focusedColor(brandColor)

Column(…) {
   LeadingImageCard(
       focusable = false,
       …
   ) {
       …
   }
   ButtonGroup(...) {
       Button(
           onClick = {},
           leadingIcon = { … },
           focusedColor = focusedColor,
       ) { Text("Add to cart") }

       /* Rest of the buttons */
   }
}
Cuplikan Kotlin pada menit 08:37 di "Prinsip desain UI untuk kacamata pintar dengan layar"
val pagerState =
  rememberGlimmerPagerState(pageCount = { 10 })

GlimmerHorizontalPager(pagerState) { page ->
   /* Card Content */
}
Cuplikan Kotlin pada menit 09:50 di "Prinsip desain UI untuk kacamata pintar dengan layar"
ButtonGroup {
   Button(onClick = {}) { Text("Button 1") }
   Button(onClick = {}) { Text("Button 2") }
   Button(onClick = {}) { Text("Button 3") }
   Button(onClick = {}) { Text("Button 4") }
   Button(onClick = {}) { Text("Button 5") }
}
Cuplikan Kotlin pada menit 10:13 di "Prinsip desain UI untuk kacamata pintar dengan layar"
var buttonChecked by remember { mutableStateOf(false) }

ToggleButton(
  checked = buttonChecked,
  leadingIcon = { Icon(FavoriteIcon) },
  onCheckedChange = { buttonChecked = it }
) {
  Text(if (buttonChecked) "On" else "Off")
}
Cuplikan Kotlin pada 13:55 di "Ringkasan anchor berbasis lokasi"
Subspace {
  SpatialPanel {
    VideoPlayer()
  }
}
Cuplikan Kotlin pada menit 14:16 di "Ringkasan anchor berbasis lokasi"
val state by
  qrCode.state.collectAsState()
Subspace(FollowTarget.anchor(anchor)) {
  SpatialPanel {
    Row {
      IndicatorDot()
      Spacer()
      QrCodeCard(state)
    }
  }
}
Cuplikan Kotlin pada menit 16:43 di "Geospatial API and Google Maps Platform integration"
produceState<AppStatus>(Initializing) {
  val geospatial = Geospatial.getInstance(session)

  val wait = geospatial.state.onEach {
     value = WaitingForGeospatial(it.geospatialTrackingState)
  }.first {
     it.geospatialTrackingState == Geospatial.GeospatialTrackingState.RUNNING
  }

  val accuracyWait = geospatial.state.onEach {
     value = WaitingForGeospatialAccuracy(it)
  }.first { it.horizontalAccuracy < horizontalAccuracyRequirement }

  value = WaitingForPlacesResults
  val result = client.findNearby(context, accWait.geospatialPose)
  value = Done(result)

}
Cuplikan Kotlin pada 17:27 di "Integrasi Geospatial API dan Google Maps Platform"
val bounds = CircularBounds.newInstance(
  LatLng(pose.latitude, pose.longitude),
  100.0, // radius, in meters
)
val placeFields = listOf(
  Place.Field.ID, Place.Field.DISPLAY_NAME,
  Place.Field.RATING, Place.Field.LOCATION,
)
return placesClient.searchNearby(
  SearchNearbyRequest.builder(bounds, placeFields)
    .setIncludedTypes(listOf(PlaceTypes.CAFE))
    .setMaxResultCount(10)
    .build()
).await()
Cuplikan Kotlin pada menit 18:09 di "Geospatial API and Google Maps Platform integration"
val anchorResult by produceState<AnchorResult?>(null) {
 val geospatial = Geospatial.getInstance(session)
 value = geospatial.createAnchorOnSurface(
   place.location.latitude, place.location.longitude,
   surface = GeospatialSurface.TERRAIN,
   altitudeAboveSurface = 3.0,
   eastUpSouthQuaternion = Quaternion()
 )
}
Cuplikan Kotlin pada menit 18:53 di "Geospatial API and Google Maps Platform integration"
when (anchorResult) {
 is AnchorCreateSuccess ->
   Subspace(FollowTarget.anchor(anchorResult.anchor)) {
     SpatialPanel(SubspaceModifier.rotateToLookAtUser()) {
       PlaceIndicator(place)
     }
   }

 else ->
   Log.e("Demo", "Failed to create anchor $anchorResult")
}