# Build world anchored experiences for wired XR glasses - Speakers: Yasmine Quintana Evjen (Senior Product Manager), Dereck Bridie (Developer Relations Engineer), Paul Hoover (Senior Interaction Designer) - Track: Android XR - Video: https://www.youtube.com/watch?v=4NGBZnfnD6o - Page: https://developer.android.com/events/dev-summit/talks/build-world-anchored-experiences-for-xreal-aura-wired-xr-glasses ## About the talk Go beyond screen-space and anchor your apps in the real world with Android XR. This session teaches you how to build geospatially aware Android XR experiences using Jetpack Compose Glimmer and ARCore's Geospatial API. We will start by covering how to get a device's geospatial pose with ARCore. Then, you'll see how Glimmer’s minimal UI components can be anchored to real-world locations via the Visual Positioning System (VPS). We'll combine these to build a simple, location-aware spatial experience. ## Summary - Android XR brings digital experiences into physical environments across a spectrum of devices, from intelligent eyewear to wired XR glasses. Existing 2D Android-compatible apps work on XR headsets and wired XR glasses with minimal modifications. - Jetpack Compose Glimmer provides components and styles tailored for optical see-through displays. Built-in helper functions adjust brand colors to glasses-safe shades to maintain visibility and contrast across lighting conditions. - The Glimmer library adds new components such as pagers and button groups. A depth API helps separate stacked elements on see-through displays where black is transparent. - Subspace composables place interfaces in 3D space and can follow ARCore anchors via a follow target, such as a tracked QR code. - The Geospatial API in ARCore combines Street View data and GPS measurements to position devices accurately in supported areas. You can attach Glimmer components to real-world geospatial anchors using coordinates from Places API queries. ## Resources - [Android CLI](https://goo.gle/android-cli) - [Glimmer guide](https://goo.gle/glimmer-guide) - [Geospatial API documentation](https://goo.gle/xr-geospatial) - [Android XR developer resources](https://goo.gle/xr-dev) - [Android XR experiments](https://goo.gle/xr-experiments) - [Android XR codelabs](https://goo.gle/xr-codelabs) - [Android XR developer documentation](https://developer.android.com/xr) ## Topics android-xr, jetpack-compose, glimmer, arcore, geospatial-api, augmented-reality ## Transcript ### Introduction to Android XR [00:05](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=5s) Hey everyone, welcome to your first session on the Android XR track here at the Android Developer Summit. [00:11](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=11s) Yeah! [00:15](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=15s) We are so excited to see so many of you learning about Android XR. [00:19](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=19s) My name is Yasmine Quintana Evjen, and I'm joined by Paul Hoover and Dereck Bridie, and they will be joining us as the conversation continues. [00:28](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=28s) And this session's topic is all about Android XR, and how you can build spatially anchored, real-world experiences with Jetpack Compose Glimmer and ARCore for Jetpack XR. [00:39](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=39s) But first, let's do a brief introduction of Android XR. [00:43](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=43s) Android XR is a new platform that redefines how users interact with your app, moving beyond the screen and into the space around them. [00:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=51s) We design the platform to bring digital experiences directly into the physical environment. [00:56](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=56s) Whether that means glanceable overlays that enhance the real-world presence or an infinite immersive environment. [01:03](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=63s) It's the same open Android ecosystem that we've been building together for years, and now the canvas is as big as the room and as expansive as your imagination can take it. [01:14](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=74s) We see XR as a spectrum of devices ranging from intelligent eyewear, which enable lightweight, augmented experiences on audio and display glasses to immersive headsets and wired XR glasses, which bring focus, productivity, and immersive entertainment capabilities. [01:31](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=91s) The newest device in the Android XR family is the XREAL AURA, which is available for purchase today. [01:37](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=97s) This device is lightweight and powerful, enabling XR experiences with familiarity of Android. [01:45](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=105s) Our vision for the platform is if you're already developing for Android, you're ready to develop for XR. [01:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=111s) Using the same app model, library, and tools you're familiar with, we want to make it simple for you to build on Android XR. [01:58](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=118s) With no to few modifications, your existing 2D Android-compatible app will work on Android XR headsets and wired XR glasses. ### Jetpack XR SDK and developer tools [02:08](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=128s) And to create awesome XR experiences that feel right at home, we provide a set of libraries especially built for the XR platform. [02:17](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=137s) For developers that are used to building experiences on other immersive platforms, you can build with OpenXR and our 3D engine support, such as Unity, Godot, and Unreal. [02:28](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=148s) Let's talk about building with Android libraries. [02:31](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=151s) We provide the Jetpack XR SDK, a set of Kotlin libraries that helps you extend your apps to XR across immersive and augmented experiences. [02:40](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=160s) Let's take a look at our immersive libraries. [02:43](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=163s) Our Jetpack XR libraries hit beta and stable this year, giving you the confidence you need to start building your immersive XR experiences. [02:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=171s) The perception layer is ARCore for Jetpack XR. [02:55](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=175s) This library provides information about the real world, such as where flat surfaces like a table is, and how users' hands are positioned. [03:02](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=182s) It can track points in 3D space, and provides that information to apps when granted the right permissions, of course. [03:10](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=190s) Then there's Jetpack XR SceneCore, which provides a scene graph for placing your spatial content. [03:16](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=196s) This library is capable of presenting entities in 3D space, provides spatial behaviors for precise scene graph placement. [03:24](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=204s) And Jetpack Compose for XR provides new subspace composables built especially for 3D. [03:30](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=210s) Android developers already familiar with compose layouts, such as building with rows and columns, will find laying out spatial UI feels intuitive. [03:38](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=218s) By creating a spatial row, you can declaratively layout multiple spatial panels side-by-side without having to manually calculate their position or size. [03:47](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=227s) Using subspace composables like a spatial panel or orbiter, you can easily extend your 2D components into this new 3D space. [03:56](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=236s) And of course, subspace composables are capable of more than just showing 2D content. [04:02](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=242s) Compose for XR supports spatial videos as well as 3D models through the spatial external surface and the spatial glTF model. ### Building UI with Jetpack Compose Glimmer [04:12](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=252s) Now, let's talk about augmented apps. [04:16](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=256s) With the Jetpack Projected library, you can enhance your existing mobile app to utilize intelligent eyewear hardware, such as sensors and display. [04:25](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=265s) Finally, Jetpack Compose Glimmer, a UI toolkit for building Android XR experiences optimized for glasses. [04:32](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=272s) Jetpack Compose Glimmer consists of styles and ready-to-use components for building your XR experiences. [04:39](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=279s) We launched Glimmer last year and have continued to expand on the capabilities, including an agentic skill to help you build your display glasses apps with Glimmer. ```shell android skills add display-glasses-with-jetpack-compose-glimmer ``` [04:49](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=289s) Since launch, we've been listening to your feedback. [04:52](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=292s) We heard that you wanted us to extend Jetpack Compose Glimmer beyond intelligent eyewear. [04:58](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=298s) We're happy to announce that we've made changes to better support your spatially anchored experiences with Glimmer, which we'll be diving into later in this talk. [05:07](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=307s) Our work to optimize Glimmer started by creating a new surface for displaying across a variety of XR form factors, from a display to Wired XR Glasses. [05:16](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=316s) The addition of this new surface provides more flexibility for how you can customize your UI. [05:23](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=323s) And to increase the distinctiveness of your apps brand, we've added custom colors to Glimmer components. [05:28](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=328s) Use these to express your brand style across your XR apps. [05:33](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=333s) Our Jetpack Compose Glimmer library provides helper functions that convert your targeted colors, brand colors to glasses-safe colors. [05:41](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=341s) This is to ensure that optimize visibility on optical see-through displays. [05:47](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=347s) So let's actually see this in action. [05:49](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=349s) We want to change the focused button color for this glasses app, which I'm going to se-- select one of my fabulous favorite colors. ```kotlin 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 */ } } ``` [05:56](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=356s) Notice that when the color is added into the code, Glimmer helper functions adjust it to a glasses-safe color for optimized visibility. [06:04](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=364s) All of this is built within our Jetpack Compose Glimmer library, ensuring you are building experiences that look great across various environments. [06:12](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=372s) In Android Studio, you can use the emulator to visualize how your glasses UI will look across various backgrounds, such as light, dark, or busy environments. [06:26](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=386s) These updates are just scratching the surface. [06:30](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=390s) Okay, no. [06:32](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=392s) My team told me you're not going to get a laugh out of that one, but I still held onto it. [06:38](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=398s) But now, I'm going to hand it over to Paul to tell you more about Jetpack Compose Glimmer. ### UI design principles for display glasses [06:45](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=405s) Testing, all right! [06:45](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=405s) I got to hit the next button. [06:49](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=409s) All right, thanks Yasmine. [06:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=411s) All right. [06:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=411s) So, like Yasmine said, Jetpack Compose Glimmer provides the foundational building blocks for developing applications tailored for display glasses. [07:01](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=421s) Our components integrate best practices built for optical see-through displays, and we built them directly into the APIs for you guys, empowering you all the developers to construct beautiful and functional optical see-through experiences. [07:16](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=436s) When you're designing and building apps for optical see-through devices like this one, you need to keep a few things in mind. [07:23](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=443s) First, it's a see-through display, meaning there is no black. [07:28](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=448s) When the world is visible it the black is transparent. [07:31](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=451s) So you can't count on dark backgrounds to maintain contrast for your UI and text and content. [07:41](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=461s) Even though black is invisible, you can use it to obscure other digital content. [07:46](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=466s) In the Glimmer UI framework, we have a depth API that enables you to easily separate UI elements from each other and provide a sense of hierarchy. [07:57](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=477s) Here, you can see how depth on the cards in this stack helps them remain remain separated from each other. [08:08](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=488s) Our vision scientists have provided target contrast ratios for text and icons that are visible in most lighting conditions. [08:15](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=495s) As Yasmine showed, we can build this or we built this into the framework so that when you customize the surface colors, you can be confident your interface will be legible for your users. [08:24](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=504s) We've built these and other best practices into our expanding component library. [08:31](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=511s) We've shipped a lot of new components recently. [08:37](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=517s) One of our newest edition is the pager component with graceful motion transitions and gestures built right in. ```kotlin val pagerState = rememberGlimmerPagerState(pageCount = { 10 }) GlimmerHorizontalPager(pagerState) { page -> /* Card Content */ } ``` [08:45](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=525s) If you're familiar with Compose's horizontal pager, this component will be really familiar. [08:52](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=532s) We've also introduced four new card variants designed for seamless integration with pagers, stacks, and other and alongside other Glimmer UI. [09:04](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=544s) Leading image cards and trailing image cards show text and images next to each other. [09:10](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=550s) So use these card variants when you have an equal amount of text and visual information. [09:15](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=555s) We've separated the image card into its own card variant. [09:23](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=563s) This one's best to use when you have a large image with maybe a single line of text or caption, like this video picker. [09:34](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=574s) The action card variant embeds a single button into a card. [09:39](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=579s) Use this when you want users to know exactly what will happen when they activate the card, like in this destination picker. [09:50](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=590s) Button groups allow you to pack a lot of buttons into a small space. ```kotlin 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") } } ``` [09:54](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=594s) With just this simple code here, you get these beautiful transitions, scrolling behaviors, scrims that hide the edges, and they show when only when needed, and input that's automatically routed from the glasses to the control. [10:13](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=613s) Button groups can also contain our new icon buttons and toggle buttons. ```kotlin var buttonChecked by remember { mutableStateOf(false) } ToggleButton( checked = buttonChecked, leadingIcon = { Icon(FavoriteIcon) }, onCheckedChange = { buttonChecked = it } ) { Text(if (buttonChecked) "On" else "Off") } ``` [10:18](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=618s) You can see all of our button types here in use to create this media control. [10:23](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=623s) And it's easy to test your UI on different backgrounds now. [10:27](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=627s) The glasses emulator actually lets you put in 360 photos and let you pan around so you can test it on different backgrounds, busy backgrounds, and, you know, light, dark. [10:42](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=642s) Button groups are great to use in a detail view like this to show contextual actions. [10:48](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=648s) On tap, you can use shared element transitions to navigate to a detailed viewer state, then use the system back gesture to go back to the previous view. [11:00](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=660s) So nice. [11:03](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=663s) Additionally, we've added a voice input indicator and alert dialogues. [11:11](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=671s) So, yeah, lots of new stuff. [11:14](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=674s) But now that we've seen some of the new things, let's build something. ### Overview of location-based anchors [11:19](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=679s) In addition to using Glimmer to build intelligent eyewear, we can use Glimmer to build experiences for wired XR glasses. [11:28](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=688s) And we want you to build experiences that augment the world around you starting with real-world location-based anchors. [11:36](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=696s) Imagine you're in a new city, maybe traveling for a developer conference, and you want to find some food in the city around you. [11:45](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=705s) You could ask your favorite navigation app to find nearby restaurants and their ratings. [11:50](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=710s) Informations can be overlaid directly on the location, providing context, intelligence, and guidance. [12:02](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=722s) Here, you can see our latest Glimmer component called Icon Marker. [12:06](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=726s) It allows you to highlight key elements in the physical world and pair them with other Glimmer components like this card. [12:13](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=733s) In this example, it annotates points of interest using Google Maps, Places, and Geospatial APIs. [12:19](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=739s) Hey, Dereck, let's show them how to set this up. [12:21](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=741s) Let's do it. [12:22](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=742s) All right. [12:23](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=743s) All right. [12:27](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=747s) So, as Paul mentioned before, let's get building. [12:32](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=752s) So, we'll we'll actually use the developer documentation on developer.android.com/xr, and we'll have a look at the Jetpack Compose Glimmer component library. [12:42](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=762s) So you'll be able to find a visual overview of all the components that are available on Glimmer. [12:48](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=768s) And let's start with this bit of UI that Paul showed earlier. [12:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=771s) So we'll use Glimmer UI to create a spatial indicator and an info box. [12:56](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=776s) So, let's start by identifying the components that we'll use. [13:00](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=780s) On the left, you'll see an icon marker, and on the right, we'll use a card that will describe the place. [13:07](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=787s) So, if you head over to Android Studio, actually you'll be able to preview this pane just like as as you would any other Compose component, and you can see your changes in real time. [13:18](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=798s) So as mentioned before, you can preview the UI in all different types of background environments and make sure that the contrast of you your UI is sufficient in multiple types of scenarios, like dark and light environments. [13:33](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=813s) And now that the canvas has been set, we'll create a row, put an icon marker in it with some spacing, and a card with some sample text. [13:41](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=821s) And there you have it, actually. [13:44](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=824s) If you're happy with the 2D preview, we can start to mark something in the real world, and we'll do that by spatializing the UI. [13:51](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=831s) So what that means is we'll lay it out in 3D instead of 2D. [13:55](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=835s) So, spatial UIs are contained in sub spaces, which is some 3D space in front of the user. ```kotlin Subspace { SpatialPanel { VideoPlayer() } } ``` [14:01](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=841s) And by default, a subspace actually lays out the its its contents at a comfortable distance away from the user. [14:11](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=851s) So, before we show you how to use the Geospatial API, let's place something nearby first. [14:16](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=856s) So, the subspace composable that I talked about earlier has an optional parameter that allows you to specify a follow target. ```kotlin val state by qrCode.state.collectAsState() Subspace(FollowTarget.anchor(anchor)) { SpatialPanel { Row { IndicatorDot() Spacer() QrCodeCard(state) } } } ``` [14:24](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=864s) So to attach something to the real world, first, you'll create an anchor that's obtained from ARCore for Jetpack XR. [14:31](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=871s) And in this example, I'm actually using the QR code recognition feature. [14:35](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=875s) And this will let you read and track QR codes, so your content can follow that QR code around in space, and we'll attach the UI that we saw earlier. ### Geospatial API and Google Maps Platform integration [14:47](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=887s) Okay. [14:47](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=887s) So, I showed you how to place digital content in the real world nearby. [14:52](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=892s) And let's go back to Paul's example. [14:54](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=894s) So, personally, I'm from the Netherlands. [14:55](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=895s) I'm not really familiar with Mountain View. [14:58](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=898s) So, after this event, I want to help you create an app that will help you find some fun coffee places. [15:05](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=905s) So let's see how we can help our users find some with the Geospatial API that's now located in ARCore for Jetpack XR. [15:13](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=913s) So, the Geospatial API that originally launched on smartphones is now available on Android XR too. [15:20](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=920s) It uses data from Google Street View and combines it with GPS measurements to position the device in supported areas. [15:29](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=929s) So, on intelligent eyewear, the Geospatial API can be used to accurately determine the user's location and heading, and it enables high-precision turn-by-turn navigation use cases. [15:40](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=940s) And on immersive devices like wired XR glasses, the Geospatial API lets you build experiences that are accurately positioned in the real world. [15:48](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=948s) So for example, you could anchor spatial content on buildings or create specialized city tours. [15:56](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=956s) So, let's get started with the Geospatial API with these three steps. [16:01](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=961s) The first one is that you'll create a Google Cloud Platform project and configure authentication in your app. [16:07](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=967s) Then, when the Geospatial API is configured and enabled in your app, you'll ask the user for permission to retrieve their location using the fine granularity. [16:17](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=977s) And then after you configure the session to use the Geospatial API, you're all set. [16:22](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=982s) So, you'll be able to find all the details on our developer documentation on the Geospatial API on our newly refreshed Android XR developers page. [16:31](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=991s) So, let's start by using the user's location to ask the Places API for from Google Maps Platform to find some great cafes near the user. [16:40](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1000s) So first off, where is the user? [16:43](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1003s) We'll ask the Geospatial API to get continuous updates on the user's location. ```kotlin produceState(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) } ``` [16:48](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1008s) So, we'll access the geospatial object through the XR session. [16:53](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1013s) After that, we'll wait for Geospatial to get up and running while it initializes the necessary centers sensors and connects to the Cloud API. [17:02](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1022s) And then, we'll wait for a certain level of accuracy. [17:05](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1025s) So, the accuracy levels can improve while GPS GPS measurements come in or when the visual positioning system finds matches at the user's location. [17:15](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1035s) And waiting for high accuracy level is important to make sure that locational experiences are anchored in the right place and that for results are from the user's nearby area. [17:27](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1047s) Then, we're finally ready to perform in the search with the Places API using the location values from the Geospatial API. ```kotlin 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() ``` [17:35](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1055s) So, we'll use a `SearchNearbyRequest` with the Places API to query for places around the user's position that we obtained before, and we'll find results within 100 m. [17:47](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1067s) We'll get the place's ID, its display name, its rating, and, of course, its location. [17:53](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1073s) And then finally, we'll perform the search with the specified parameters including a place type filter. [17:59](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1079s) So, that's it for the data, and let's go back to the UI. [18:02](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1082s) So, we'll need to figure out how to place our marker and info box from earlier, and for that, we'll use geospatial anchors. [18:09](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1089s) So, back to the code, once again, we'll access our Geospatial API using our XR session, and then we'll create a geospatial anchor using a specific latitude and longitude that was obtained from the search results earlier. ```kotlin val anchorResult by produceState(null) { val geospatial = Geospatial.getInstance(session) value = geospatial.createAnchorOnSurface( place.location.latitude, place.location.longitude, surface = GeospatialSurface.TERRAIN, altitudeAboveSurface = 3.0, eastUpSouthQuaternion = Quaternion() ) } ``` [18:21](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1101s) So, in this example, we've specified the altitude to be 3 m above the terrain at those coordinates, but you could also attach to supported rooftops, which means that the altitude value will be determined relative to the rooftop at the building at that location. [18:39](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1119s) So, you can also rotate the anchor using a quaternion, which specifies like the rotational values of the anchor. [18:46](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1126s) But we'll actually use the defaults in this example because we'll be making the UI rotate to face the user. [18:53](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1133s) And then, we'll attach the Glimmer UI from before to this anchor, and that really gives you the building blocks for a spatially-anchored experience. ```kotlin when (anchorResult) { is AnchorCreateSuccess -> Subspace(FollowTarget.anchor(anchorResult.anchor)) { SpatialPanel(SubspaceModifier.rotateToLookAtUser()) { PlaceIndicator(place) } } else -> Log.e("Demo", "Failed to create anchor $anchorResult") } ``` [19:00](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1140s) So, we believe that the Geospatial API can enable great wayfinding experiences, and designing with Glimmer will help create glanceable user experiences made especially for your see-through displays. [19:12](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1152s) For more information on the Geospatial API, visit the recently updated developer.android.com/xr. [19:18](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1158s) And I'll hand it back to Yasmine to finish us off. ### Conclusion and developer resources [19:27](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1167s) In this session, we went over a few capabilities of Android XR: ARCore for Jetpack XR and Jetpack Compose Glimmer. [19:35](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1175s) We're enthusiastic about what new features Android XR will bring to wired XR glasses. [19:43](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1183s) Developers are already building for Android XR, and we hope to see your creative work on the Google Play Store. [19:49](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1189s) To help you get started, please check out our developer documentation, be inspired by our XR experiments, and jump into it with the codelabs. [20:00](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1200s) We have a ton of great XR sessions, demos, and workshops planned for all of you. [20:05](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1205s) So, please tune in and learn about building for Android XR across immersive and augmented experiences. [20:15](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1215s) On behalf of the Android XR team, thank you all so much for being here, and we hope you enjoy the rest of your time here at the Android Developer Summit. [20:23](https://www.youtube.com/watch?v=4NGBZnfnD6o&t=1223s) So, thank you.