<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0"><id>tag:blogger.com,1999:blog-6755709643044947179</id><updated>2026-08-31T14:27:58.923-07:00</updated><category term="Featured"/><category term="Google Play"/><category term="Android"/><category term="latest"/><category term="android developers"/><category term="Develop"/><category term="Android Developer"/><category term="Android Studio"/><category term="Games"/><category term="Announcements"/><category term="Security"/><category term="Jetpack"/><category term="Wear OS"/><category term="Play Console"/><category term="Jetpack Compose"/><category term="Privacy"/><category term="Apps"/><category term="Developer Preview"/><category term="archive"/><category term="app development"/><category term="Compose"/><category term="Game Development"/><category term="developer stories"/><category term="Google Play services"/><category term="Kotlin"/><category term="Android Wear"/><category term="google play developers"/><category term="success stories"/><category term="#WeArePlay"/><category term="Performance"/><category term="Platform_Update"/><category term="case study"/><category term="Gemini"/><category term="mobile"/><category term="Distribute"/><category term="android security"/><category term="#11WeeksOfAndroid"/><category term="GooglePlay"/><category term="NDK"/><category term="#GoogleIO"/><category term="App"/><category term="Google Services"/><category term="User Interface"/><category term="Design"/><category term="Developer Tools"/><category term="Android TV"/><category term="Game"/><category term="Google Play Console"/><category term="Media"/><category term="Android Auto"/><category term="Material Design"/><category term="androidstudio"/><category term="Android N"/><category term="Developer Console"/><category term="Google Play Games"/><category term="Large Screens"/><category term="SDK updates"/><category term="Android Developer Challenge"/><category term="Explore"/><category term="Google Play game services"/><category term="Best Practices"/><category term="Google I/O"/><category term="Google I/O 2025"/><category term="How-to"/><category term="foldables"/><category term="#GenerativeAI"/><category term="#TheAndroidShow"/><category term="AI"/><category term="Android app development"/><category term="Google I/O 2023"/><category term="Story"/><category term="Tablets"/><category term="UI"/><category term="Android Jetpack"/><category term="Web"/><category term="developers"/><category term="Tools"/><category term="form factors"/><category term="wear"/><category term="Android Development"/><category term="Android Market"/><category term="Beta"/><category term="Google I/O 2024"/><category term="AndroidDevStory"/><category term="android11"/><category term="developer"/><category term="#androiddevsummit"/><category term="Android Things"/><category term="Indie Games"/><category term="Location"/><category term="machine learning"/><category term="Android 1.5"/><category term="Android for cars"/><category term="App quality"/><category term="compatibility"/><category term="Android Dev Summit"/><category term="Camera"/><category term="Firebase"/><category term="Android Design"/><category term="Android12"/><category term="Authentication"/><category term="CameraX"/><category term="Optimization"/><category term="Solve"/><category term="Widgets"/><category term="android p"/><category term="media3"/><category term="permissions"/><category term="#Android"/><category term="Android 11"/><category term="Android O"/><category term="Android XR"/><category term="Indie Games Accelerator"/><category term="R8"/><category term="Udacity"/><category term="Wear OS 6"/><category term="announcement"/><category term="monetization"/><category term="#JetpackCompose"/><category term="Android Automotive OS"/><category term="Android Emulator"/><category term="Audio"/><category term="Google Play Store"/><category term="Identity"/><category term="Marshmallow"/><category term="Support Library"/><category term="UX"/><category term="androidq"/><category term="indie developers"/><category term="safety"/><category term="#Media"/><category term="API"/><category term="Android 1.6"/><category term="Gemini Nano"/><category term="Google"/><category term="Google Analytics"/><category term="Open source"/><category term="Pixel"/><category term="notifications"/><category term="subscriptions"/><category term="Europe"/><category term="ExoPlayer"/><category term="Health Connect"/><category term="Kotlin Multiplatform"/><category term="Learn"/><category term="Localization"/><category term="London"/><category term="ML Kit"/><category term="Modern Android Development"/><category term="Navigation"/><category term="Performance Optimization"/><category term="Testing"/><category term="adaptive"/><category term="beginner"/><category term="business"/><category term="events"/><category term="passkeys"/><category term="Android 5.0"/><category term="Android UI"/><category term="AndroidO"/><category term="C++"/><category term="Gemini in Android Studio"/><category term="Google Cloud Platform"/><category term="Graphics"/><category term="Health Connect API"/><category term="How-To Guide"/><category term="IoT"/><category term="Layout"/><category term="Play Store"/><category term="Project Treble"/><category term="WebView"/><category term="analytics"/><category term="aosp"/><category term="appstory"/><category term="competition"/><category term="engagement"/><category term="grow"/><category term="prizes"/><category term="release"/><category term="win"/><category term="#MADSkills"/><category term="ADS 22"/><category term="Ads"/><category term="Android Developer Story"/><category term="Android Instant Apps"/><category term="Android Pie"/><category term="Android SDK"/><category term="Android Vitals"/><category term="AndroidX"/><category term="GDC"/><category term="Game Developers Conference"/><category term="Google Cast"/><category term="Google Cloud Messaging"/><category term="Google Fit"/><category term="Google Play Indie Games Festival"/><category term="Google Play Indie games accelerator"/><category term="Google Play policy"/><category term="Indie Games Festival"/><category term="Mobile Games"/><category term="News"/><category term="Policy"/><category term="Product News"/><category term="Quality"/><category term="Release Notes"/><category term="Renderscript"/><category term="UI toolkit"/><category term="adaptive layouts"/><category term="admob"/><category term="android13"/><category term="android14"/><category term="android16"/><category term="battery"/><category term="credential manager"/><category term="developerstory"/><category term="indie"/><category term="indies"/><category term="showcase"/><category term="user experience"/><category term="wearos"/><category term="‘Google Play"/><category term="#AndroidDevJourney"/><category term="#camera"/><category term="APIs"/><category term="Android 15"/><category term="Android Gradle Plugin"/><category term="Android M"/><category term="Android Q"/><category term="Android fitness"/><category term="Android health"/><category term="Androidify"/><category term="Background work"/><category term="Dev Story"/><category term="Developer Inspiration"/><category term="Google Assistant"/><category term="IO2013"/><category term="Policies"/><category term="Saatchi"/><category term="TensorFlow"/><category term="app optimizations"/><category term="career inspiration"/><category term="careers in tech"/><category term="google play protect"/><category term="google tv"/><category term="health data"/><category term="spotlight week"/><category term="users"/><category term="watch faces"/><category term="#io19"/><category term="Android 10"/><category term="Android 13"/><category term="Android 14"/><category term="Android 2.0"/><category term="Android 9"/><category term="Android Dev Journey"/><category term="Android Go"/><category term="Android Open Source Project"/><category term="Android app developers"/><category term="AndroidAI"/><category term="AndroidDev"/><category term="App Resources"/><category term="Bluetooth"/><category term="Developer Journey"/><category term="Education"/><category term="GenAI"/><category term="GenerativeAI"/><category term="Get Inspired"/><category term="Google Drive"/><category term="Google Play Devs"/><category term="Google Play games services"/><category term="HDR"/><category term="HTTPS"/><category term="In-app Billing"/><category term="KMP"/><category term="Latest news"/><category term="Material 3 Expressive Design"/><category term="Media and Camera"/><category term="OpenGL ES"/><category term="Power series"/><category term="Requirements"/><category term="Samples"/><category term="TV"/><category term="TensorFlow Lite"/><category term="Tiles"/><category term="Treble"/><category term="VR"/><category term="Video"/><category term="Watch Face Format"/><category term="adaptive UI"/><category term="android15"/><category term="androidn"/><category term="app performance"/><category term="appexcellence"/><category term="chrome"/><category term="community"/><category term="contest"/><category term="desktop"/><category term="developer story"/><category term="gamestory"/><category term="growth"/><category term="io15"/><category term="library"/><category term="material you"/><category term="nearby"/><category term="playback"/><category term="rendering"/><category term="startup"/><category term="update"/><category term="watchface"/><category term="workmanager"/><category term="#AdaptiveApps"/><category term="#Android11"/><category term="#AndroidDevChallenge"/><category term="#Wear"/><category term="#passkeys"/><category term="ART"/><category term="Actions on Google"/><category term="Android 4.2"/><category term="Android 6.0"/><category term="Android Camera"/><category term="Android Studio Emulator"/><category term="Android Study Jams"/><category term="Android for Work"/><category term="AndroidWear"/><category term="Animation"/><category term="App Components"/><category term="App Security"/><category term="Architecture"/><category term="Baseline Profiles"/><category term="Canary"/><category term="Code Day"/><category term="Connectivity"/><category term="Coroutines"/><category term="Courses"/><category term="DAC/Develop"/><category term="Developer profiles"/><category term="Developing Media Apps"/><category term="Development Tools"/><category term="FIDO2"/><category term="GCM"/><category term="Google Developers"/><category term="Google Mobile Ads"/><category term="IO2014"/><category term="Intents"/><category term="Jetpack Navigation"/><category term="KotlinConf"/><category term="Launch"/><category term="Launchpad Accelerator"/><category term="Licensing"/><category term="ML"/><category term="Platform"/><category term="Platform_Updates"/><category term="Resources"/><category term="Sample code"/><category term="Text-to-Speech"/><category term="Unity"/><category term="Virtual Reality"/><category term="accessibility"/><category term="advertising"/><category term="androidp"/><category term="d8"/><category term="event"/><category term="features"/><category term="iOS"/><category term="large_screens"/><category term="layouts"/><category term="multiplatform apps"/><category term="play"/><category term="resizing"/><category term="sandbox"/><category term="signing"/><category term="tutorial"/><category term="vulkan"/><category term="wifi"/><category term="windowing"/><category term="#AndroidAI"/><category term="#Gemini"/><category term="#GoogleforGames"/><category term="#Productive"/><category term="#featured"/><category term="#io17"/><category term="#io18"/><category term="#transformer"/><category term="#watch-face"/><category term="#wff"/><category term="#widgets"/><category term="AGDK"/><category term="Activity Recognition"/><category term="Agentic"/><category term="Android 3.0"/><category term="Android 3.2"/><category term="Android 4.4"/><category term="Android App"/><category term="Android Architecture"/><category term="Android Basics"/><category term="Android Dev"/><category term="Android Development Tools"/><category term="Android Studio Narwhal"/><category term="Android ecosystem"/><category term="Android16QPR2"/><category term="AndroidGameDev"/><category term="AndroidPerformance"/><category term="App Bundle"/><category term="App Indexing"/><category term="Architecture Components"/><category term="Auto"/><category term="Biometrics"/><category term="Business &amp; Leadership"/><category term="Camera X"/><category term="Camera2"/><category term="ChromeOS"/><category term="Chromebooks"/><category term="Cloud"/><category term="Commerce"/><category term="Compose Material 3"/><category term="Compose UI"/><category term="Crashlytics"/><category term="Custom Model"/><category term="DAC/google"/><category term="DataStore"/><category term="Developer Labs"/><category term="Developer Productivity"/><category term="Early Access"/><category term="Firebase Cloud Messaging"/><category term="Fragments"/><category term="GameDev"/><category term="Gemma"/><category term="Global"/><category term="Google For Games"/><category term="Google Maps"/><category term="Google Play for Work"/><category term="Google client API"/><category term="Google+"/><category term="Gradle"/><category term="Indie Contest"/><category term="Indie games contest"/><category term="Indie games showcase"/><category term="Indie showcase"/><category term="Input methods"/><category term="Instant Apps"/><category term="LiquidFun"/><category term="MADSkills"/><category term="Maps"/><category term="Maps API"/><category term="MaterialDesign"/><category term="MediaSession"/><category term="Mobile App Development"/><category term="Mobile Development"/><category term="Notification"/><category term="Onboarding"/><category term="Pixel Fold"/><category term="Pixel Watch"/><category term="Preview"/><category term="Privacy Sandbox"/><category term="Productivity"/><category term="Profiling"/><category term="SDK Tools"/><category term="Samsung"/><category term="Screens"/><category term="Studio Bot"/><category term="Subscription"/><category term="TLS"/><category term="Text and Input"/><category term="UI Development"/><category term="Ultra HDR"/><category term="Watch Face"/><category term="Wearables"/><category term="Window Size Classes"/><category term="android oreo"/><category term="android privacy"/><category term="android-tv"/><category term="android17"/><category term="apk"/><category term="appexcellencecasestudy"/><category term="appquality"/><category term="ar"/><category term="bestpractices"/><category term="chrome os"/><category term="codelab"/><category term="compiler"/><category term="connection encryption"/><category term="cross-device"/><category term="developergamestory"/><category term="documentation"/><category term="dynamic delivery"/><category term="emulator"/><category term="encryption"/><category term="fcm"/><category term="foldable"/><category term="free-form"/><category term="glance"/><category term="google play for families"/><category term="google-tv"/><category term="insets"/><category term="kernel"/><category term="language"/><category term="largescreens"/><category term="live edit"/><category term="memory"/><category term="mobile vision APIs"/><category term="multi-device development"/><category term="multitasking"/><category term="network security"/><category term="oreo"/><category term="people"/><category term="privacy sandbox on android"/><category term="profile guided optimization"/><category term="stable release"/><category term="store listing experiments"/><category term="training"/><category term="transformer"/><category term="transparency"/><category term="ubicomp"/><category term="updates"/><category term="wear-tiles"/><category term="windowmanager"/><category term="#APK"/><category term="#Android12"/><category term="#AndroidDev"/><category term="#AndroidJetpack"/><category term="#Androiddevelopment"/><category term="#CredentialManager"/><category term="#GDC20"/><category term="#Media3"/><category term="#Studio"/><category term="#TV"/><category term="#complications"/><category term="#credential-manager"/><category term="#exoplayer"/><category term="#googleplay"/><category term="#identity"/><category term="#nav3"/><category term="#releases"/><category term="#tiles"/><category term="'Google Play"/><category term="5G"/><category term="64bit"/><category term="A/B testing"/><category term="AGDE"/><category term="AI assisted coding"/><category term="AI code completion"/><category term="Action Bar"/><category term="Actions"/><category term="Adaptive apps"/><category term="Adaptive development"/><category term="Agent Mode"/><category term="Android 12L"/><category term="Android 16"/><category term="Android 2.1"/><category term="Android 2.2"/><category term="Android 2.3"/><category term="Android 7.0"/><category term="Android 71"/><category term="Android App Bundles"/><category term="Android Architecture Components"/><category term="Android Bench"/><category term="Android CLI"/><category term="Android Developer Community"/><category term="Android Developer Phone"/><category term="Android Device Streaming"/><category term="Android Devs"/><category term="Android Game SDK"/><category term="Android Media"/><category term="Android Pay API"/><category term="Android Photo Picker"/><category term="Android SDK Upgrade Assistant"/><category term="Android Storage"/><category term="Android Studio 3.0"/><category term="Android Studio Arctic Fox"/><category term="Android Studio Dolphin"/><category term="Android Studio Flamingo"/><category term="Android Studio Giraffe"/><category term="Android Studio Hedgehog"/><category term="Android Studio Jellyfish"/><category term="Android Studio Koala"/><category term="Android Studio Koala Feature Drop"/><category term="Android TV OS"/><category term="Android Wear 2.0"/><category term="Android XR SDK"/><category term="Android app excellence"/><category term="Android betas"/><category term="Android codelabs"/><category term="Android courses"/><category term="Android skills"/><category term="Android training"/><category term="Androidtv"/><category term="Animation and Graphics"/><category term="App Bundles"/><category term="App Excellence"/><category term="App Quality Insights"/><category term="AppCompat"/><category term="AppFunctions"/><category term="Assistant"/><category term="Audio for Android"/><category term="BLE"/><category term="Back Stack"/><category term="Better together"/><category term="Boston"/><category term="C"/><category term="Compose Animation Previews"/><category term="Conversation API"/><category term="Dashboard"/><category term="Daydream"/><category term="Debugging"/><category term="Declarative Programming"/><category term="Dev Tools"/><category term="Developer Console Store Listing Experiments"/><category term="Developer Preview 4"/><category term="Efficient Apps"/><category term="Feature Group"/><category term="Fundamentals"/><category term="GDC 2020"/><category term="GLSL"/><category term="GPS"/><category term="Gesture Navigation"/><category term="Gestures"/><category term="Google AI Studio"/><category term="Google Developer"/><category term="Google Play App Safety"/><category term="Google Play Billing"/><category term="Google Play Instant"/><category term="Google Play Integrity API"/><category term="Google Play SDK Console"/><category term="Google Play SDK Index"/><category term="Google Sign-In"/><category term="Google Wallet"/><category term="Google codelabs"/><category term="Google for Games Developer Summit"/><category term="GoogleAPIClient"/><category term="GoogleIO"/><category term="Gradle sync"/><category term="Guidelines"/><category term="Health Services"/><category term="Horologist"/><category term="I/O"/><category term="I/O2014"/><category term="IME"/><category term="Influence"/><category term="Internet of Things"/><category term="JNI"/><category term="Japan"/><category term="Java"/><category term="Java 8"/><category term="JetBrains"/><category term="Jetpack Compose 1.2"/><category term="Jetpack Glance"/><category term="Jetpack Libraries"/><category term="Jetpack XR SDK"/><category term="Kotlin Everywhere"/><category term="KotlinConf 2023"/><category term="LVL"/><category term="LaunchShow"/><category term="Linux"/><category term="LondonEng"/><category term="MAD Skills"/><category term="Made by Google"/><category term="Memory Management"/><category term="Mobile World Congress"/><category term="Model Maker"/><category term="MotionLayout"/><category term="Multi-form factor designs"/><category term="Navigation Library"/><category term="Navigation Q&amp;A"/><category term="Navigation component"/><category term="Navigation3"/><category term="Nougat"/><category term="On-Device Machine Learning"/><category term="OnePlus"/><category term="OpenGL"/><category term="OpenXR"/><category term="PC games"/><category term="PickVisualMedia"/><category term="Pixel Tablet"/><category term="Places"/><category term="Play Academy"/><category term="Play Commerce"/><category term="Play Privacy"/><category term="Play Security"/><category term="Play Vitals"/><category term="PlayStore"/><category term="Preview Stabilization"/><category term="Problem-Solving"/><category term="Profilers"/><category term="Pure"/><category term="SDR"/><category term="SEA"/><category term="Safe Browsing"/><category term="SafetyNet"/><category term="Scoped Storage"/><category term="Sharing"/><category term="Southeast Asia"/><category term="Storage"/><category term="TLS by default"/><category term="TikTok"/><category term="Translation"/><category term="UXR"/><category term="User Engagement"/><category term="User Support"/><category term="Visibility"/><category term="Watch Face Push"/><category term="Wear surfaces"/><category term="WebXR"/><category term="Window Manager"/><category term="adaptive API"/><category term="android ux"/><category term="androidjetpack"/><category term="app developer"/><category term="app lifecycle"/><category term="app signing"/><category term="apps games insights"/><category term="attestation"/><category term="autofill"/><category term="beacons"/><category term="beta testing"/><category term="billing"/><category term="build Android apps"/><category term="buildingforbillions"/><category term="canonical layouts"/><category term="code completion"/><category term="codelabs"/><category term="coding productivity"/><category term="color"/><category term="constraintlayout"/><category term="conversations"/><category term="conversions"/><category term="device explorer"/><category term="devices"/><category term="dexer"/><category term="dx"/><category term="editing"/><category term="emojis"/><category term="fitness"/><category term="game design"/><category term="gaming"/><category term="get started"/><category term="google computer science"/><category term="hackster"/><category term="immersive experiences"/><category term="in-app purchase"/><category term="indie game developers"/><category term="infinite deviation: games"/><category term="insights"/><category term="io2010"/><category term="laptops"/><category term="learn Android"/><category term="malware"/><category term="media controls"/><category term="multi-device"/><category term="on-device"/><category term="passwords"/><category term="podcast"/><category term="policy compliance"/><category term="ratings"/><category term="regulations"/><category term="reviews"/><category term="search"/><category term="social impact"/><category term="solutions"/><category term="spatial computing"/><category term="startup profiles"/><category term="target API"/><category term="text"/><category term="things"/><category term="time"/><category term="user data"/><category term="watch face API"/><category term="&quot;featured'+'androidstudio'"/><category term="#11WeeksOfAndroid Android TV"/><category term="#64-bit"/><category term="#AAB"/><category term="#ADS19"/><category term="#AIGlasses"/><category term="#ARCore #TheAndroidShow"/><category term="#ART"/><category term="#ATV"/><category term="#Android #Android development # advanced Android #learn Android #build Android apps #Udacity"/><category term="#Android 14"/><category term="#AndroidAppBundles"/><category term="#AndroidDeviceStreaming&#10;#AndroidStudio"/><category term="#AndroidGeiminiEra"/><category term="#AndroidStudio"/><category term="#AndroidTV"/><category term="#AndroidTV #Google Cast #Udacity"/><category term="#AndroidXR"/><category term="#Androidbasics"/><category term="#AppBundles"/><category term="#Argentina"/><category term="#Compose"/><category term="#Composecamp"/><category term="#Covid-19"/><category term="#EdTech"/><category term="#Editing"/><category term="#Experts"/><category term="#FFmpeg"/><category term="#Firebase"/><category term="#GDC17 #GoogleDeveloperDay #GooglePlay #Games #VR #Daydream #Developers #Android #Google Play"/><category term="#GDE"/><category term="#GPA2017 #GooglePlayAwards #GooglePlay #Games #VR #AR #AndroidWear #Indies #Startup #Apps #Developers #Android #Google Play"/><category term="#GPA2018 #GooglePlayAwards #GooglePlay #Games #VR #AR #AndroidWear #Indies #Startup #Apps #Developers #Android #Google Play"/><category term="#GTV"/><category term="#Game"/><category term="#Gemma"/><category term="#GoogleDevelopers"/><category term="#GoogleTV"/><category term="#Imagen"/><category term="#MADscore"/><category term="#PasskeysWeek #Identity"/><category term="#Pixel"/><category term="#Productivity"/><category term="#STEM"/><category term="#StorageSavings"/><category term="#TechEd"/><category term="#TechEdu"/><category term="#XRGlasses"/><category term="#XRHeadsets"/><category term="#adaptive"/><category term="#advancedAndroid #Udacity"/><category term="#apps"/><category term="#auth-wear"/><category term="#authentication"/><category term="#autofill"/><category term="#autofill-services"/><category term="#codelabcourses"/><category term="#codelabs"/><category term="#compiler"/><category term="#develop"/><category term="#exposing-data"/><category term="#google"/><category term="#io16"/><category term="#largescreens"/><category term="#memory"/><category term="#notifications"/><category term="#optimization"/><category term="#page-sizes"/><category term="#performance"/><category term="#pixel7"/><category term="#restorecredentials"/><category term="#sign-in"/><category term="#ultra-hdr"/><category term="#watch-face-push"/><category term="#xr"/><category term="'featured'+'platform_update'"/><category term=". Web"/><category term=".app"/><category term="11 Weeks of Android"/><category term="11weeksofandroid"/><category term="12l"/><category term="16 KB memory page"/><category term="16 KB page size"/><category term="16KB Page Size"/><category term="3d"/><category term="4 KB page size"/><category term="5 star apps"/><category term="505 Games"/><category term="60 FPS"/><category term="8.1"/><category term="AAKB"/><category term="AAOS"/><category term="AAudio for Android"/><category term="ADT-3"/><category term="AGI"/><category term="AI&#10;Industry Trends"/><category term="AI Edge"/><category term="AI glasses"/><category term="AI-assisted coding"/><category term="AIY"/><category term="AIY Projects"/><category term="AMD"/><category term="AMP"/><category term="ANR"/><category term="API stabilization"/><category term="APK Expansion Files"/><category term="AQI"/><category term="ARM"/><category term="ARPU"/><category term="ART profiles"/><category term="ASO"/><category term="ATSL"/><category term="About Fun"/><category term="Access"/><category term="Acquisition"/><category term="Activity Embedding"/><category term="Activity Stack Pinning"/><category term="ActivityResult"/><category term="Administration"/><category term="Advanced Android course"/><category term="Advanced Android training"/><category term="Agent Skills"/><category term="Agentic AI"/><category term="Agus Gomez"/><category term="Android 11 Compatibility"/><category term="Android 11 final release"/><category term="Android 12 Beta 5"/><category term="Android 16 KB page"/><category term="Android 17"/><category term="Android 2.3.3"/><category term="Android 4.0"/><category term="Android 4.3"/><category term="Android 5.1"/><category term="Android 7.1"/><category term="Android 8.1"/><category term="Android AICore"/><category term="Android Basics in Kotlin"/><category term="Android Basics with Compose"/><category term="Android C++"/><category term="Android Dev Summit 2021"/><category term="Android Developer Journey"/><category term="Android Developers  #GooglePlayAwards #GooglePlay #Games #Indies #Startup #Apps #Developers #Android"/><category term="Android Developers Best Practices"/><category term="Android Excellence"/><category term="Android GPU"/><category term="Android Game Development Kit"/><category term="Android Games"/><category term="Android IDE"/><category term="Android IO"/><category term="Android Keystore"/><category term="Android ML"/><category term="Android Neural Networks"/><category term="Android Neural Networks API"/><category term="Android O Developer Preview"/><category term="Android One"/><category term="Android Output Switcher"/><category term="Android Paging"/><category term="Android Pay"/><category term="Android Performance Tuner"/><category term="Android Plugins"/><category term="Android Prompting"/><category term="Android Q Beta"/><category term="Android Q Beta 6"/><category term="Android Quality"/><category term="Android Scudo"/><category term="Android Security Rewards"/><category term="Android Security Rewards Program"/><category term="Android Studio 3.6"/><category term="Android Studio 4.0"/><category term="Android Studio 4.1"/><category term="Android Studio 4.2"/><category term="Android Studio Bumblebee"/><category term="Android Studio Chipmunk"/><category term="Android Studio Dolphin Beta"/><category term="Android Studio Electric Eel Canary"/><category term="Android Studio Icon"/><category term="Android Studio Iguana"/><category term="Android Studio Ladybug"/><category term="Android Studio Logo"/><category term="Android Studio Otter"/><category term="Android Studio Profiler"/><category term="Android Studio for enterprises"/><category term="Android Testing Support Library"/><category term="Android Tools"/><category term="Android U"/><category term="Android VRP"/><category term="Android audio latency"/><category term="Android developer codelabs"/><category term="Android games on PC"/><category term="Android graphics"/><category term="Android release"/><category term="AndroidCanary"/><category term="AndroidRuntime"/><category term="Annoucements"/><category term="AnswerLab"/><category term="AoG"/><category term="App Actions"/><category term="App Review"/><category term="App Startup"/><category term="App Testing"/><category term="App experience"/><category term="App icons"/><category term="AppSearch"/><category term="AppWidgets"/><category term="Application Security Improvement Program"/><category term="Assistant SDK"/><category term="Auto Backup"/><category term="Autofill Framework"/><category term="Autofill Services"/><category term="Automatic App Testing"/><category term="Automotive"/><category term="BABBQ"/><category term="Backup and Restore (IDE)"/><category term="Benchmarking"/><category term="Beta Announcement"/><category term="Betatesting"/><category term="Billions"/><category term="Biometric authentication"/><category term="BiometricPrompt"/><category term="BiometricPrompt API"/><category term="Budge Studios"/><category term="Bugs"/><category term="Built-in Intents"/><category term="C++ audio library for Android"/><category term="CDD"/><category term="CFI"/><category term="CMP"/><category term="CTS"/><category term="Call Log"/><category term="CameraX Effect"/><category term="CameraX Extensions"/><category term="Cars"/><category term="Cast"/><category term="Certificates"/><category term="Certification"/><category term="Channels"/><category term="Clock"/><category term="Cloud Speech API"/><category term="Code Generation"/><category term="Compiler Mitigations"/><category term="Compiler-based security"/><category term="Complications"/><category term="Composables"/><category term="Compose 1.8"/><category term="Compose Adaptive Layouts Library 1.2"/><category term="Compose MultiPlatform"/><category term="Compose Preview"/><category term="Compose Tools"/><category term="Compose for Wear OS"/><category term="CompositionPlayer"/><category term="Connected displays"/><category term="Consistency"/><category term="Console"/><category term="Contacts"/><category term="Content Provider"/><category term="Control Flow Integrity"/><category term="Cool Stuff"/><category term="Credential Saving"/><category term="CredentialManager"/><category term="Crostini"/><category term="CultureAlley"/><category term="DAC/Design"/><category term="DNG"/><category term="DNS over TLS"/><category term="DP3"/><category term="DST"/><category term="Dagger"/><category term="Dan Dole"/><category term="Data-Driven Prompts"/><category term="Daylight savings"/><category term="Deep Links"/><category term="DeliQueue"/><category term="Demographics"/><category term="Deprecation"/><category term="Design Hub"/><category term="Desugaring"/><category term="DevTools"/><category term="Developer Accounts"/><category term="Developer Days"/><category term="Developer Experience"/><category term="Developer Student Clubs"/><category term="DialogFragment"/><category term="Disruptor Beam"/><category term="DonutTracker"/><category term="Doze"/><category term="Driving Do Not Disturb"/><category term="Duolingo"/><category term="EA"/><category term="EAP"/><category term="EOY Recap 2022"/><category term="EOY recap 2023"/><category term="Editors’ Choice"/><category term="Educate"/><category term="Electronic Arts"/><category term="Engage"/><category term="Engage SDK"/><category term="Engineering"/><category term="Enterprise"/><category term="Entrepreneurs"/><category term="Extensions"/><category term="FAQ"/><category term="Facebook"/><category term="Fast"/><category term="Fast Pair"/><category term="Feature Combination"/><category term="Feedback"/><category term="Figma"/><category term="Finance"/><category term="Find My Device"/><category term="Firebase AI Logic"/><category term="Firebase Crashlytics"/><category term="Fit"/><category term="Foreground services"/><category term="Fortify"/><category term="Fragment"/><category term="Freeform Resizing"/><category term="Frequently Asked Questions"/><category term="Froyo 2.2"/><category term="GDC 2025"/><category term="GDC17"/><category term="GDC19"/><category term="GDC20"/><category term="GMD"/><category term="GNSS"/><category term="GPGS"/><category term="GPU acceleration"/><category term="GSI"/><category term="Game Mode API"/><category term="Game engine development"/><category term="Gamer Profile"/><category term="Games and Media"/><category term="Gareth Jones"/><category term="Gemini 1.5 Flash"/><category term="Gemini 1.5 Pro"/><category term="Gemini API"/><category term="Gemini APIs"/><category term="Gemini features"/><category term="Gemini for enterprises"/><category term="GeminiPro"/><category term="GenAI APIs"/><category term="Global Game Jam"/><category term="Global events"/><category term="Gmail"/><category term="Golf Clash"/><category term="Google AI Edge"/><category term="Google APIs"/><category term="Google Ads"/><category term="Google Apps"/><category term="Google Awareness API"/><category term="Google Cloud"/><category term="Google Developer Student Clubs"/><category term="Google Health"/><category term="Google Home app"/><category term="Google I/O 2021"/><category term="Google I/O 2026"/><category term="Google I/O 26"/><category term="Google Mobile Developer Day"/><category term="Google Now"/><category term="Google Photos"/><category term="Google Play Asset Delivery"/><category term="Google Play Developer API"/><category term="Google Play Developer API V3"/><category term="Google Play Developer API Version 3"/><category term="Google Play Developer Policies"/><category term="Google Play Games on PC"/><category term="Google Play Orders API benefits"/><category term="Google Play Points"/><category term="Google Play Protect Rewards Program"/><category term="Google Play developer distribution agreement"/><category term="Google Play monetization insights"/><category term="Google Play system updates"/><category term="Google registry"/><category term="GoogleDeveloperDay"/><category term="GoogleForGames"/><category term="GooglePlay AndroidDev"/><category term="Gpfe"/><category term="GridLayout"/><category term="Guidance on how to declare support for pointer input"/><category term="HAL"/><category term="HDR Headroom"/><category term="HTC G1"/><category term="HWASan"/><category term="Hard"/><category term="Health and Fitness"/><category term="HelloEnglish"/><category term="High Speed Recording"/><category term="Hilt"/><category term="Hiring"/><category term="Holo"/><category term="How to build Android app"/><category term="HttpsURLConnection"/><category term="Hutch"/><category term="Hutch Games"/><category term="Hybrid Interface"/><category term="HyperV"/><category term="I/O '25"/><category term="I/O 2018"/><category term="I/O 2024 KMP"/><category term="I/O 2026 announcements"/><category term="ICS"/><category term="IO"/><category term="IO 2019"/><category term="Image Attachment"/><category term="Image Processing"/><category term="Imagen"/><category term="Images"/><category term="Indie Games Fund"/><category term="Indie games developers"/><category term="Indonesia"/><category term="Indonesia Games Contest"/><category term="Industry Standards"/><category term="Industry Trends"/><category term="InkToCode"/><category term="Intel"/><category term="Intent"/><category term="Intermediate"/><category term="Introducing Android Performance Analyzer"/><category term="Inzen studio"/><category term="Issue Tracker"/><category term="J. Eason"/><category term="Jamal Eason"/><category term="Jetpack Compose 1.3"/><category term="Jetpack Compose 1.4"/><category term="Jetpack Compose 1.5"/><category term="Jetpack Core Performance library"/><category term="Jetpack Tiles Library"/><category term="JetpackCompose"/><category term="JioHotstar"/><category term="Job Scheduler"/><category term="Job Service"/><category term="KNOX"/><category term="KSP"/><category term="Key Attestation"/><category term="Keystone"/><category term="Kids experience"/><category term="Klei Entertainment"/><category term="Kotlin Event"/><category term="Kotlin Symbol Processiong"/><category term="Kotlin codelabs"/><category term="KotlinConf 2025"/><category term="LLM"/><category term="LLM Optimization"/><category term="LLM Tuning"/><category term="LTV"/><category term="LaMatinale"/><category term="Large screen"/><category term="Layout Inspector"/><category term="LeMonde"/><category term="Life of a Bug"/><category term="Lifecycle"/><category term="Lint"/><category term="Linux on Chrome OS"/><category term="Linux on Chromebooks"/><category term="LiteRT"/><category term="Live Updates"/><category term="LiveData"/><category term="Lollipop"/><category term="Low-light"/><category term="MCP"/><category term="MENA"/><category term="ML Kit Face Detection"/><category term="ML Stack"/><category term="MLKit"/><category term="Marta Gui"/><category term="Material 3 Expressive"/><category term="Media Development Kit"/><category term="Media Editing"/><category term="Media3 Effect"/><category term="MediaPipe"/><category term="Memory Safety"/><category term="MessageQueue"/><category term="Messenger"/><category term="Meta"/><category term="Mirror Mode"/><category term="Mixed Reality"/><category term="Mobilel"/><category term="Motorola Droid"/><category term="Mountain View"/><category term="Multimodal"/><category term="Multiwindow"/><category term="Munich"/><category term="Music"/><category term="MyTouch 3G"/><category term="NBU"/><category term="NFC"/><category term="NLP"/><category term="Narwhal Canary"/><category term="Nav Editor"/><category term="Navigation 3"/><category term="Navigation Sample"/><category term="Night Mode"/><category term="Niji Games"/><category term="Nix Hydra"/><category term="Non-SDK"/><category term="Notification bubbles"/><category term="Now in Arabic"/><category term="O-MG"/><category term="OAuth"/><category term="OEM"/><category term="OS Updates"/><category term="Oboe audio library"/><category term="Omnidrone"/><category term="OneTap sign-in"/><category term="OneUi7"/><category term="Ongoing Activities API"/><category term="OpenSL ES for Android"/><category term="Operating System"/><category term="Oppo"/><category term="Orientation"/><category term="OverlayEffect"/><category term="P2P"/><category term="PC"/><category term="PC gaming"/><category term="PWA"/><category term="Paging"/><category term="Pane expansion"/><category term="Parcelize"/><category term="Paris Hsu"/><category term="PasskeysWeek"/><category term="Password Manager"/><category term="Paul Gouge"/><category term="Photo Sphere"/><category term="Physics"/><category term="Pico"/><category term="Pixel 10 Pro fold"/><category term="Pixel 2"/><category term="Pixel 9"/><category term="Pixel Fold AVD"/><category term="Pixel Fold Emulator"/><category term="Pixel Tablet AVD"/><category term="Pixel Tablet Emulator"/><category term="Pixel Watch 4"/><category term="Platform Stability"/><category term="PlatformUpdate"/><category term="Platforms"/><category term="Play Console sales channel reporting"/><category term="Play Games Services"/><category term="Play IO19"/><category term="Play Quality"/><category term="Play developer identification"/><category term="Playdemic"/><category term="Playtime"/><category term="Playtime 2016"/><category term="Plugin"/><category term="Pocket Gems"/><category term="Potentially Harmful Applications"/><category term="Power Consumption"/><category term="Power Profiler"/><category term="Power Rails"/><category term="Pre-Launch Report"/><category term="Preload Manager"/><category term="PreloadManagerListener"/><category term="Preloading"/><category term="Product Inclusion"/><category term="Profileable Build"/><category term="ProfilingManager"/><category term="Programs"/><category term="Project Mainline"/><category term="Promo Graphics"/><category term="Promotions"/><category term="Prompt Library"/><category term="Protolayout"/><category term="Protolayouts"/><category term="Public Tracker"/><category term="Publishing Overview"/><category term="PyTorch"/><category term="PyTorch mobile support"/><category term="PyTorck"/><category term="Q Beta 6"/><category term="Quick Search Box"/><category term="RAW capture"/><category term="RTL"/><category term="Ratings and Reviews"/><category term="Releases"/><category term="RemoteCompose"/><category term="Restore Credentials"/><category term="Robinhood"/><category term="Room"/><category term="Rust"/><category term="SDLC"/><category term="SDV"/><category term="SMS"/><category term="SQLite"/><category term="SafeArgs"/><category term="Sam Glassenberg"/><category term="Sample app"/><category term="Samsung One UI"/><category term="Sanitizers"/><category term="Santa Tracker"/><category term="Save for later"/><category term="Schell Games"/><category term="Screen Flash"/><category term="ScreenCapture"/><category term="Security Development Lifecycle"/><category term="Selected Photos"/><category term="Sensors"/><category term="Seriously"/><category term="Server"/><category term="SessionConfig"/><category term="Sharding"/><category term="ShareActionProvider"/><category term="Shared Components"/><category term="Shared Elements"/><category term="SharedPreferences"/><category term="Shortcuts"/><category term="Signos"/><category term="Simultaneous Contrast"/><category term="Skyscanner"/><category term="Sliding Window Pattern"/><category term="Small Business"/><category term="Smart Home"/><category term="Smart Lock"/><category term="Smartlock"/><category term="Social"/><category term="Social Point"/><category term="South Korea"/><category term="Space"/><category term="Space Ape Games"/><category term="Speech Input"/><category term="Stable 1.0"/><category term="Startup Speed"/><category term="Stencils"/><category term="Storytoys"/><category term="Stripe"/><category term="Studio"/><category term="Stylus"/><category term="Submit changes"/><category term="Super Evil MegaCorp"/><category term="Survey"/><category term="System Fitness Tracker"/><category term="System Instructions"/><category term="System Media Controls"/><category term="System hardening"/><category term="TAGS: Google Play"/><category term="TEE"/><category term="Tabletop"/><category term="Tap to Pay"/><category term="Target API level"/><category term="TargetPreloadStatusControl"/><category term="Tel Aviv"/><category term="Telephony"/><category term="Text improvements"/><category term="The Android Show"/><category term="The Next Evolution in Profiling for Android"/><category term="Tiles API"/><category term="Tiles components"/><category term="Tiles material"/><category term="Timekeeping"/><category term="Timestamps"/><category term="Tips"/><category term="Titan Brawl"/><category term="Todoist"/><category term="Tor Norbye"/><category term="Touch"/><category term="Transform Preview with Gemini"/><category term="Trusted User Interface"/><category term="TrustedTime"/><category term="Twitter"/><category term="UAMP"/><category term="UI Automation"/><category term="USB speed detection"/><category term="UTP"/><category term="Universal Android Music Player"/><category term="Updatability"/><category term="Upgrade Agent"/><category term="User Acquisition"/><category term="User Feedback"/><category term="User Retention"/><category term="User-Agent Reduction"/><category term="VGames"/><category term="VOD"/><category term="Vertex AI Prompts"/><category term="Viber"/><category term="Video recording"/><category term="ViewBinding"/><category term="Virtualization"/><category term="Visibility tracking"/><category term="Vitals"/><category term="Voice"/><category term="Voice Kit"/><category term="Vulnerability"/><category term="Vulnerability Remediation"/><category term="WEI"/><category term="WFF 5"/><category term="WM"/><category term="Wakelocks"/><category term="Watch Face Studio"/><category term="Wear UI Library"/><category term="Webdriver"/><category term="What's new in Cars for developers"/><category term="Wide Color"/><category term="Widget Discovery"/><category term="WindowSizeClass"/><category term="Wired XR glasses"/><category term="Withings"/><category term="Work Manager"/><category term="World Food Day"/><category term="X"/><category term="X86"/><category term="XML"/><category term="XR"/><category term="XR Emulator"/><category term="Xiaomi"/><category term="XmlPullParser"/><category term="YouTube"/><category term="Zero-Shot Prompts"/><category term="activity-recognition"/><category term="add-ons"/><category term="advanced Android"/><category term="adventure games"/><category term="and appquality"/><category term="android 12"/><category term="android 8.0"/><category term="android audio apps"/><category term="android c++ games linux open source release osx serialization windows"/><category term="android extension pack"/><category term="android kotlin"/><category term="android o apis"/><category term="android sanitizer"/><category term="android things 1.0"/><category term="android wear 1.0"/><category term="android-dev"/><category term="android10"/><category term="android71"/><category term="android81"/><category term="android9"/><category term="androidbasics"/><category term="androiddevsummit"/><category term="androidoreo"/><category term="app attribution"/><category term="app id"/><category term="app install"/><category term="app size"/><category term="app standby buckets"/><category term="app updates"/><category term="appbundle"/><category term="application security"/><category term="applications"/><category term="arch"/><category term="arcore"/><category term="ask android"/><category term="assistive technology"/><category term="atomic"/><category term="audio playback"/><category term="audio playback capture"/><category term="audio recording"/><category term="augmented reality"/><category term="award"/><category term="awareness"/><category term="background"/><category term="background access"/><category term="background location"/><category term="backup and sync"/><category term="badge"/><category term="bar code"/><category term="beacon"/><category term="best apps 2020"/><category term="best games 2020"/><category term="betatesting GooglePlayforFamilies"/><category term="big data"/><category term="blackhat"/><category term="bootcamp"/><category term="bubbles"/><category term="bug swatting"/><category term="building 5 star apps"/><category term="building across devices"/><category term="bulletins"/><category term="business development"/><category term="calling"/><category term="car app quality"/><category term="clang"/><category term="class loading"/><category term="code sharing"/><category term="codesearch"/><category term="coding"/><category term="companion Action"/><category term="compilers"/><category term="concurrency"/><category term="concurrent camera"/><category term="conferencing"/><category term="context"/><category term="controls"/><category term="course"/><category term="crash management"/><category term="credential"/><category term="cross-device sdk"/><category term="cross-platform"/><category term="cross-platform development"/><category term="curriculum"/><category term="custom tiles"/><category term="cutout"/><category term="dalvik"/><category term="data storage"/><category term="ddms"/><category term="decompile"/><category term="deeplocal"/><category term="desktop apps"/><category term="developer community"/><category term="developer profile"/><category term="developer success"/><category term="developerappstory"/><category term="developerpreview"/><category term="developerstory developerconsole"/><category term="device id"/><category term="dex2oat"/><category term="diagnostics"/><category term="dialog full-screen dim"/><category term="digital credentials"/><category term="digital identity"/><category term="disassembly"/><category term="dynamicdelivery"/><category term="eBook"/><category term="ecosystem"/><category term="educator"/><category term="efficiency"/><category term="encoding"/><category term="explorer"/><category term="face detection"/><category term="faculty"/><category term="families"/><category term="feature combination query"/><category term="final release"/><category term="financial management"/><category term="first app"/><category term="font updates"/><category term="free trial"/><category term="full-text search"/><category term="game-as-a-service"/><category term="games business"/><category term="gaming industry"/><category term="gapid"/><category term="gdc18"/><category term="getting started"/><category term="go edition"/><category term="gold"/><category term="golf games"/><category term="google pay"/><category term="google security"/><category term="googleservices"/><category term="guide"/><category term="heading"/><category term="health"/><category term="heart rate sensor"/><category term="high dynamic range"/><category term="high frame rate"/><category term="how to develop audio apps for android"/><category term="how to increase app revenue Google Play"/><category term="http"/><category term="i18n"/><category term="iOS development"/><category term="image description"/><category term="imakeapps"/><category term="in-app transactions"/><category term="in-car experiences"/><category term="insider attack resistance"/><category term="install referrer"/><category term="install track"/><category term="installs"/><category term="instant"/><category term="instant experience"/><category term="instant games"/><category term="instructor"/><category term="interactive divider"/><category term="internationalization"/><category term="internet"/><category term="intuit"/><category term="io16"/><category term="io18"/><category term="jetpack media3"/><category term="jobscheduler"/><category term="journeys testing"/><category term="journeys with gemini"/><category term="key"/><category term="keymaster"/><category term="keymint"/><category term="keys"/><category term="keystore"/><category term="kids app developers"/><category term="kids apps"/><category term="ktx"/><category term="l10n"/><category term="language id"/><category term="language identification"/><category term="laptop apps"/><category term="large screen devices"/><category term="latency"/><category term="latest."/><category term="leanback"/><category term="learning"/><category term="listing"/><category term="liveops"/><category term="location access"/><category term="location data"/><category term="lock contention"/><category term="lock-free"/><category term="long aspect ratio"/><category term="longevity"/><category term="machine"/><category term="marble"/><category term="media playback"/><category term="meet"/><category term="messaging api"/><category term="minSdkVersion"/><category term="mobile ads"/><category term="mobile driving license"/><category term="mobile encryption"/><category term="mobile search"/><category term="monitoring"/><category term="motion"/><category term="motion."/><category term="multi-display support"/><category term="multi-product checkout"/><category term="multiplayer"/><category term="music player"/><category term="musician apps"/><category term="native development"/><category term="native libraries"/><category term="navigation apps"/><category term="network"/><category term="new Play developer accounts"/><category term="new with Cast"/><category term="nonce field"/><category term="oboe"/><category term="of"/><category term="official launch"/><category term="offline"/><category term="on-device AI"/><category term="optimize app ARPPU"/><category term="optimized resource shrinking"/><category term="ordered broadcast"/><category term="oscon"/><category term="outreach"/><category term="packaging"/><category term="partial"/><category term="passwordless authentication"/><category term="patch level"/><category term="patching"/><category term="pathway"/><category term="peer group"/><category term="perfetto"/><category term="performance class"/><category term="performancetools"/><category term="phone"/><category term="photo picker"/><category term="play billing"/><category term="play billing library"/><category term="play core"/><category term="playback resumption"/><category term="playbook app"/><category term="playconsole"/><category term="player engagement"/><category term="policy violations"/><category term="postview"/><category term="pre rotation"/><category term="pre-leaunch"/><category term="preinstalled apps"/><category term="preloaded apps"/><category term="priority inversion"/><category term="pro audio"/><category term="problem solving"/><category term="programming"/><category term="project marble"/><category term="protection"/><category term="provisioning"/><category term="publishing"/><category term="purchase flows"/><category term="push messaging"/><category term="pwn"/><category term="real world identity"/><category term="real-time audio"/><category term="recaptcha"/><category term="reduce app churn strategies"/><category term="registration"/><category term="requirement"/><category term="revenue"/><category term="robotics"/><category term="rotation"/><category term="runtime"/><category term="runtime permissions"/><category term="sandbox ads"/><category term="sanitizer"/><category term="schools"/><category term="screen"/><category term="screensharing"/><category term="sdk"/><category term="seamless transfer"/><category term="secondhand"/><category term="secure hardware"/><category term="security infrastructure"/><category term="selinux"/><category term="sensors-and-location"/><category term="service fees"/><category term="sign-in"/><category term="slow motion"/><category term="smart reply"/><category term="smartwatch design"/><category term="smr"/><category term="source code"/><category term="spam"/><category term="spatial audio"/><category term="spyware"/><category term="stability"/><category term="stable"/><category term="storelistingexperime"/><category term="strictmode"/><category term="study group"/><category term="success"/><category term="suggested fixes for crashes"/><category term="synthetics"/><category term="system UI"/><category term="system fonts"/><category term="tamper-resistant hardware security"/><category term="targeted spyware"/><category term="taxation"/><category term="taxes"/><category term="teach"/><category term="telecom"/><category term="text styling API"/><category term="textclassifier"/><category term="texture compression"/><category term="textview"/><category term="threading"/><category term="time zone"/><category term="titan"/><category term="traceview"/><category term="tradein"/><category term="transition api"/><category term="transitions"/><category term="trial period"/><category term="trust"/><category term="university"/><category term="user control"/><category term="user location"/><category term="user safety"/><category term="version"/><category term="video call"/><category term="video editing"/><category term="video playback"/><category term="videocall"/><category term="viewfinder"/><category term="viewpager"/><category term="virtual instruments"/><category term="voice call"/><category term="voip"/><category term="vulnerabilities"/><category term="wake locks"/><category term="wear emulators"/><category term="web registry"/><category term="wellness"/><category term="window"/><category term="“Privacy Sandbox on Android”"/><title type="text">Android Developers Blog</title><subtitle type="html">An Open Handset Alliance Project.</subtitle><link href="http://android-developers.googleblog.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/" rel="alternate" type="text/html"/><link href="http://pubsubhubbub.appspot.com/" rel="hub"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/><author><name>Birna</name><uri>http://www.blogger.com/profile/04044883525253664551</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><generator uri="http://www.blogger.com" version="7.00">Blogger</generator><openSearch:totalResults>2060</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-6766967387297621648</id><published>2026-08-31T09:00:00.000-07:00</published><updated>2026-08-31T09:00:23.581-07:00</updated><title type="text">Emulator control for adaptive app development</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCQsu918ozPnYGqHeRBhQloNpT7ahw1BtBs97BDcUQWNgJoFv5UE_COINTQ2Ya1u8319UoLFzEl5Wz-10eGwB3Qbi-NmDEkOljLUiBNb1KOeEV83VoGRY7SUex8-aRZuSJNkHkbmt-2rJ_s3QhdxLwSQB0AYDUJo3Tcs5XE89CLHvuR47bPnK04OPTB9Y/s2469/%5BABL_123%5D%20Streamline%20adaptive%20testing%20with%20emulator%20commands_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCQsu918ozPnYGqHeRBhQloNpT7ahw1BtBs97BDcUQWNgJoFv5UE_COINTQ2Ya1u8319UoLFzEl5Wz-10eGwB3Qbi-NmDEkOljLUiBNb1KOeEV83VoGRY7SUex8-aRZuSJNkHkbmt-2rJ_s3QhdxLwSQB0AYDUJo3Tcs5XE89CLHvuR47bPnK04OPTB9Y/s2469/%5BABL_123%5D%20Streamline%20adaptive%20testing%20with%20emulator%20commands_Meta.png" style="display: none;" /&gt;
&lt;i&gt;Posted by Rob Orgiu, Developer Relations Engineer, Adaptive Apps, Android&lt;/i&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO0zMwpcBq5LYxHaNarJBD_tAelQXRfOab9l11lpZzKwoF3RHM9cIPJNu1VoMcV-MNaorKjjNH97okdMRbO5ZQJTRbFssC7kX2AjikUKhTjWLsjgnp-LdU-OfowomiOZAsJ0PxDqpqTPVmuRl5HOMqJ55kNfVeX6al8h-d0RKxZOcVhDKB-83cx1OLlok/s8583/%5BABL_123%5D%20Streamline%20adaptive%20testing%20with%20emulator%20commands_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO0zMwpcBq5LYxHaNarJBD_tAelQXRfOab9l11lpZzKwoF3RHM9cIPJNu1VoMcV-MNaorKjjNH97okdMRbO5ZQJTRbFssC7kX2AjikUKhTjWLsjgnp-LdU-OfowomiOZAsJ0PxDqpqTPVmuRl5HOMqJ55kNfVeX6al8h-d0RKxZOcVhDKB-83cx1OLlok/s1600/%5BABL_123%5D%20Streamline%20adaptive%20testing%20with%20emulator%20commands_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Adaptive app development is fundamental on Android, but making sure everything looks good and every feature works the way it should require multiple tests on multiple devices. Or does it?&lt;/p&gt;

&lt;p&gt;Well, yes… and no! While Android Studio is bundled with the Resizable Emulator to let you test layouts manually, there’s a faster, more streamlined way to control form factors directly from your terminal. By leveraging fire-and-forget console commands using the &lt;code&gt;adb emu&lt;/code&gt; shortcut, you can execute commands that immediately return control to your invoking shell.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;If you have multiple emulators running at the same time, you can target a specific virtual device by passing in the shortcut's serial:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb -s &amp;lt;serial&amp;gt; emu &amp;lt;command&amp;gt; &amp;lt;parameter&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3 style="text-align: left;"&gt;First things first: Fold and unfold&lt;/h3&gt;&lt;p&gt;To test foldable-specific user journeys and layout configurations, you can fold and unfold your emulated device programmatically.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu fold&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If your foldable emulator is unfolded, you can fold it to display its smaller screen configuration, powering on the (virtual) external display. To unfold the emulator and power on the internal display, simply run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu unfold&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, you can instantly verify that your app preserves its state and that layouts appear exactly as they should on different display sizes.&lt;/p&gt;

&lt;h3 style="text-align: left;"&gt;Rotation, rotation, rotation&lt;/h3&gt;&lt;p&gt;Correctly handling orientation changes is a cornerstone of adaptive app development. You can trigger device rotations programmatically to test how well your app handles configuration changes, including state restoration. The following command rotates the device 90° clockwise:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu rotate&lt;/code&gt;&lt;/pre&gt;

&lt;h3 style="text-align: left;"&gt;Simulating postures using sensors&lt;/h3&gt;&lt;p&gt;What about placing the emulator into a specific physical posture, like tabletop mode? The easiest approach is querying for the number of available positions with .&lt;/p&gt;

&lt;p&gt;First, list all available sensors and their current status:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu posture&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This returns&amp;nbsp; a list of positions similar to the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Usage: "posture &amp;lt;posture_id&amp;gt;" 1: closed	2: half-opened	3: opened	…&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can then invoke the tabletop posture by using the half-opened ID:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu posture 2&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;i&gt;&lt;span style="color: #444444;"&gt;&lt;b&gt;Note: Not all postures are supported by every virtual device. Standard AVD templates like the Pixel Fold or the Resizable AVD only support postures 1 , 2 , and 3 . Attempting to set 4 or 5 on these templates will return a KO: Failed to set posture error.&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: left;"&gt;What about the resizable emulator?&lt;/h3&gt;The resizable emulator has the super power to change its size with ease. With the &lt;code&gt;adb emu&lt;/code&gt; command, you can move it freely with one command. Before you can do any changes, querying for the available resize presets requires only one call:&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu resize-display&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will return the list of available presents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KO usage: "resize-display &amp;lt;index&amp;gt;" 0: phone	1: unfolded	2: tablet&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, invoking the resize-display parameter with the wanted ID will resize the emulator to the wanted size:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adb emu resize-display 1&lt;/code&gt;&lt;/pre&gt;

&lt;h3 style="text-align: left;"&gt;Streamline your testing today&lt;/h3&gt;&lt;p&gt;And that's it! By integrating fire-and-forget commands into your command-line workflow, you save a lot of time and resources compared to running multiple emulators simultaneously.&lt;/p&gt;

&lt;p&gt;Now is the time to start experimenting. If you haven't used these console shortcuts before, open up your terminal, fire up your emulator, &lt;a href="https://developer.android.com/studio/run/emulator-console" target="_blank"&gt;head over to the documentation&lt;/a&gt;, and get started today!&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/6766967387297621648/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/emulator-adaptive.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6766967387297621648" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6766967387297621648" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/emulator-adaptive.html" rel="alternate" title="Emulator control for adaptive app development" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCQsu918ozPnYGqHeRBhQloNpT7ahw1BtBs97BDcUQWNgJoFv5UE_COINTQ2Ya1u8319UoLFzEl5Wz-10eGwB3Qbi-NmDEkOljLUiBNb1KOeEV83VoGRY7SUex8-aRZuSJNkHkbmt-2rJ_s3QhdxLwSQB0AYDUJo3Tcs5XE89CLHvuR47bPnK04OPTB9Y/s72-c/%5BABL_123%5D%20Streamline%20adaptive%20testing%20with%20emulator%20commands_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-2142519968365769225</id><published>2026-08-27T10:00:00.000-07:00</published><updated>2026-08-28T10:10:10.680-07:00</updated><title type="text">How WhatsApp Upgraded to Secure, Seamless Sign-In for 1 Billion Users with Passkeys</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGAONWXboSifa5iIBDqZhlyepp3OtXMzKrhnluPZqHKLlQ-oUE7xmHG9l0eVz7z4a_Xlan3w7Wr-FwhTZFQ2mcPqgzOGv3G7Sny756QYTIwczo_D3OG_gSWcxvDJFXQDd4lPhUTqXwgiCCadfA6WAT_lUVgRr6GyozoYCnkPY6wSXNqfqJGC-HV6MNduY/s2048/ANDDM_Passkeys_Metacard.png" /&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGAONWXboSifa5iIBDqZhlyepp3OtXMzKrhnluPZqHKLlQ-oUE7xmHG9l0eVz7z4a_Xlan3w7Wr-FwhTZFQ2mcPqgzOGv3G7Sny756QYTIwczo_D3OG_gSWcxvDJFXQDd4lPhUTqXwgiCCadfA6WAT_lUVgRr6GyozoYCnkPY6wSXNqfqJGC-HV6MNduY/s2048/ANDDM_Passkeys_Metacard.png" style="display: none;" /&gt;

&lt;div style="margin-bottom: 1.5em; line-height: 1.5;"&gt;
  &lt;i&gt;Posted by Niharika Arora, Senior Developer Relations Engineer, Tracy Agyemang, Product Marketing Manager, Google and Mayank Manuja, Android Engineer, Meta&lt;/i&gt;
&lt;/div&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEhUHPaGaRvrcsRsnWd4IrnlDhp7qQi7NXX8Tw2z7jPcCOw61MvzahqArQwcJE_4PhrKk6Pfl3p_V_BK_SyMT-6AqSRksocMZL_8i002dIjrzEArmzxGKJLrNYZEHjzqt1ylVBbfHURUpLBO4_RBvdaqJxRnn4d6MUheG4olb9voYy7HcCbfrBkxykMivl0" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: none;" alt="WhatsApp passkey banner" /&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.whatsapp&amp;amp;hl=en_IN" target="_blank"&gt;WhatsApp&lt;/a&gt; is the world's largest messaging platform, serving billions of users globally. It is the default communication tool for people across diverse regions, connecting users through private, reliable, and secure messaging.&lt;/p&gt;

&lt;p&gt;"What excites me most is the sheer scale of WhatsApp's impact. Even a small improvement to WhatsApp touches billions of users worldwide," says Mayank Manuja, an Android Engineer on the WhatsApp Registration and Access team who led the design and implementation of passkey-based authentication for WhatsApp.&lt;/p&gt;

&lt;p&gt;Building for an audience of this magnitude requires navigating a vast range of network conditions, device capabilities, and levels of digital literacy. Recognizing the potential early, WhatsApp committed to adopting passkeys in 2023, becoming one of the first major consumer apps to integrate the technology. By implementing passkeys, WhatsApp aimed to provide a fast, phishing-resistant option that significantly reduces user friction while providing robust protection against account takeovers and credential theft.&lt;/p&gt;

&lt;div class="separator" style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3DhE6boxs7muAVBzxKfPlwkP3EXyHr0-27x-qP0-imGubN7-F8rZJWQfJi4kw8I9AJo-GlgJgSYXzuKoU62V3iGyoTRGn5NmUqMXdiqPU4ivrWE2V6GGnzFr-tMCqXAZa1CaXg0o27fQRHgTGYoO48Rw11O4vQUvs0rI2KahrSnj7WqVnc4iLnZD6vIU/s1920/UpdatedVideo.gif" style="display: block;"&gt;
    &lt;img border="0" data-original-height="1920" data-original-width="1080" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3DhE6boxs7muAVBzxKfPlwkP3EXyHr0-27x-qP0-imGubN7-F8rZJWQfJi4kw8I9AJo-GlgJgSYXzuKoU62V3iGyoTRGn5NmUqMXdiqPU4ivrWE2V6GGnzFr-tMCqXAZa1CaXg0o27fQRHgTGYoO48Rw11O4vQUvs0rI2KahrSnj7WqVnc4iLnZD6vIU/w360-h640/UpdatedVideo.gif" style="max-width: 100%; height: auto; display: block; margin: 0 auto;" alt="Passkey setup walkthrough animation" /&gt;
  &lt;/a&gt;
  &lt;div style="font-size: 0.9em; color: #555; margin-top: 0.5em;"&gt;A user creating a passkey on WhatsApp for faster, more secure sign-ins.&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;The Decision to Adopt Passkeys&lt;/h2&gt;

&lt;p&gt;For WhatsApp, offering multiple access methods is key to making it easier for users to stay connected and regain access when needed. &lt;a href="https://developer.android.com/identity/passkeys" target="_blank"&gt;Passkeys&lt;/a&gt; offer users a streamlined, one-tap login experience that eliminates phishing risks and functions reliably even in regions where OTP message delivery can be inconsistent.&lt;/p&gt;

&lt;p&gt;Underneath, passkeys leverage public-private key cryptography to replace manual entry with biometric or screen lock authentication. This workflow drastically improves sign-in speeds by reducing the process to a single tap via a unified, bottom-sheet interface that keeps users engaged within the app's context. The benefits are twofold: passkeys offer users a streamlined login experience while simultaneously providing robust, native protection against phishing attacks. Crucially, they function reliably even in regions where traditional SMS OTP delivery can be inconsistent.&lt;/p&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEhEuhBNptAiQX2s_lLFIiEKyEzsk0ecg-vNxhfYpWGWb56KUIKqXyiAiGhqOxtEzPxjSd4UyWJgC-BA9T6QaftQrzB8GyPJX8OdV3X9Qtcx7NfJLSzVIreIfTrY02NT49e85nv-eWNoxDJU7UKnabxUdgxKn5iLvO3n_phX-zvWB18RiW9bsi-z3LKeqoo" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: none;" alt="Public-private key cryptography flow" /&gt;
  &lt;div style="font-size: 0.9em; color: #555; margin-top: 0.5em;"&gt;How passkeys are saved and used to authenticate using public-private key cryptography&lt;/div&gt;
&lt;/div&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEiHV3mjNiN4_EaUUV_H-Ye4hgEx6B5of3dKEEmK1fbkTON62LATSbmU_BM43Jo1FawU6l1GWEHx17eau2j9huu_q4XIwsyhPukWM395QbZehQ7PIJV0sLmrngM3FEfo7DHK8zhpxXAedVIaM_0tG8Dpay2B7h0ztqVRSLRg0ajoZqtswXezLZQTaQQ3ilk" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: none;" alt="Passkeys security architecture overview" /&gt;
&lt;/div&gt;

&lt;p&gt;Having robust and diverse account access methods ensures that users are never locked out of what matters most to them.&lt;/p&gt;

&lt;h2&gt;Client-Side Integration&lt;/h2&gt;

&lt;p&gt;From the WhatsApp developer perspective, the Credential Manager API provided a clean, unified interface that abstracted away the complexity of underlying credential providers. Once initial integration flows were mapped out, the API surface became straightforward, with credential creation and retrieval following well-defined request and response patterns. Find the implementation guide in the &lt;a href="https://developer.android.com/identity/passkeys/create-passkeys" target="_blank"&gt;Android developer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While the happy path worked from the start, navigating a diverse user base across OEMs, multiple Android versions, and varied device configurations (such as PIN-only versus biometric, or Android 13 versus 14+) surfaced unprecedented edge cases. These included users without a screen lock, unexpected exception types, outdated Play Services, and inconsistent credential provider behavior.&lt;/p&gt;

&lt;p&gt;To overcome these hurdles, the WhatsApp and Google teams collaborated deeply and tackled several challenges:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Optimizing the credential lookup flow:&lt;/strong&gt; The initial lookup flow exhibited poor latency, particularly for users who had not yet created a passkey. Since the majority of WhatsApp users fall under this bucket in early stages, this added noticeable delay to nearly every sign-in. By instrumenting the call path and identifying bottlenecks together, WhatsApp significantly fastened up the process, achieving performance gains that ultimately benefited the entire Android ecosystem.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Handling transient states:&lt;/strong&gt; WhatsApp built a comprehensive error-handling layer to navigate device-specific hurdles such as password manager availability, screen lock not configured, intermittent connectivity issues, incompatible hardware, outdated play services, categorizing exceptions into recoverable and terminal states. This allowed for graceful degradation, if a passkey flow could not complete, the system safely fell back to traditional authentication without leaving the user in a broken state.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Navigating OS-specific exceptions:&lt;/strong&gt; When telemetry revealed device-specific hurdles such as GetPublicKeyCredentialDomException (Failed to decrypt credential) on certain Android 13 devices, and CreatePublicKeyCredentialDomException (Unable to get sync account) during passkey creation on Android 14, Google and the WhatsApp team investigated the root causes and implemented platform-level improvements to ensure smoother creation flows. You can find the comprehensive error guide &lt;a href="https://developer.android.com/identity/passkeys/create-passkeys" target="_blank"&gt;here&lt;/a&gt; which lists common error codes and descriptions related to Credential Manager, and provides some information about their causes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color: #444444;"&gt;Note: For further guidance, explore the &lt;a href="https://android-developers.googleblog.com/2025/09/best-practices-migrating-users-passkeys-credential-manager.html" target="_blank"&gt;Passkeys best practices blog&lt;/a&gt; to learn how to optimize the user experience when adopting passkeys.&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;

&lt;h2&gt;Refining the User Experience&lt;/h2&gt;

&lt;p&gt;Because passkeys were an entirely new concept in early 2023, there were no established patterns for prompting their creation. Through extensive A/B testing, WhatsApp developed a contextual framework targeting users who would benefit most. This strategy continuously evolved: as Android OS flows matured into a streamlined, single-screen experience, WhatsApp simplified its own prompts to avoid redundant or confusing UI.&lt;/p&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEgWMep-pY28YAdsTyp8XVFUZZ6y7lC71bX0sCr8Iym1iHsFhusrFdOjiQNxvE6PF0CfbNiJ0ylh_-V5zZ-D3hBTBIUJ1sPZ4YX87soOobX0sjIdNAGWGj5AMiuQEUDHlDKwFdMuSQPjWsolZjldGHKvObqXEhLakOlnq_NWBsNh50r8MHTsDqndOIe5ACE" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: none;" title="Case-Study-1.png" alt="WhatsApp passkey screen setup" /&gt;
  &lt;div style="font-size: 0.9em; color: #555; margin-top: 0.5em;"&gt;WhatsApp's streamlined, single-screen passkey creation flow&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Server-Side Architecture and Cross-Platform Hurdles&lt;/h2&gt;

&lt;p&gt;On the backend, WhatsApp's server implements the standard WebAuthn/FIDO2 ceremonies. The backend is written in Erlang and calls the Rust webauthn-rs library through a native interface. This Rust library handles signature verification and credential parsing, allowing the internal code to remain focused on orchestration, storage, and product rules like eligibility, rate-limiting, and credential lifecycle.&lt;/p&gt;

&lt;p&gt;The server architecture orchestrates these core ceremonies through four primary entry points, paired into Begin and Finish sequences for both Registration and Authentication:&lt;/p&gt;

&lt;h3&gt;1. Passkey registration&lt;/h3&gt;

&lt;p&gt;This sequence handles issuing creation options to the client, verifying the attestation once the client acknowledges successful creation, and securely persisting the credential.&lt;/p&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img alt="The server &amp;amp; client interaction architecture during passkey registration" src="https://blogger.googleusercontent.com/img/a/AVvXsEgQrF0mavvlBedNMSkRUpprg5mJccLvIHlIPVGl2QS0WLk31zDXtYuXeykoXyaQ8lNr9957MepK__A8g-7X3VMyNbgheLLYrkqcQVf38sh4Lwe2Kkkbfuimw20ncITWigXPOzy3fheE1Pl-79vvoZ62ibNWoB8j02uTJcSUYQmPytXeaJu7h_lLHATuJtg" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: 1pt solid rgb(67, 67, 67); box-sizing: border-box;" /&gt;
  &lt;div style="font-size: 0.9em; color: #555; margin-top: 0.5em;"&gt;The server &amp;amp; client interaction architecture during passkey registration&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Erlang: Begin Registration&lt;/strong&gt;&lt;/p&gt;
&lt;pre style="overflow-x: auto; background-color: #f6f8fa; padding: 12px; border-radius: 6px; font-size: 13px; max-width: 100%; box-sizing: border-box;"&gt;&lt;code&gt;begin_registration(UserId) -&amp;gt;
    Existing = list_credentials(UserId),
    %% reuse the existing user handle, or mint a new one
    {UserHandle, IsNew} = user_handle(Existing),
    %% returns the client creation options and the server-side challenge state
    #{client_safe := CreationOptions, server_only := ChallengeState} =
        webauthn:start_registration(UserId, UserHandle, rp_config()),
    %% excludeCredentials: the user's existing credential IDs, so the device won't re-enroll one
    Options = with_exclude_credentials(CreationOptions, credential_ids(Existing)),
    store_challenge(UserId, ChallengeState),          %% short TTL
    IsNew andalso reserve_user_handle(UserId, UserHandle),
    Options.&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Identify the user:&lt;/strong&gt; The server first checks for any existing credentials to either reuse an existing user handle or generate a new one.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generate options and challenge:&lt;/strong&gt; It calls the WebAuthn library to generate the creation options for the client and a secure challenge state for the server.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Prevent duplicates:&lt;/strong&gt; It explicitly excludes the user's existing credential IDs so that the device does not accidentally re-enroll a passkey that is already registered.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Store challenge:&lt;/strong&gt; The server temporarily stores the challenge with a short time-to-live (TTL) and sends the options back to the client device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Erlang: Finish Registration&lt;/strong&gt;&lt;/p&gt;
&lt;pre style="overflow-x: auto; background-color: #f6f8fa; padding: 12px; border-radius: 6px; font-size: 13px; max-width: 100%; box-sizing: border-box;"&gt;&lt;code&gt;finish_registration(UserId, Attestation) -&amp;gt;
    ChallengeState = get_challenge(UserId),          %% must exist and be unexpired
    #{credential_id := CredId, public_key := PubKey} =
        webauthn:finish_registration(Attestation, ChallengeState, rp_config()),
    ok = index_credential(CredId, UserId),            %% map credential_id -&amp;gt; account
    case multi_passkey_enabled(UserId) of
        true  -&amp;gt; add_credential(UserId, CredId, PubKey);      %% append (oldest evicted past the cap)
        false -&amp;gt; replace_credential(UserId, CredId, PubKey)   %% single-passkey mode
    end,
    notify_client(UserId, {passkey_created, CredId}),
    ok.&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Retrieve challenge:&lt;/strong&gt; The server retrieves the stored challenge, ensuring it still exists and hasn't expired.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Verify attestation:&lt;/strong&gt; It passes the client's response (Attestation) and the challenge to the WebAuthn library to verify the request and extract the new credential ID and public key.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Index the credential:&lt;/strong&gt; The new credential ID is mapped directly to the user's account for fast lookup later.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Save and manage limits:&lt;/strong&gt; Depending on whether the multi-passkey feature is enabled, the server will either append the new credential to the user's list (evicting the oldest if a cap is reached) or replace the existing one in single-passkey mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;2. Credential Authentication&lt;/h3&gt;

&lt;p&gt;Similar to creation, the app server handles the authentication flow by orchestrating the login sequence. This includes verifying the assertion after successful client authentication, and dynamically updating stored credentials whenever WebAuthn signals a refresh is necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Erlang: Begin Authentication&lt;/strong&gt;&lt;/p&gt;
&lt;pre style="overflow-x: auto; background-color: #f6f8fa; padding: 12px; border-radius: 6px; font-size: 13px; max-width: 100%; box-sizing: border-box;"&gt;&lt;code&gt;begin_authentication(UserId) -&amp;gt;
    Credentials = list_valid_credentials(UserId),
    #{client_safe := RequestOptions, server_only := ChallengeState} =
        webauthn:start_authentication(Credentials, rp_config()),
    store_challenge(UserId, ChallengeState),          %% short TTL
    RequestOptions.&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Fetch valid credentials:&lt;/strong&gt; The server looks up all currently valid credentials associated with the user.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generate challenge:&lt;/strong&gt; It uses those credentials to build request options for the client and generates a new server-side challenge.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Store and return:&lt;/strong&gt; Just like in registration, the challenge is saved temporarily, and the request options are passed to the client app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Erlang: Finish Authentication&lt;/strong&gt;&lt;/p&gt;
&lt;pre style="overflow-x: auto; background-color: #f6f8fa; padding: 12px; border-radius: 6px; font-size: 13px; max-width: 100%; box-sizing: border-box;"&gt;&lt;code&gt;finish_authentication(UserId, Assertion) -&amp;gt;
    ChallengeState = get_challenge(UserId),
    Credentials = list_valid_credentials(UserId),
    case webauthn:finish_authentication(Credentials, Assertion, ChallengeState) of
        #{user_verified := true, credential_id := CredId, needs_update := NeedsUpdate} = Result -&amp;gt;
            %% webauthn tells us when the stored credential should be refreshed
            NeedsUpdate andalso refresh_credential(UserId, CredId, Result),
            mark_credential_used(UserId, CredId),
            {ok, CredId};
        _ -&amp;gt;
            {error, not_allowed}
    end.&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Verify assertion:&lt;/strong&gt; The server retrieves the stored challenge and valid credentials, then asks the WebAuthn library to verify the client's Assertion.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Refresh if needed:&lt;/strong&gt; If the user is successfully verified, the server checks a needs_update flag. The WebAuthn library uses this flag to signal if the stored credential state needs to be refreshed on the server.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Finalize:&lt;/strong&gt; The server marks the credential as used and successfully completes the login process.&lt;/li&gt;
&lt;/ul&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEgnuu1jtm1QGCkLZc5AixjAyHB9jW7iPGw7Exm5FG2LRqZuMNmINbBRQacaswh-o1uMKO2FLSEPaF2D7qSaq_Z1JFsSNM7QYvhODFqx7H3iS8DUJTxA2tOtkD2JcfZHkaO3ycoYQp6QOVM7MxocJqD1CPWsZlvhbwcnwylkpvLYp8CFN6TKHFP7Ee_hlYY" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: none;" title="Case-Study-2.png" alt="Step-by-step passkey login experience" /&gt;
  &lt;div style="font-size: 0.9em; color: #555; margin-top: 0.5em;"&gt;The step-by-step passkey login experience on the WhatsApp app.&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;To know more about server registration, follow the integration guide &lt;a href="https://developers.google.com/identity/passkeys/developer-guides/server-registration" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Advanced Architectural Considerations&lt;/h2&gt;

&lt;p&gt;Implementing passkeys on the server at scale presented unique challenges, particularly concerning account architecture and device synchronization. Ashish Choudhary from the WhatsApp backend team highlighted the primary hurdles they faced:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Migrating to multiple passkeys per account:&lt;/strong&gt; WhatsApp's legacy server logic was deeply intertwined with the assumption of a single credential per user. To support modern multi-device realities, they engineered a bounded list system that intelligently evicts the oldest credential once a limit is reached. To ensure absolute stability, this major structural shift was rolled out gradually through rigorous experimentation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Balancing the credential lifecycle:&lt;/strong&gt; Managing credential validity required a delicate touch. Invalidating credentials too aggressively forces needless re-enrollments, while being too lenient lets stale credentials pile up. WhatsApp solved this by implementing balanced lifecycle states to maintain tight security without frustrating users, complemented by automated background cleanup for inactive passkeys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Rethinking Cross-Device Synchronization&lt;/h2&gt;

&lt;p&gt;This robust multi-passkey architecture also allowed WhatsApp to completely rethink cross-platform usability. The standard WebAuthn cross-device flow requires scanning a QR code on one device and authenticating over Bluetooth on another. However, WhatsApp found the Bluetooth dependency unreliable, and users often confused the new QR codes with the existing WhatsApp Web linking process.&lt;/p&gt;

&lt;p&gt;Instead of forcing a fragile cross-device transport mechanism, WhatsApp allows users to hold passkeys natively across multiple ecosystems such as Google Password Manager on Android and iCloud Keychain on iOS. When users migrate to a new platform, they simply generate a fresh passkey during their next sign-in. This approach is completely frictionless for the user and operates seamlessly on top of the new multi-passkey server infrastructure.&lt;/p&gt;

&lt;h2&gt;Looking Ahead&lt;/h2&gt;

&lt;p&gt;Since launching passkeys, WhatsApp has witnessed robust organic adoption across its vast user base. By transforming the traditional multi-step sign-in process into a single, frictionless biometric gesture, the app has dramatically improved the user experience. Building on this momentum, WhatsApp is now expanding passkey utility beyond initial sign-ins, exploring seamless in-app re-authentication for sensitive account actions like passkey-encrypted backups.&lt;/p&gt;

&lt;p&gt;Looking ahead, WhatsApp is actively collaborating with platform partners to pioneer lower-friction credential creation paths, anticipating that barriers to entry will naturally diminish as device biometric capabilities expand.&lt;/p&gt;

&lt;h2&gt;Recommendation for Developers Building at Scale&lt;/h2&gt;

&lt;p&gt;For developers preparing to integrate passkeys at scale, the WhatsApp team shares these critical recommendations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Invest in an error taxonomy early:&lt;/strong&gt; Categorize the wide variety of Credential Manager exceptions into recoverable versus terminal states, and define clear, graceful fallback paths for each scenario.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Understand your eligibility funnel:&lt;/strong&gt; Instrument device capability checks such as screen lock presence, biometric hardware, and Play Services versions and design flows to proactively exclude ineligible users rather than failing mid-flow.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Prepare your app for fallback:&lt;/strong&gt; Use passkeys as an optimal primary authentication method for capable devices, but always retain traditional methods as a reliable, universal fallback.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan for OS version fragmentation:&lt;/strong&gt; Passkey behavior can differ across operating systems. Test thoroughly on Android 13, 14, and 15+, and account for OEM-specific variations in the credential selection UI.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Upsell contextually and educate:&lt;/strong&gt; Present passkey creation naturally during security-relevant actions. Clearly emphasize the value proposition (speed and security) using accessible language to drive user adoption.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Monitor proactively:&lt;/strong&gt; The ecosystem evolves with every OS update. Continuously track latency and error patterns to stay ahead of shifting device landscapes.&lt;/li&gt;
&lt;/ul&gt;

&lt;div style="text-align: center; margin: 1.5em 0;"&gt;
  &lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEhfPG-edHN3BgDMmQ3OS6YG5allmOvjMfakBWSpTMOKrAwc7-rcTXwCVaD1P1DxUzo243Lnyc0SHc5tBJb1q0F-2Rnhwe3ed9Z-8ldVY208Pg79q7R-QHKy-dsaBXgbDbxciHJkHxmlZ0zyydYcQHOFBdf9deGlGHUqzCsWS-CIZ47Yw4I5we9gsHGd1HI" style="max-width: 100%; height: auto; display: block; margin: 0 auto; border: none;" alt="WhatsApp passkey summary diagram" /&gt;
&lt;/div&gt;

&lt;h2&gt;Get Started with Passkeys and Credential Manager&lt;/h2&gt;

&lt;p&gt;Get hands on with passkeys and Credential Manager on Android using our &lt;a href="https://developer.android.com/identity/credential-manager" target="_blank"&gt;integration guide&lt;/a&gt; and &lt;a href="https://github.com/android/identity-samples/tree/main/Shrine" target="_blank"&gt;public sample code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions or issues, you can share with us through the &lt;a href="https://github.com/android/identity-samples/tree/main/Shrine" target="_blank"&gt;Android Credentials issues tracker&lt;/a&gt;.&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/2142519968365769225/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/whatsapp-passkeys-secure-sign-in.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/2142519968365769225" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/2142519968365769225" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/whatsapp-passkeys-secure-sign-in.html" rel="alternate" title="How WhatsApp Upgraded to Secure, Seamless Sign-In for 1 Billion Users with Passkeys" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGAONWXboSifa5iIBDqZhlyepp3OtXMzKrhnluPZqHKLlQ-oUE7xmHG9l0eVz7z4a_Xlan3w7Wr-FwhTZFQ2mcPqgzOGv3G7Sny756QYTIwczo_D3OG_gSWcxvDJFXQDd4lPhUTqXwgiCCadfA6WAT_lUVgRr6GyozoYCnkPY6wSXNqfqJGC-HV6MNduY/s72-c/ANDDM_Passkeys_Metacard.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-3046254478597816363</id><published>2026-08-26T10:00:00.000-07:00</published><updated>2026-08-27T12:57:42.296-07:00</updated><title type="text">Elevating app quality: Reducing memory usage and improving device migration</title><content type="html">&lt;i&gt;Posted by Raghavendra Hareesh Pottamsetty, GM, Google Play Developer &amp;amp; Monetization&lt;/i&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTRcluZ2sIWzgtqECLI7tz8XZkws6VtGWVJXK2uAb6zaq9GS0IIRTYaf4OPGdRe0sHEUwr9YvR1dtCxf6QC8UpOXNpMXg9gWmjmkj20q0O9-E_MxdWdDOCt8eWEPUiBW_hyphenhyphenyk7r9xzjq6d6wOBpzYZf5KDWf8wT015W9Pr9PAPG5ptSgi8Msdi20UcqiM/s4209/Raising-the-bar---Google-Play-Header-2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTRcluZ2sIWzgtqECLI7tz8XZkws6VtGWVJXK2uAb6zaq9GS0IIRTYaf4OPGdRe0sHEUwr9YvR1dtCxf6QC8UpOXNpMXg9gWmjmkj20q0O9-E_MxdWdDOCt8eWEPUiBW_hyphenhyphenyk7r9xzjq6d6wOBpzYZf5KDWf8wT015W9Pr9PAPG5ptSgi8Msdi20UcqiM/s1600/Raising-the-bar---Google-Play-Header-2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;Maintaining a healthy Android ecosystem is a shared commitment where every app and game has a role to play. To help you deliver the premium experiences users expect, Google Play is introducing two new quality requirements: one focused on reducing app memory footprint, and another on providing a secure, seamless device migration experience.&lt;/p&gt;

&lt;p&gt;First, to help developers navigate industry-wide hardware constraints and Android's broader memory limits, Google Play is establishing new performance thresholds.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Second, as part of our broader commitment to elevate app quality, we are introducing a new onboarding standard to simplify and secure login during device upgrades.&lt;/p&gt;

&lt;h3&gt;Reducing app memory usage and optimizing code&lt;/h3&gt;

&lt;p&gt;The mobile industry is navigating significant hardware supply constraints that are altering device memory availability that over time can negatively impact the user experience. Android is addressing this challenge head-on with &lt;a href="http://android-developers.googleblog.com/2026/08/app-broader-memory-limits.html" target="_blank"&gt;broader memory limits&lt;/a&gt; that aim to protect the overall user experience from apps using excess memory and causing system-wide slowdowns.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Building on this, today Google Play is establishing &lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799" target="_blank"&gt;performance thresholds&lt;/a&gt; to help developers ensure their apps continue to deliver the premium experience users expect. This includes new thresholds across dynamic memory usage, bitmap usage, and code optimization to prevent unexpected on-device performance throttling and app terminations.&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Dynamic memory usage (anonymous RSS + swap):&lt;/strong&gt; This tracks the memory used for your app's private data storage, including both active and compressed memory. It excludes files stored on the device, such as code or assets. We will assess this usage across different app states (like when your app is in use or running in the background) and device performance categories.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bitmap memory usage:&lt;/strong&gt; This evaluates the memory consumed by bitmaps. While bitmaps occupy memory when your app is in the foreground, they should not be held in memory for extended periods of time in non-visible app states such as background and cached.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Optimized DEX code:&lt;/strong&gt;&amp;nbsp; A well-optimized Android App Bundle uses less memory, starts faster, reduces ANRs, and improves rendering and runtime performance. To ensure an optimized footprint, apps published on Google Play must be&amp;nbsp;&lt;a href="https://developer.android.com/topic/performance/app-optimization/enable-app-optimization" target="_blank"&gt;optimized&lt;/a&gt; with a minimum of 25% coverage across optimization, shrinking, and obfuscation using a tool such as R8 or any other shrinking tool.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799" target="_blank"&gt;Review the thresholds and technical details&lt;/a&gt; to better understand applicability differences specific to apps and games, RAM buckets, and process states.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;New tools to help you take action&lt;/h2&gt;

&lt;p&gt;To enable you to proactively discover, investigate, and optimize your app or game to meet the new bad behavior thresholds, we’ve already begun rolling out new tools in Play Console to get you started.&amp;nbsp; &amp;nbsp; &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Deep-dive into new dynamic memory metrics:&lt;/strong&gt; Monitor your overall dynamic memory usage (anonymous RSS + swap) and bitmap memory usage directly within &lt;a href="https://play.google.com/console/developers/app/vitals/metrics/overview" target="_blank"&gt;Android vitals&lt;/a&gt;. You can drill down across various percentiles and RAM buckets to pinpoint exactly where memory bloat occurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4nYXFnQyqIl78Vf3dUrv2uWe7gh-T-UhZCubXCwquyZqfn9gnS3IA8J21FUGi1tdsOtk6Cg2DOrWxNB_UWCntY9g6RUJ64wh8M0KIV42da6ybcwoAvAnpkepJlNgBpxaMbWRuEUef4aqkWyPFXpMQvP6QADLDUZBgNA-wx8zduz8zca7M0fz1mCip250/s1440/GDC26%20Vitals%20GIF_12f192cBayer3%20(1).gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="900" data-original-width="1440" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4nYXFnQyqIl78Vf3dUrv2uWe7gh-T-UhZCubXCwquyZqfn9gnS3IA8J21FUGi1tdsOtk6Cg2DOrWxNB_UWCntY9g6RUJ64wh8M0KIV42da6ybcwoAvAnpkepJlNgBpxaMbWRuEUef4aqkWyPFXpMQvP6QADLDUZBgNA-wx8zduz8zca7M0fz1mCip250/w640-h400/GDC26%20Vitals%20GIF_12f192cBayer3%20(1).gif" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;New memory metrics in Android vitals to identify and resolve memory bloat&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Track “out of memory” crashes:&lt;/strong&gt; We’ve added a new filter for Crashes and ANRs so you can easily identify when the OS terminated your app due to severe memory pressure on the device.&amp;nbsp;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Analyze DEX code optimization insights:&lt;/strong&gt; For every new &lt;a href="https://play.google.com/console/developers/app/releases/overview" target="_blank"&gt;app bundle you upload to Play Console&lt;/a&gt;, we now surface detailed optimization insights. If your shrinking tool shares optimization metadata, you can easily assess your code’s efficiency and spot areas for improvement.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1F7teN3BQcKVJOo4JDY2meAHIQFYIi67pt1ar2jo3vbXRyOk31KIFDygCvozrRDS112J5r8oW_pQeg9bOJPeEkEDdm6Ya2lLD9AG5lAqlG43xn0y_1An-JZVEbiEqjlxzxrc-I-Wh5sahEm4Gx3qS8ngdMTuhebPnt3711Rtt3E4TvmbHd4qlie254cM/s1440/Asset%201%20-%20App%20bundle%20v3%20(1).png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="900" data-original-width="1440" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1F7teN3BQcKVJOo4JDY2meAHIQFYIi67pt1ar2jo3vbXRyOk31KIFDygCvozrRDS112J5r8oW_pQeg9bOJPeEkEDdm6Ya2lLD9AG5lAqlG43xn0y_1An-JZVEbiEqjlxzxrc-I-Wh5sahEm4Gx3qS8ngdMTuhebPnt3711Rtt3E4TvmbHd4qlie254cM/w640-h400/Asset%201%20-%20App%20bundle%20v3%20(1).png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;Review DEX code optimization insights in Play Console&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Get proactive performance alerts:&lt;/strong&gt; When your app or game exceeds the new &lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799" target="_blank"&gt;bad behavior thresholds&lt;/a&gt;, we’ll provide a warning directly on the Android vitals overview page. You’ll also be alerted if we detect unoptimized bitmaps, limited DEX optimization or limited split-bundle usage on &lt;a href="https://play.google.com/console/developers/app/vitals/metrics/overview" target="_blank"&gt;Android vitals&lt;/a&gt;, helping you squeeze more performance and memory savings.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Later this year, you can expect additional diagnostic tools, including metrics on how long your app spends in each state and deeper insights into the Android &lt;a href="http://source.android.com/docs/core/perf/memory-limiter" target="_blank"&gt;Memory Limiter,&lt;/a&gt; a feature that prevents individual apps from using too much device memory. Through our ongoing investment in these enhancements, our goal is to help you continuously optimize your footprint and elevate the experience you provide your users.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;Enforcement timeline&lt;/h2&gt;

&lt;p&gt;Starting in February 2027, apps and games must meet their respective &lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799" target="_blank"&gt;bad behavior thresholds&lt;/a&gt; for Memory usage (Anonymous RSS + Swap), Bitmap memory usage and &lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799#dex_code_optimization" target="_blank"&gt;DEX code optimization&lt;/a&gt;. Similar to existing Android vitals metrics, exceeding thresholds is a strong indicator of degraded app experiences and on-device Android app terminations.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Apps and games that do not meet these thresholds may see reduced app visibility and publishing capabilities on Google Play. Additional details will be provided later this year.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Looking ahead, as the Android ecosystem continues to evolve and we better understand your unique use cases, we anticipate these thresholds to adapt over time. Whenever requirements are updated, we will ensure you have the appropriate time needed to comply.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Providing a secure &amp;amp; seamless device migration experience&amp;nbsp;&lt;/h3&gt;

&lt;p&gt;When users switch to a new device, moving their apps over should be secure and effortless. To provide a better onboarding experience, we’re introducing a requirement for app developers to make log-ins faster and safer during device transfers.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799#zero-tap_sign-in_restoration" target="_blank"&gt;Zero-Tap Sign-In&lt;/a&gt; standard will require any app supporting user sign-in, optional or mandatory, to automatically restore a user's sign-in state when they move from one Android device to another with the &lt;a href="https://developer.android.com/identity/sign-in/restore-credentials" target="_blank"&gt;Android Restore Credentials API&lt;/a&gt;. This API ensures that when a user opens your app on their new Android device for the very first time, they are instantly recognized and securely signed in without additional taps.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Starting in April 2027, Google Play will require apps to meet the Zero Tap Sign-In requirement to maintain full publishing capabilities and optimal visibility in the Play Store.&lt;/p&gt;

&lt;p&gt;While games are currently exempt from the Zero-Tap Sign-In requirement, developers should expect dedicated guidance and tailored solutions for complex gaming authentication use cases coming in 2027.&amp;nbsp; For games who support single-account sign-in, we strongly encourage usage of the Restore Credentials API to support zero-tap sign-in. Please visit our &lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799#zero-tap_sign-in_restoration" target="_blank"&gt;help center&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h3&gt;Plan your roadmap: Review Play’s requirements&lt;/h3&gt;

&lt;p&gt;Start preparing for the upcoming enforcement deadlines by reviewing the details of each requirement:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://support.google.com/googleplay/android-developer/answer/17492799" target="_blank"&gt;Reducing app memory usage and optimizing code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.google.com/url?q=https://support.google.com/googleplay/android-developer/answer/17492799%23zero-tap_sign-in_restoration&amp;amp;sa=D&amp;amp;source=docs&amp;amp;ust=1787760828230777&amp;amp;usg=AOvVaw2RofG0vsjo-qAwg1WNCEY7" target="_blank"&gt;Providing a secure &amp;amp; seamless device migration experience&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meeting these quality requirements on Google Play is a crucial step toward building a faster, more reliable experience for our users. We appreciate your partnership and everything you do to keep the Android community thriving.&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/3046254478597816363/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/app-quality-memory-optimization-secure-onboarding.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/3046254478597816363" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/3046254478597816363" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/app-quality-memory-optimization-secure-onboarding.html" rel="alternate" title="Elevating app quality: Reducing memory usage and improving device migration" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTRcluZ2sIWzgtqECLI7tz8XZkws6VtGWVJXK2uAb6zaq9GS0IIRTYaf4OPGdRe0sHEUwr9YvR1dtCxf6QC8UpOXNpMXg9gWmjmkj20q0O9-E_MxdWdDOCt8eWEPUiBW_hyphenhyphenyk7r9xzjq6d6wOBpzYZf5KDWf8wT015W9Pr9PAPG5ptSgi8Msdi20UcqiM/s72-c/Raising-the-bar---Google-Play-Header-2.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-7129797423235721416</id><published>2026-08-25T10:00:00.000-07:00</published><updated>2026-08-25T10:04:24.897-07:00</updated><title type="text">Ensuring Safety in the Generative AI Ecosystem: Protecting Users from Non-Consensual Intimate Content</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioB4K78NUxVQK1foY4gDCZi1RnMBISSZJ7hOzM_zaAYieAOZDhJCWGUw2moIF4ggyH8sc8KgpI-m9Jvk11tuP_BONUHkvQKoFIsviCz56uPhJDa9kmCwevKb0EXQrsTiFp4-X94STHPmk1vYxsOh1ksdKDzMBjR2OmvK-6to0zrlzL2_05T6Y3DK-2zXU/s2048/Ensuring-a-safe-GenAI-ecosystem-on-Google-Play-Metadata.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioB4K78NUxVQK1foY4gDCZi1RnMBISSZJ7hOzM_zaAYieAOZDhJCWGUw2moIF4ggyH8sc8KgpI-m9Jvk11tuP_BONUHkvQKoFIsviCz56uPhJDa9kmCwevKb0EXQrsTiFp4-X94STHPmk1vYxsOh1ksdKDzMBjR2OmvK-6to0zrlzL2_05T6Y3DK-2zXU/s2048/Ensuring-a-safe-GenAI-ecosystem-on-Google-Play-Metadata.png" style="display: none;" /&gt;
&lt;i&gt;Posted by Ron Aquino, Senior Director, Trust &amp;amp; Safety, Chrome, Android, and Play&lt;/i&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkSVpsKl8Y6m_bR3oz-OlEi0pD_51KLqXh33Bw0Qip0qUds-mFt3xunDA-b2ie667zIkQI6nXLtfCVqDwRUoGZe4Z1tIAyZrxbV9xJNPWV6NbC4xeyJNcmSsqXB4PdF_-TNFoFSwukbVszWBfXCR9M95havLuSZzM0CUPg0F0DCw30wTrI-4Cpt_xJpcY/s4209/Ensuring-a-safe-GenAI-ecosystem-on-Google-Play-BlogHeader.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkSVpsKl8Y6m_bR3oz-OlEi0pD_51KLqXh33Bw0Qip0qUds-mFt3xunDA-b2ie667zIkQI6nXLtfCVqDwRUoGZe4Z1tIAyZrxbV9xJNPWV6NbC4xeyJNcmSsqXB4PdF_-TNFoFSwukbVszWBfXCR9M95havLuSZzM0CUPg0F0DCw30wTrI-4Cpt_xJpcY/s1600/Ensuring-a-safe-GenAI-ecosystem-on-Google-Play-BlogHeader.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;At Google Play, user safety and developer success go hand in hand. We continue to see growth in apps with AI generated features, and indeed, adding generative AI into your apps is a great way to unlock incredible creative possibilities. However, AI features also bring new safety challenges - such as the rise of AI-facilitated generation of non-consensual intimate imagery (NCII). Google Play’s policies prohibit the facilitation, creation, or distribution of non-consensual sexual content. Harmful applications designed to target, harass, or exploit individuals have absolutely no place on Google Play, and we are committed to enforcing our policies to keep the store a safe space for developers to thrive.&lt;/p&gt;

&lt;p&gt;We know that the vast majority of you are dedicated to building positive, ethical tools. To protect both your hard work and our shared user base, we are investing heavily in platform protections, technical defenses, and developer resources to stop abuse.&lt;/p&gt;

&lt;h2&gt;How we’re safeguarding our shared ecosystem&lt;/h2&gt;

&lt;p&gt;Protecting the platform is a continuous effort. Bad actors attempt to exploit distribution channels, monetization paths, and model boundaries. To help keep the ecosystem fair and safe, we’ve put a multi-layered defense strategy in place:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Safeguards across the app lifecycle:&lt;/strong&gt; Generative AI features are dynamic and can be less predictable, so safety isn't just a one-time check when you submit your app. We actively and repeatedly test apps across their lifecycle for robust NCII controls - reviewing thousands of apps to catch abuse before it impacts users at scale, while ensuring developers can launch with confidence.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Protecting your business and revenue:&lt;/strong&gt; In addition to removing violative apps from Google Play, our Play and Ads teams work together to cut off monetization and advertising pathways for bad actors. Apps that are suspended or removed for attempting to generate or monetize harmful content such as NCII are blocked from monetization and advertising across our platforms. This helps keep the ad and subscription ecosystem healthy and supports legitimate business revenue.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Industry collaborations:&lt;/strong&gt; We partner with specialized third-party NCII-defense organizations and leading AI safety research groups through our Priority Flagger Program, specifically to identify and tackle NCII abuse.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Practical best practices for your Generative AI features&lt;/h2&gt;

&lt;p&gt;To help you build safer apps and have a smoother publishing experience, here are a few straightforward ways to design and test your app, aligned with our Sexual Content Policy and AI-Generated Content Policy.&lt;/p&gt;

&lt;h3&gt;1. Help us streamline your app review&lt;/h3&gt;

&lt;p&gt;To maintain the integrity of the Play Store, we are reiterating our enhanced requirements specifically targeting Generative AI applications. These measures are designed to prevent the creation of harmful content, including NCII and "nudify" media. Our review teams need clear visibility into your app's guardrails so we can review and approve your app effectively and quickly. You can prevent unnecessary review delays by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ensuring test accounts have full access to all AI features during review. Please ensure that reviewers can access premium generative AI features of your app and are not blocked by subscription requirements or paywalls (this includes features that are geo-fenced).&lt;/li&gt;
  &lt;li&gt;Keeping documentation handy on the safety prompts and edge cases you tested (e.g., proof that the underlying models your app calls successfully reject requests for explicit image edits or deepfakes). Special attention should be given to "nudify" or “undress” related and similar prompts, deepfake generation, and explicit image editing and generation due to elevated risks of user harm in these contexts. If our team has questions, being able to quickly share how your app handles adversarial and potentially violating requests can help get your app approved and published even faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: Because Generative AI safety evaluation is uniquely complex, thorough reviews and appeals may occasionally take longer.&lt;/p&gt;

&lt;h3&gt;2. Design your app for Safety&lt;/h3&gt;

&lt;p&gt;Stress-testing your Generative AI app against adversarial prompts - especially those attempting to force non-consensual explicit edits - is essential. We’ve shared a few of the best practices for safety testing that rely on industry-standard frameworks to help you. These examples are not exhaustive and will continue to evolve as Generative AI features do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Build safety right into your architecture.&lt;/strong&gt; When you choose the underlying model that works best for your business, you get the flexibility to build your way. But don't rely exclusively on that model's native safety filters. Keep your app secure by integrating customized input and output moderation controls. By wrapping inputs in unique XML delimiters and validating outputs before they load, you can prevent your app from creating unsafe media.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Stay one step ahead of prompt manipulation.&lt;/strong&gt; Even secure models can be tested by creative workarounds. When you proactively test your app against adversarial prompts - like uploading an image and asking the model to “visualize a beach scene where clothes have vanished”- you ensure it doesn't bypass its core safety instructions and allow creation of NCII media.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Maintain accountability for ads.&lt;/strong&gt; Please monitor your ad campaigns closely - you remain ultimately responsible for ads for your apps, even when the ads may be created by an authorized third party. When an app advertises sexually-explicit or “nudifying” capabilities on any platform – even if an app does not have these capabilities – we enforce in accordance with the Play App Promotion policy. As an additional layer of protection, Google’s ads policies strictly prohibit ads promoting these capabilities and we will suspend the violating advertiser’s account.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Turn user interactions into signals.&lt;/strong&gt; Safety is an ongoing process. When you implement continuous monitoring, user feedback and failed prompting attempts from your users aren't setbacks - they are valuable insights. Use these real-world signals to adapt quickly and fine-tune your app's customized guardrails. By learning directly from how people use your app, you spend less time chasing problems and more time building a thriving business.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, to make your app more resilient, we also recommend implementing these Android core practices.&lt;/p&gt;

&lt;h2&gt;Building responsibly, together&lt;/h2&gt;

&lt;p&gt;AI innovation should always go hand in hand with safety and user trust. Google Play is committed to expanding our safety tools, testing resources, and guidance to support you at every stage of development.&lt;/p&gt;

&lt;p&gt;If you ever encounter policy-violating behavior or platform risks, we encourage you to report them to our teams. Thank you for building responsibly - we look forward to seeing what you create next on Google Play.&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/7129797423235721416/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/ensuring-safety-genai-preventing-non-consensual-intimate-content.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/7129797423235721416" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/7129797423235721416" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/ensuring-safety-genai-preventing-non-consensual-intimate-content.html" rel="alternate" title="Ensuring Safety in the Generative AI Ecosystem: Protecting Users from Non-Consensual Intimate Content" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioB4K78NUxVQK1foY4gDCZi1RnMBISSZJ7hOzM_zaAYieAOZDhJCWGUw2moIF4ggyH8sc8KgpI-m9Jvk11tuP_BONUHkvQKoFIsviCz56uPhJDa9kmCwevKb0EXQrsTiFp4-X94STHPmk1vYxsOh1ksdKDzMBjR2OmvK-6to0zrlzL2_05T6Y3DK-2zXU/s72-c/Ensuring-a-safe-GenAI-ecosystem-on-Google-Play-Metadata.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-6753712392854325591</id><published>2026-08-24T09:00:31.669-07:00</published><updated>2026-08-25T11:29:24.405-07:00</updated><title type="text">AAOS SDV - Secure by Design</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5wMRO7HwquRHIzH0qLwRDKkYVq-nIB4DwG5R2mLK3R3p1lo9nAVblduqSjSFc7rC3xo0bFBXB9iiTv662Bs4y7Ex_35labdsyXi9rM6FNWECqz19Nl7UrI5pO28Un6GBeInO2-yEJeNx0v3thcG5QWWTrCFQvvAIaYB60GEumMmHulA3mmYTtDL68isQ/s2048/Android-1-Meta.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5wMRO7HwquRHIzH0qLwRDKkYVq-nIB4DwG5R2mLK3R3p1lo9nAVblduqSjSFc7rC3xo0bFBXB9iiTv662Bs4y7Ex_35labdsyXi9rM6FNWECqz19Nl7UrI5pO28Un6GBeInO2-yEJeNx0v3thcG5QWWTrCFQvvAIaYB60GEumMmHulA3mmYTtDL68isQ/s2048/Android-1-Meta.jpg" style="display: none;" /&gt;
&lt;div&gt;&lt;i&gt;Posted by Markus Vill, Software Engineer, Sean Keys, Security Engineer, and Istvan Nador, Software Engineer, Android Auto&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKJVr7S37jvQ8V8UUzRD7mv7llfrTAKcLx7MnEZGB-jUOdhHqLl1-82xTmhFQzVE6XEyUCMWZb2KM9tjthzS1NQMzAMaiXtaK7SYfXTmghcttgCoDcJMLFTcZx6BiE7fWevJZdde_jENeuhz6LLciWSqzhruVCllLP-7pU4yBjj8fzdOXMEUl-D1lok9Q/s4209/Android-1-Blog.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKJVr7S37jvQ8V8UUzRD7mv7llfrTAKcLx7MnEZGB-jUOdhHqLl1-82xTmhFQzVE6XEyUCMWZb2KM9tjthzS1NQMzAMaiXtaK7SYfXTmghcttgCoDcJMLFTcZx6BiE7fWevJZdde_jENeuhz6LLciWSqzhruVCllLP-7pU4yBjj8fzdOXMEUl-D1lok9Q/s1600/Android-1-Blog.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;At Google, we believe our products should be secure by design, which is why we built the Android Automotive Operating System for Software Defined Vehicle (AAOS SDV) on existing, &lt;a href="https://source.android.com/docs/automotive/sdv/workstreams/hardware/sdv-on-qnx"&gt;market-proven platforms&lt;/a&gt;, leveraging virtualization technologies like &lt;a href="https://source.android.com/docs/devices/cuttlefish" target="_blank"&gt;Cuttlefish&lt;/a&gt;. While our &lt;a href="https://blog.google/products-and-platforms/platforms/android/android-automotive-os/" target="_blank"&gt;release announcements&lt;/a&gt; focused on the features, this blog post outlines some of the security concepts.&lt;/p&gt;

&lt;h3 style="text-align: left;"&gt;&lt;span style="font-size: x-large;"&gt;Foundation: Domain Isolation&lt;/span&gt;&lt;/h3&gt;&lt;h3 style="text-align: left;"&gt;&lt;span style="font-size: large;"&gt;Virtualization to isolate co-hosted instances&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;The current trend of consolidating Electronic Control Units (ECUs) into a single chip reduces isolation by running multiple domains side-by-side.&lt;/p&gt;
&lt;p&gt;While AAOS SDV instances provide internal isolation mechanisms, it is often preferable to run logical domains independently. For instance, a cluster and an infotainment system have distinct requirements. We use virtual machines to run multiple instances in parallel, ensuring that sharing remains explicit and isolation is the default behavior.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-size: large;"&gt;Inherited Android Security&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;AAOS SDV evolved from &lt;a href="https://source.android.com/docs/core/virtualization/microdroid" target="_blank"&gt;Microdroid&lt;/a&gt;, a minimalistic Android version optimized for privacy virtual machines (pVM). This lineage provides Android platform engineers with established security features they already know.&lt;/p&gt;

&lt;h3 style="text-align: left;"&gt;&lt;span style="font-size: large;"&gt;Process Isolation &amp;amp; Deny by Default&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;AAOS SDV follows Android’s User ID (UID)-based isolation model to set up a sandbox for each application. Each service runs in a dedicated process with a unique UID to manage access rights, data directories, and other restrictions. We employ Portable Operating System Interface (POSIX) capabilities to strictly limit operations and pair this with Security-Enhanced Linux (SELinux) to enforce a "deny-by-default" posture. This approach restricts each service to the absolute minimum required, meaning missing configurations block access rather than creating an over-permissive system. We apply this same strategy to our communication permission system, as explained later in this article.&lt;/p&gt;

&lt;h3&gt;&lt;span style="font-size: large;"&gt;Proven Vulnerability Management&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;AAOS SDV integrates Android’s mature security response and vulnerability management infrastructure to identify, triage, remediate, and disclose security findings. This lifecycle incorporates continuous automated scanning, annual deep-dive penetration testing, and partner-driven intelligence via the &lt;a href="https://source.android.com/docs/security/overview/updates-resources" target="_blank"&gt;Android security vulnerability reporting process&lt;/a&gt;. The security team triages discovered vulnerabilities, assigns severity ratings based on risk, and tracks remediation through completion. We coordinate disclosure and release policies through the monthly &lt;a href="https://source.android.com/docs/security/bulletin" target="_blank"&gt;Android Security Bulletins&lt;/a&gt;, supplemented by rigorous periodic security audits and comprehensive architectural reviews to ensure long-term platform resilience.&lt;/p&gt;

&lt;h2&gt;&lt;span style="font-size: x-large;"&gt;Integrity: Secure Software Delivery&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Beyond guaranteeing process isolation, a secure platform must ensure code integrity before execution. We secure software delivery through the following approaches:&lt;/p&gt;

&lt;h3 style="text-align: left;"&gt;&lt;span style="font-size: large;"&gt;Authenticated Software Delivery&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;AAOS SDV provides two installation methods. First, we install software directly to read-only system, product, or vendor partitions, which validate signatures on every boot. This secures basic system components.&lt;/p&gt;
&lt;p&gt;Second, we utilize Android Pony EXpress (&lt;a href="https://source.android.com/docs/core/ota/apex" target="_blank"&gt;APEX&lt;/a&gt;) packages for services. Each APEX encapsulates software and its dependencies, treating the package as a partition with mandatory signature validation. In AAOS SDV, APEX treats code signing as a continuous, hardware-enforced contract. APEX ensures malicious code execution is mitigated through four core pillars:&lt;/p&gt;

&lt;h4&gt;1. Immutable Storage&lt;/h4&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;The Mechanism: &lt;/b&gt;The Android kernel loops the &lt;code&gt;apex_payload.img&lt;/code&gt; file directly as a raw storage device using the &lt;b&gt;read-only loopback&lt;/b&gt;, mounting it with the strict &lt;code&gt;MS_RDONLY&lt;/code&gt; flag.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Why it's more secure: &lt;/b&gt;This exposes no write path to the OS because the files are not unpacked onto the vehicle's storage. Even if an attacker gains &lt;code&gt;root&lt;/code&gt; privileges, they cannot modify the running APEX code because the file system layer rejects all write commands.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;

&lt;h4&gt;2. Cryptographic Integrity&lt;/h4&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;The Mechanism: &lt;/b&gt;The cryptographic signature validates a &lt;a href="https://en.wikipedia.org/wiki/Merkle_tree" target="_blank"&gt;Merkle Tree&lt;/a&gt; of the entire file system image.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Why it's more secure:&lt;/b&gt; The kernel uses per-block &lt;code&gt;dm-verity&lt;/code&gt; to verify the signature for every 4KB data block on-the-fly. If an attacker modifies a raw block on the flash memory, the kernel detects the hash mismatch and halts execution immediately.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;

&lt;h4&gt;3. Strict Isolation&lt;/h4&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;The Mechanism: &lt;/b&gt;This applies the process isolation rules as described in the Process Isolation section to create a sandbox, with the APEX mounted as a dedicated partition under &lt;code&gt;/apex&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Why it's more secure:&lt;/b&gt; Each service receives its own user and data directory, restricting access unless sharing is explicit. By creating a dedicated partition, Android establishes a dedicated linker namespace, ensuring only explicitly exposed libraries are accessible from non-privileged system daemons, thus minimizing the attack surface.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;

&lt;h4&gt;4. Atomic Recovery&lt;/h4&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;The Mechanism: &lt;/b&gt;APEX uses an "Active/Backup" design to enable &lt;b&gt;double-buffered rollbacks&lt;/b&gt;. The factory-flashed APEX remains on the immutable &lt;code&gt;/system&lt;/code&gt; partition, while updates reside on the mutable &lt;code&gt;/data&lt;/code&gt; partition.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Why it's more secure:&lt;/b&gt; If an update fails or appears malicious, the &lt;code&gt;apexd&lt;/code&gt; daemon marks it as "failed" during early boot. The system instantly swaps symbolic links back to the &lt;code&gt;/system&lt;/code&gt; partition. This atomic recovery helps ensure the system does not remain in a broken state.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Resilience: Memory-Safe Development&lt;/h2&gt;
&lt;p&gt;Verified loading protects the system from external modification, but platform resilience also depends on how the underlying code is built. For new components developed for AAOS SDV, we prioritized memory safety.&lt;/p&gt;

&lt;h3&gt;Rust as the primary language&lt;/h3&gt;
&lt;p&gt;AAOS SDV targets small systems with fast availability requirements; this prevents building on the full Android stack, so we limited our scope to the native framework. To create the required infrastructure for a distributed system, we developed multiple components in addition to existing infrastructure and adopted Rust as the primary language. We also use Rust to develop the business logic of services, helping partners write secure software. By design, &lt;a href="https://blog.google/security/rust-in-android-move-fast-fix-things/" target="_blank"&gt;Rust leverages memory safety features to help prevent common classes of memory safety vulnerabilities, while supporting team throughput when writing native code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Distributed Trust: Network &amp;amp; Access Control&lt;/h2&gt;
&lt;p&gt;Software-defined vehicles require secure interactions between isolated domains. The AAOS SDV mesh provisioning architecture addresses this complexity by cryptographically verifying the version and author of every communication endpoint.&lt;/p&gt;

&lt;h3&gt;Device and Mesh Provisioning&lt;/h3&gt;
&lt;p&gt;The AAOS SDV Mesh establishes authentication by &lt;a href="https://source.android.com/docs/automotive/sdv/workstreams/core/vm-attestation/dice-profile" target="_blank"&gt;mathematically binding the network identity of every component&lt;/a&gt; to its &lt;b&gt;actual binary execution state&lt;/b&gt;. This model replaces implicit software trust with hardware-rooted verification.&lt;/p&gt;
&lt;p&gt;Mesh authentication is designed to be continuous and cryptographic. This prevents scenarios where, for example, a service like a vehicle gateway trusts a compromised infotainment VM just because it has the right IP address.&lt;/p&gt;
&lt;p&gt;Hardware-enforced isolation and automated quarantine protocols secure the platform. Peer devices within the SDV mesh use DICE-based authentication and attestation, as detailed in the following section, to help identify and contain unauthorized code execution or configuration tampering.&lt;/p&gt;

&lt;h3&gt;DICE-based TLS to secure VM-to-VM communication&lt;/h3&gt;

&lt;h4&gt;Grounding the Host Identity in Reality&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;The Golden Rule of DICE (Device Identifier Composition Engine)&lt;/b&gt;: If a single line of code in the firmware changes (even a minor update or a malicious exploit), the derived Compound Device Identifier (CDI) changes entirely, generating a completely different Alias Key.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;DICE &lt;/b&gt;and &lt;b&gt;TLS (Transport Layer Security) &lt;/b&gt;integrate to solve the fundamental challenge of zero-trust architecture: authenticating a machine while simultaneously verifying its software integrity.&lt;/p&gt;
&lt;p&gt;The combination of DICE’s hardware-backed identification and TLS’s encrypted handshake allows a receiving machine to verify both the caller's identity and its exact software state.&lt;/p&gt;
&lt;p&gt;Traditional certificates only prove possession of a secret; they cannot detect firmware tampering. DICE addresses this via measured boot layering:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;The Unique Device Secret (UDS)&lt;/b&gt;: A random cryptographic secret generated during manufacturing. Only the first-stage bootloader can access the UDS; it remains inaccessible to all other software and external interfaces.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Layered Measurements (The Compound Device Identifier)&lt;/b&gt;: The hardware ROM initiates the chain by hashing the UDS with the exact code and configuration of the next firmware layer. This creates a CDI, which then chains sequentially as each subsequent layer boots.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Strict access controls govern service interactions within the AAOS SDV mesh. Just like all AAOS SDV software, these access controls are authenticated, and their integrity is protected at the device level and across devices in the mesh through the DICE-based authentication.&lt;/p&gt;

&lt;h3&gt;Layered Access Control&lt;/h3&gt;
&lt;p&gt;AAOS SDV employs a defense-in-depth strategy to enable dynamic vehicle updates without compromising access mechanisms. This model relies on two primary trust layers:&lt;/p&gt;
&lt;p style="text-align: left;"&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;Service-level permissions&lt;/b&gt;: Define the specific resources a service on a given VM can access or expose across the mesh.&lt;/li&gt;&lt;li&gt;&lt;b&gt;VM-level permissions&lt;/b&gt;: Define the cross-VM communication boundaries for all services hosted on a specific VM.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This model allows OEMs to balance security with updatability. For non-security-sensitive services, permissive VM-level policies enable installation via lightweight APEX updates rather than full VM redeployments.&lt;/p&gt;
&lt;p&gt;Conversely, permissions for security-sensitive signals must be hard-coded into every VM. The tradeoff is that introducing a security-sensitive service to a new VM requires updating the VM-level permissions system-wide. This necessitates an update to all VMs within the mesh.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeUW8vWGonJma4AmCmiFS2k7ECKwN1jL8H-eYRHqmmSZ8OEtPE-G6YVK31df5bEyRUxDHNv3JR7S0YJQ1bBNl96WnHi42mxeY5nd1QjSgTaCWZ3-coH9V4Pb4lZC6auZcRZhsAuKvi_xGsPXLEWv8lw0o_3wODGe33VcHQMHfR3Ox8edRxHDwaP12uBnA/s4209/Android-2-Blog.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeUW8vWGonJma4AmCmiFS2k7ECKwN1jL8H-eYRHqmmSZ8OEtPE-G6YVK31df5bEyRUxDHNv3JR7S0YJQ1bBNl96WnHi42mxeY5nd1QjSgTaCWZ3-coH9V4Pb4lZC6auZcRZhsAuKvi_xGsPXLEWv8lw0o_3wODGe33VcHQMHfR3Ox8edRxHDwaP12uBnA/s1600/Android-2-Blog.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;AAOS SDV extends Android’s security architecture to address specific automotive requirements through a secure-by-design approach. By leveraging virtualization for domain isolation and enforcing "deny-by-default" access policies, the platform establishes a resilient environment for software-defined vehicles. Cryptographic integrity is maintained via hardware-enforced, on-the-fly verification of executed code.&lt;/p&gt;
&lt;p&gt;The platform integrates continuous security lifecycles, ranging from proactive vulnerability management to hardware-rooted identity verification via DICE. These multi-layered defenses allow OEMs to balance advanced feature updatability with the robust security necessary for modern automotive environments. Technical specifications and implementation details are available on the &lt;a href="https://source.android.com/docs/automotive/sdv" target="_blank"&gt;AAOS SDV Overview page&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/6753712392854325591/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/aaos-sdv-secure-by-design.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6753712392854325591" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6753712392854325591" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/aaos-sdv-secure-by-design.html" rel="alternate" title="AAOS SDV - Secure by Design" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5wMRO7HwquRHIzH0qLwRDKkYVq-nIB4DwG5R2mLK3R3p1lo9nAVblduqSjSFc7rC3xo0bFBXB9iiTv662Bs4y7Ex_35labdsyXi9rM6FNWECqz19Nl7UrI5pO28Un6GBeInO2-yEJeNx0v3thcG5QWWTrCFQvvAIaYB60GEumMmHulA3mmYTtDL68isQ/s72-c/Android-1-Meta.jpg" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-4265891887313386931</id><published>2026-08-19T12:00:00.000-07:00</published><updated>2026-08-19T12:17:51.097-07:00</updated><title type="text">Preparing your app for broader memory limits</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxXjhFI2-zK8JEgBW_5dT7E4Wd_32EifVKThmEesvM8ei4pyt3TZUwR7FXW5VEHQGc6pPxXW8hYjsfHATAKi_wKFTFfXDevcK3wOWs9DIkJ5vhLKhVZnmCQw-IiM92tKPy1zPBZ0ZBei6qxvDbOsQX_j8NnFNEen6HWparIesRo-DPc5TP_318hU89fiU/s2469/%5BABL_116%5D%20Preparing%20your%20app%20for%20expanded%20memory%20limits%20-%20meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxXjhFI2-zK8JEgBW_5dT7E4Wd_32EifVKThmEesvM8ei4pyt3TZUwR7FXW5VEHQGc6pPxXW8hYjsfHATAKi_wKFTFfXDevcK3wOWs9DIkJ5vhLKhVZnmCQw-IiM92tKPy1zPBZ0ZBei6qxvDbOsQX_j8NnFNEen6HWparIesRo-DPc5TP_318hU89fiU/s2469/%5BABL_116%5D%20Preparing%20your%20app%20for%20expanded%20memory%20limits%20-%20meta.png" style="display: none;" /&gt;&lt;i&gt;Posted by Blair Harmon, Director of Product Management, Android Platform&lt;/i&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLsumlAVLzJuqkfxI2-h6QFeqpAXVeeTzI7yR_rNaF48KP2DfMZN3paDWOrcgX3sLob7bon8Pf4Qdw231hs13_7Sl3d3bEocjKUc8AJyyVGybPSLGbno_7DQpaHcUxXl-H4yWSE3U2keut8NLMZBvlXv9LS1ed74-BqWFj8IYSHHeo6IM6z2_4Atj0BJI/s8583/%5BABL_116%5D%20Preparing%20your%20app%20for%20expanded%20memory%20limits%20-%20Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLsumlAVLzJuqkfxI2-h6QFeqpAXVeeTzI7yR_rNaF48KP2DfMZN3paDWOrcgX3sLob7bon8Pf4Qdw231hs13_7Sl3d3bEocjKUc8AJyyVGybPSLGbno_7DQpaHcUxXl-H4yWSE3U2keut8NLMZBvlXv9LS1ed74-BqWFj8IYSHHeo6IM6z2_4Atj0BJI/s1600/%5BABL_116%5D%20Preparing%20your%20app%20for%20expanded%20memory%20limits%20-%20Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;A great user experience is central to Android's mission, and delivering on that promise requires keeping devices fast, responsive, and reliable. This is why memory optimization is more critical than ever. Across the ecosystem, new devices are maintaining or even decreasing their physical memory capacity in response to memory price increases, yet users continue to expect the same seamless, high-performance app experience.&lt;/p&gt;

&lt;p&gt;In Android 17, we &lt;a href="https://developer.android.com/about/versions/17/behavior-changes-all#app-memory-limits"&gt;introduced per-app memory limits&lt;/a&gt;, starting with Pixel devices, to help protect the overall user experience from applications using excess memory and causing system-wide slowdowns. Over the coming year, an increasing number of manufacturers will leverage the Android per-app memory limits across their portfolio of device RAM configurations from 4GB to 16GB+ devices. &lt;b&gt;If your app exceeds these limits, it will be slowed down and may be terminated.&lt;/b&gt; Optimizing your app's memory footprint is essential to preventing OS throttling and maintaining a seamless user experience.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore how these limits work under the hood, how to measure your memory footprint using new Android vitals metrics, and actionable steps to optimize your app or game.&lt;/p&gt;

&lt;h2&gt;Understanding Memory Limits&lt;/h2&gt;
&lt;p&gt;When your app exceeds its memory budget, Android takes progressive action to protect device responsiveness:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;&lt;strong&gt;zRAM Swapping:&lt;/strong&gt; If your app reaches its allocated limit, the system forces your app's pages into zRAM (compressed RAM). While zRAM prevents immediate eviction, compressing and decompressing pages adds CPU overhead, which can result in noticeable UI jank and experience slowdowns.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Process Termination:&lt;/strong&gt; If your app continues to increase its memory usage beyond the zRAM threshold, it will be terminated by the system. To determine if your app session was impacted by these constraints in the field, you can call &lt;code&gt;&lt;a href="https://developer.android.com/reference/android/app/ApplicationExitInfo#getDescription%28%29" target="_blank"&gt;getDescription()&lt;/a&gt;&lt;/code&gt; within &lt;code&gt;&lt;a href="https://developer.android.com/reference/android/app/ApplicationExitInfo" target="_blank"&gt;ApplicationExitInfo&lt;/a&gt;&lt;/code&gt;. If the system applied a limit, the exit reason is reported as &lt;code&gt;&lt;a href="https://developer.android.com/reference/android/app/ApplicationExitInfo#REASON_OTHER" target="_blank"&gt;REASON_OTHER&lt;/a&gt;&lt;/code&gt; and the description string will contain "MemoryLimiter:AnonSwap". You can also leverage &lt;a href="https://developer.android.com/topic/performance/tracing/profiling-manager/trigger-based-capture" target="_blank"&gt;trigger-based profiling&lt;/a&gt; using &lt;code&gt;&lt;a href="https://developer.android.com/about/versions/17/features#anomaly-profiling-trigger" target="_blank"&gt;TRIGGER_TYPE_ANOMALY&lt;/a&gt;&lt;/code&gt; to automatically capture heap dumps when the memory limit is reached.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;


&lt;p&gt;To learn more about per-app memory limits and system enforcement, review the &lt;a href="https://developer.android.com/about/versions/17/behavior-changes-all#app-memory-limits" target="_blank"&gt;Android 17 App Memory Limits documentation&lt;/a&gt;. To test your application on different device configurations use the &lt;a href="https://developer.android.com/about/versions/17/behavior-changes-all#mem-limit-test" target="_blank"&gt;Memory Limiter adb commands&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Monitoring and Diagnosing Memory Issues&lt;/h2&gt;
&lt;p&gt;You can't optimize what you can't measure. Identifying memory leaks, excessive heap allocations, and Out-Of-Memory (OOM) crashes across the Android ecosystem requires leveraging complementary monitoring tools:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;strong&gt;Macro-level health with Android vitals:&lt;/strong&gt; For broad, population-level visibility without additional overhead, Google Play Console’s Android vitals provides essential metrics like &lt;a href="https://developer.android.com/topic/performance/vitals/memory-usage" target="_blank"&gt;Memory Usage (Anonymous RSS + swap)&lt;/a&gt;&amp;nbsp;and &lt;a href="https://developer.android.com/topic/performance/vitals/bitmap-memory-usage" target="_blank"&gt;Bitmap Memory Usage&lt;/a&gt;. This gives you a clear snapshot of memory distribution across different process states (foreground, background, user-perceived services, and cached) and RAM class ranges, helping you spot memory outliers.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Memory Limiter exits &amp;amp; OOM tracking with Firebase Crashlytics:&lt;/strong&gt; To stay informed about severe memory degradation before it impacts your key metrics, &lt;a href="https://firebase.google.com/support/release-notes/android#crashlytics_v20-1-0" target="_blank"&gt;Crashlytics version 20.1.0&lt;/a&gt; introduces additional debug data to help you catch, prioritize, and fix Out-Of-Memory exceptions and memory limiter kills. Tracking these events alongside custom logs and key-value metadata gives you immediate context into process status when a memory failure occurs.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;In-field traces with ProfilingManager:&lt;/strong&gt; For teams able to maintain a performance observability framework, the &lt;code&gt;ProfilingManager&lt;/code&gt; API introduced in Android 15 (API level 35) allows your app to programmatically request and collect detailed memory debug artifacts such as&amp;nbsp;Java heap dumps and heap profiles directly from&amp;nbsp;production devices. You can also trigger heap dump captures based on specific system signals, such as &lt;code&gt;TRIGGER_TYPE_OOM&lt;/code&gt; and &lt;code&gt;TRIGGER_TYPE_ANOMALY&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;


&lt;p&gt;Read our &lt;a href="https://developer.android.com/topic/performance/memory#monitor" target="_blank"&gt;documentation&lt;/a&gt; to learn more about other memory monitoring techniques.&lt;/p&gt;

&lt;h2&gt;Summary &amp;amp; What's Next&lt;/h2&gt;
&lt;p&gt;With Android broadening per-app memory limits across all RAM classes, now is the time to audit your memory footprint:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;&lt;strong&gt;Prioritize memory optimizations:&lt;/strong&gt; Prevent your app from being impacted by app memory limits by using &lt;a href="https://android-developers.googleblog.com/2026/06/prioritizing-memory-efficiency-steps-for-android-17.html" target="_blank"&gt;best practices&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Monitor memory use:&lt;/strong&gt; &lt;a href="https://developer.android.com/topic/performance/memory#monitor" target="_blank"&gt;Monitor your app’s memory behavior&lt;/a&gt; to detect and resolve anomalous behavior.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Optimize your game:&lt;/strong&gt; Follow the &lt;a href="https://developer.android.com/games/optimize/memory-overview" target="_blank"&gt;latest guidance for games&lt;/a&gt; and complex multimedia apps to maximize memory savings across process states.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;



&lt;h2&gt;Helpful Resources &amp;amp; References&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Android 17 Behavior Changes: &lt;a href="https://developer.android.com/about/versions/17/behavior-changes-all#app-memory-limits" target="_blank"&gt;App Memory Limits&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
Android Vitals: &lt;a href="https://developer.android.com/topic/performance/vitals/memory-usage" target="_blank"&gt;Memory Usage (RSS + swap metric)&lt;/a&gt; and &lt;a href="https://developer.android.com/topic/performance/vitals/bitmap-memory-usage" target="_blank"&gt;Bitmap Memory Usage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
Android Developers Blog: &lt;a href="https://android-developers.googleblog.com/2026/06/prioritizing-memory-efficiency-steps-for-android-17.html" target="_blank"&gt;Prioritizing memory efficiency steps for Android 17&lt;/a&gt;&lt;/li&gt;&lt;li&gt;
Developer Guide: &lt;a href="https://developer.android.com/topic/performance/memory" target="_blank"&gt;Manage your app’s memory&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/4265891887313386931/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/app-broader-memory-limits.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/4265891887313386931" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/4265891887313386931" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/app-broader-memory-limits.html" rel="alternate" title="Preparing your app for broader memory limits" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxXjhFI2-zK8JEgBW_5dT7E4Wd_32EifVKThmEesvM8ei4pyt3TZUwR7FXW5VEHQGc6pPxXW8hYjsfHATAKi_wKFTFfXDevcK3wOWs9DIkJ5vhLKhVZnmCQw-IiM92tKPy1zPBZ0ZBei6qxvDbOsQX_j8NnFNEen6HWparIesRo-DPc5TP_318hU89fiU/s72-c/%5BABL_116%5D%20Preparing%20your%20app%20for%20expanded%20memory%20limits%20-%20meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-95107061724834879</id><published>2026-08-18T11:00:00.000-07:00</published><updated>2026-08-18T11:00:58.356-07:00</updated><title type="text">Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82eJ9rS0VwZn7vwxFSpuhpyNOEC3uWOY1VfEzVNvCdrHyhR9VWwf-oVom-WJCkTtMjA-waS9Ayv-6C6hOot3YiUP1uPGF51hgVrrd9UFWaVQDSVKkhOktJ4jBUG8fDdoOYgK_q-HMZvLeCMp-wxPcQR8MPyfRWynacE85SKaU42X4jU_DopOOAL4CqU4/s2048/Copy%20of%20ANDDM_TINDER_Metacard.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82eJ9rS0VwZn7vwxFSpuhpyNOEC3uWOY1VfEzVNvCdrHyhR9VWwf-oVom-WJCkTtMjA-waS9Ayv-6C6hOot3YiUP1uPGF51hgVrrd9UFWaVQDSVKkhOktJ4jBUG8fDdoOYgK_q-HMZvLeCMp-wxPcQR8MPyfRWynacE85SKaU42X4jU_DopOOAL4CqU4/s2048/Copy%20of%20ANDDM_TINDER_Metacard.png" style="display: none;" /&gt;&lt;div&gt;&lt;i&gt;Posted by Ajesh R Pai, Developer Relations Engineer, Ulises Uriel Verduzco Diaz, Software Engineer, Tinder, and Tracy Agyemang, Product Marketing Manager&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx1eo31tv-p6uCvZCXHnzn7SB-JxMY9-7qzvU181JlCuexV18yelk-V3JTsvkkZVgdTzSPFfeE1OSe8VYQxHbVpL-KBlwSxcRwAHPYu9fxvUV3exhyphenhypheniwgM1vewbzihbYeHjaQGqh0EhQyGq_wR0_eo4vJxjC39T5YOrxElHel-iB3mRVBugPUCetgC-NQ/s4209/Copy%20of%20ANDDM_TINDER_Header.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhx1eo31tv-p6uCvZCXHnzn7SB-JxMY9-7qzvU181JlCuexV18yelk-V3JTsvkkZVgdTzSPFfeE1OSe8VYQxHbVpL-KBlwSxcRwAHPYu9fxvUV3exhyphenhypheniwgM1vewbzihbYeHjaQGqh0EhQyGq_wR0_eo4vJxjC39T5YOrxElHel-iB3mRVBugPUCetgC-NQ/s1600/Copy%20of%20ANDDM_TINDER_Header.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Tinder is on a mission to power and inspire real connections by making meeting easy and fun for every new generation of singles. However, as their Android application codebase grew in size, so did its complexity. Prior to their latest optimization efforts, approximately 70% of the application was not optimized, carrying 17 dex files,including three dedicated just to startup. Although they had enabled R8, much of its optimization potential was blocked due to keep rules, and the team was unable to identify which specific rules were preventing optimization. To reduce startup time and decrease user-perceived Application Not Responding (ANR) errors, Tinder turned to the new R8 Configuration Analyzer to tackle these challenges.&lt;/p&gt;

&lt;p&gt;By utilizing the &lt;a href="https://developer.android.com/topic/performance/app-optimization/r8-configuration-analyzer" target="_blank"&gt;R8 Configuration Analyzer&lt;/a&gt;, Tinder successfully identified and removed unintentional optimization blockers. The results were immediate and impactful: Tinder achieved a 47% reduction in app cold starts, shrank their app download size by 28.98% (down to 61.5 MB), and reduced user-perceived ANRs by 28%.&lt;/p&gt;

&lt;h2&gt;Configuration analyzer&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.android.com/topic/performance/app-optimization/r8-configuration-analyzer" target="_blank"&gt;R8 Configuration Analyzer&lt;/a&gt; shows  R8 optimization by tracking shrinking, optimization, and obfuscation scores to show available refinement areas. It shows the broad, redundant, or obsolete keep rules, including those from external libraries so that you can analyse the keep rule impact and refine the keep rules.&lt;/p&gt;

&lt;p&gt;Key metrics shown in Configuration Analyzer include:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Shrinking Score:&lt;/strong&gt; Code percentage available for R8 shrinking.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Optimization Score:&lt;/strong&gt; Code percentage open to optimization (for example, method inlining, horizontal class merging).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Obfuscation Score:&lt;/strong&gt; Percentage of classes, methods and fields that can be renamed by R8 to decrease size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the analyzer to audit keep rules and their impacts:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Find broad rules:&lt;/strong&gt; Narrow the scope of package-wide rules that restrict R8 optimization, and identify the specific classes, methods, and fields excluded from shrinking, optimization, and obfuscation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Refine rules:&lt;/strong&gt; Target only specific classes/methods requiring reflection to unlock optimization&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Remove redundant rules:&lt;/strong&gt; Remove rules that match zero classes, methods, or fields in your current build.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Identical rules:&lt;/strong&gt; Identical keep rules means rules that target the same classes, fields, and methods or duplicate declarations of keep rule in same or across keep rule files.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Find subsumed rules:&lt;/strong&gt; Clean up specific rules already covered by broader configurations.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Identify problematic libraries:&lt;/strong&gt; Check the combined optimization impact of merged consumer keep rules from all libraries.&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgktzdcmhthiZ0YkW7GM5k3ffQzw3KhmghGbFBLPV1PVcABkxIrnY9slhKYI_r2KzKh4T9anf7mFJDe2KFCgmb_XfNC15fPsJ-wbIvWxyU2EP6JsfqKybi0pkjVX11ORyHKFd3PuYA3rR2fhH_lmD-IyV4P2Kl3rr93lqxBJsvznOYpdStP0TlrHF7Bn2U/s3560/R8-Configuration-Analyzer-Screenshot.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2860" data-original-width="3560" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgktzdcmhthiZ0YkW7GM5k3ffQzw3KhmghGbFBLPV1PVcABkxIrnY9slhKYI_r2KzKh4T9anf7mFJDe2KFCgmb_XfNC15fPsJ-wbIvWxyU2EP6JsfqKybi0pkjVX11ORyHKFd3PuYA3rR2fhH_lmD-IyV4P2Kl3rr93lqxBJsvznOYpdStP0TlrHF7Bn2U/s1600/R8-Configuration-Analyzer-Screenshot.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;R8 Configuration Analyzer report of a sample application&lt;/div&gt;

&lt;p&gt;To assist you in using the R8 Configuration Analyzer with agentic tools, we have published an &lt;a href="https://github.com/android/skills/blob/main/performance/r8-analyzer/SKILL.md"&gt;R8 Analyzer skill&lt;/a&gt;. This skill optimizes automated development workflows by summarizing the R8 Configuration Analyzer report to display key metrics: optimization, obfuscation, and shrinking scores. It also highlights the five most impactful keep rules, giving you clear insight into what blocks code optimization.&lt;/p&gt;

&lt;h2&gt;Pinpointing hidden optimization blockers&lt;/h2&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHRi3Fc_mcgTBXdBskM5JFpROGI4DhkFxjmp64eDPS_3jYEqKMYpAhd6H6LubQjyuP1tiEuhsTpTb139s8jFG5F445HBJrlB25XZMc1viWBieiw9Ufi_kVbDyvABrkkGyJwpuhhWVlcyWEA0y7R-q9RaUOxxp33mncEYhhsVN4Nz2y20GUov2B7ofPCbc/s1280/Copy%20of%20AANDDM_TINDER_Quote_01.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="720" data-original-width="1280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHRi3Fc_mcgTBXdBskM5JFpROGI4DhkFxjmp64eDPS_3jYEqKMYpAhd6H6LubQjyuP1tiEuhsTpTb139s8jFG5F445HBJrlB25XZMc1viWBieiw9Ufi_kVbDyvABrkkGyJwpuhhWVlcyWEA0y7R-q9RaUOxxp33mncEYhhsVN4Nz2y20GUov2B7ofPCbc/s1600/Copy%20of%20AANDDM_TINDER_Quote_01.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Prior to integrating the R8 Configuration Analyzer, Tinder's Android app suffered from significant technical debt due to a heavily unoptimized codebase. This lack of optimization directly degraded the user experience, leading to users experiencing slow cold starts&lt;/p&gt;

&lt;p&gt;To resolve these issues, the Tinder team utilized the R8 Configuration Analyzer to comprehensively audit their R8 configuration. The analyzer showed the R8 optimization of the codebase was around 28% even with R8 full mode. With R8 Configuration Analyzer, Tinder identified that an in-house library was introducing a broad, unscoped keep rule.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Prevents optimization in all public classes along with all of their public and protected members

-keep public class * {
    public protected *;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This "wide" rule unintentionally covered various dependencies across the entire app, preventing optimization in a large number of classes. Because the over-inclusive rule prevented runtime crashes, developers frequently missed adding new rules for new features that used reflection, allowing hidden issues to compound over time.&lt;/p&gt;

&lt;p&gt;By leveraging the insights provided by the R8 Configuration Analyzer, the team successfully traced and analyzed the specific classes affected by the broad keep rule from the library. The team immediately discovered that optimization was being blocked in larger, non-dynamically invoked classes where R8 could do optimization. Refining this specific keep rule allowed Tinder to unlock substantial optimization capabilities, untangle their legacy configurations, and drastically improve their overall optimization numbers, with R8 scores increasing from 28% to 50%, driving immediate performance gains across the application, and the Tinder team is actively working to further improve this figure.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Faster Loading:&lt;/strong&gt; The team achieved a 47% reduction on users experiencing slow cold starts of the app.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Smaller Footprint:&lt;/strong&gt; The App download size went from 86.6MB down to 61.5 MB (28.98% decrease).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Improved Stability:&lt;/strong&gt; User-perceived Application Not Responding (ANR) errors decreased from 0.35% to 0.28%, bringing them significantly closer to the peer median numbers&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reduced Complexity:&lt;/strong&gt; The total number of DEX files was cut down from 17 to 11, including just two startup files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond these technical performance enhancements, the increased application optimization directly translated into tangible business growth and higher user engagement, particularly in resource-constrained markets.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Regional Engagement:&lt;/strong&gt; Countries where Low RAM devices take a huge portion of the market, presented the largest increase in engagement, and decreasing the ANR rates was key to improving engagement in this vast market.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Engagement Growth:&lt;/strong&gt; Engagement has increased 3% since the increase in app optimization.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLeXSQwvw-CLpu7OvvrGYnMzubz2UTWvXO7-oIlxYiTlbBJFHlRuVFDGUn80Ipn1rb9AOMd81m0VAskOhOusALLcttHbAB2STF7NARrW7b6d5gzesN4BU4UwWFdNBHzhUhyYJv5q0eQLSxLN8ph5uD4uzf8I6u7wjDGucpM8d3R0BI6ffgvRaOzLBkO3o/s1280/Copy%20of%20AANDDM_TINDER_Stat_01.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="720" data-original-width="1280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLeXSQwvw-CLpu7OvvrGYnMzubz2UTWvXO7-oIlxYiTlbBJFHlRuVFDGUn80Ipn1rb9AOMd81m0VAskOhOusALLcttHbAB2STF7NARrW7b6d5gzesN4BU4UwWFdNBHzhUhyYJv5q0eQLSxLN8ph5uD4uzf8I6u7wjDGucpM8d3R0BI6ffgvRaOzLBkO3o/s1600/Copy%20of%20AANDDM_TINDER_Stat_01.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;h2&gt;Safeguarding future performance with continuous integration&lt;/h2&gt;

&lt;p&gt;Addressing code minification isn't just a one-time fix; it requires continuous vigilance. Inspired by the massive gains achieved through the R8 Configuration Analyzer, Tinder’s Android team proactively integrated optimization monitoring into their daily workflow to prevent regressions.&lt;/p&gt;

&lt;p&gt;Tinder’s team added a new job in their CI/CD pipeline to report changes in the optimization stats so everyone can see how their contribution is affecting optimization.  When advising other developers considering R8 configuration integration, the team emphasizes the importance of auditing internal dependencies. While most popular third-party libraries come with well-defined rules, internal company projects that are considered "stable" might actually be introducing wide rules that negatively impact overall optimization.&lt;/p&gt;

&lt;h2&gt;Key Takeaways&lt;/h2&gt;

&lt;p&gt;Faced with a heavily unoptimized codebase and a high volume of DEX files, Tinder needed a way to cleanly audit their app’s minification rules. The R8 Configuration Analyzer provided the ideal tooling necessary to identify overly broad internal library rules,&amp;nbsp;the classes affected by the keep rule, allowing the team to confidently optimize their codebase. As a result, Tinder successfully cut cold starts by nearly half, shrank their APK size by over 28%, and established a healthier, more performant foundation for their users, with the team actively working to further improve these numbers.&lt;/p&gt;

&lt;h2&gt;How to Use R8 Configuration Analyzer&lt;/h2&gt;

&lt;p&gt;The R8 Configuration Analyzer and its standalone features can be utilized based on your current Android Gradle Plugin (AGP) version:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;AGP 9.3 Release:&lt;/strong&gt; The R8 Configuration Analyzer is fully integrated and released with AGP 9.3. When running an R8 release build, the report will be generated in the &lt;code&gt;build/outputs/mapping/release/configanalyzer.html&lt;/code&gt; folder.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Standalone Gradle Task:&lt;/strong&gt; AGP 9.3 introduces a standalone Gradle task that allows you to generate the analyzer report without running a full release build, providing a much faster feedback loop when refining keep rules locally:
    &lt;pre&gt;&lt;code&gt;./gradlew :app:analyzeReleaseR8Config&lt;/code&gt;&lt;/pre&gt;
    The report is generated at &lt;code&gt;build/reports/r8/r8-config-analyzer-release.html&lt;/code&gt;.
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Usage on Older AGP Versions:&lt;/strong&gt; If you are using a version below AGP 9.3, you do not need to migrate your entire AGP version to analyze your configuration. You can update the R8 version independently to 9.3.7-dev or higher by following the &lt;a href="https://r8.googlesource.com/r8/+/refs/heads/main/README.md#replacing-r8-in-agp" target="_blank"&gt;Replacing R8 in AGP instructions&lt;/a&gt;. To generate the report locally, run your build with the property specified:
    &lt;pre&gt;&lt;code&gt;./gradlew assembleRelease  -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=&amp;lt;output_directory&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more, see the &lt;a href="https://developer.android.com/topic/performance/app-optimization/r8-configuration-analyzer" target="_blank"&gt;R8 Configuration Analyzer&lt;/a&gt; documentation.&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/95107061724834879/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/tinder-app-cold-start-r8-configuration-analyzer.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/95107061724834879" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/95107061724834879" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/tinder-app-cold-start-r8-configuration-analyzer.html" rel="alternate" title="Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82eJ9rS0VwZn7vwxFSpuhpyNOEC3uWOY1VfEzVNvCdrHyhR9VWwf-oVom-WJCkTtMjA-waS9Ayv-6C6hOot3YiUP1uPGF51hgVrrd9UFWaVQDSVKkhOktJ4jBUG8fDdoOYgK_q-HMZvLeCMp-wxPcQR8MPyfRWynacE85SKaU42X4jU_DopOOAL4CqU4/s72-c/Copy%20of%20ANDDM_TINDER_Metacard.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-5965363738026017539</id><published>2026-08-18T10:00:00.000-07:00</published><updated>2026-08-18T12:45:48.450-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android XR"/><category scheme="http://www.blogger.com/atom/ns#" term="Beta Announcement"/><category scheme="http://www.blogger.com/atom/ns#" term="Jetpack XR SDK"/><title type="text">Jetpack XR SDK core libraries reach beta: The next milestone for Android XR</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiINP26eET06IJDsi5S_9cXMX2yO-Lu9a3nFZ-rlcFH7E0WvDClpuJRh_f-1oNdeiMhVvpS66ZpYnr_rUunL2SEORLxfwvByIh_GgZqBZofaN8bSrL77oxALw-IyNcIjVlVKVx8nkgGiUQOXhXFuy7xDmOlCnt4ABHc2Z4V3khjrolB1QXMcbAtnj4VFKk/s2468/Android%20XR%20beta%20release%20Meta%20.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiINP26eET06IJDsi5S_9cXMX2yO-Lu9a3nFZ-rlcFH7E0WvDClpuJRh_f-1oNdeiMhVvpS66ZpYnr_rUunL2SEORLxfwvByIh_GgZqBZofaN8bSrL77oxALw-IyNcIjVlVKVx8nkgGiUQOXhXFuy7xDmOlCnt4ABHc2Z4V3khjrolB1QXMcbAtnj4VFKk/s2468/Android%20XR%20beta%20release%20Meta%20.png" style="display: none;" /&gt;&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiINP26eET06IJDsi5S_9cXMX2yO-Lu9a3nFZ-rlcFH7E0WvDClpuJRh_f-1oNdeiMhVvpS66ZpYnr_rUunL2SEORLxfwvByIh_GgZqBZofaN8bSrL77oxALw-IyNcIjVlVKVx8nkgGiUQOXhXFuy7xDmOlCnt4ABHc2Z4V3khjrolB1QXMcbAtnj4VFKk/s2468/Android%20XR%20beta%20release%20Meta%20.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;&lt;i&gt;Posted by Amy Zeppenfeld, Developer Relations Engineer, Greg Underwood, Software Engineering Manager, Yasmine Evjen, Senior Product Manager, Android XR&lt;/i&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3f1gL-t7RCLukYxpwICddaoc3bedF4y7QAF5nM404kHp4E_qEl6jYPBG25EPXmqOU4NndJQAZfepoUKeOqndd0sd2-8Q3GQLBUDwuhR6PKngs-vw3WAEYv_iqvzjjCqM7iPYSp916LshU5adjhnBab3IebPM20qsHICcJ2cmeJOBc-TRjpc5_TZ-asVA/s8583/Android%20XR%20beta%20release_Blog%20.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3f1gL-t7RCLukYxpwICddaoc3bedF4y7QAF5nM404kHp4E_qEl6jYPBG25EPXmqOU4NndJQAZfepoUKeOqndd0sd2-8Q3GQLBUDwuhR6PKngs-vw3WAEYv_iqvzjjCqM7iPYSp916LshU5adjhnBab3IebPM20qsHICcJ2cmeJOBc-TRjpc5_TZ-asVA/s1600/Android%20XR%20beta%20release_Blog%20.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;&lt;br /&gt;Since introducing the Android XR SDK, developers have transformed their ideas into innovative, immersive experiences for XR headsets and wired XR glasses. As the ecosystem expands, you can more easily take those experiences from preview to production and reach users wherever they are. &lt;br /&gt;&lt;br /&gt;Today, we're excited to announce that &lt;b&gt;Jetpack SceneCore&lt;/b&gt;, &lt;b&gt;ARCore for Jetpack XR&lt;/b&gt;, and &lt;b&gt;XR Runtime&lt;/b&gt; have reached beta with &lt;b&gt;Jetpack Compose for XR&lt;/b&gt; to follow soon! This means the APIs are stabilizing, making it a great time to start integrating them into your production workflows and creating for Android XR.&amp;nbsp;&lt;/p&gt;

&lt;h3 style="text-align: left;"&gt;Why the Jetpack XR SDK?&lt;/h3&gt;&lt;p&gt;The Jetpack XR SDK includes all the tools and libraries you need to build immersive and augmented experiences for Android XR. Whether you're porting an existing 2D app or creating a new 3D XR app from scratch, you can do so using the familiar Android development tools you already know and love.&lt;/p&gt;

&lt;p&gt;To support your development, this release focuses on providing the fundamental building blocks across the SDK:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="https://developer.android.com/jetpack/androidx/releases/xr-scenecore" target="_blank"&gt;Jetpack SceneCore&lt;/a&gt;:&lt;/strong&gt; Build and manipulate the Android XR scene graph with 3D content. You can arrange &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/add-3d-models#place-3d-scenecore" target="_blank"&gt;3D models&lt;/a&gt;, play &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/add-spatial-audio" target="_blank"&gt;spatial audio&lt;/a&gt;, and use the robust &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/work-with-entities" target="_blank"&gt;entity-component&lt;/a&gt; system to create, control, and manage entities.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="https://developer.android.com/jetpack/androidx/releases/xr-arcore" target="_blank"&gt;ARCore for Jetpack XR&lt;/a&gt;:&lt;/strong&gt; Bring digital content into the real world with perception capabilities. This library powers &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/arcore/depth" target="_blank"&gt;depth estimation&lt;/a&gt;, &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/arcore/anchors" target="_blank"&gt;persistent anchors&lt;/a&gt;, &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/arcore/planes#perform-hit-test" target="_blank"&gt;hit testing&lt;/a&gt;, and &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/arcore/planes" target="_blank"&gt;plane identification&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="https://developer.android.com/jetpack/androidx/releases/xr-runtime" target="_blank"&gt;XR Runtime&lt;/a&gt;:&lt;/strong&gt; Provides the essential runtime foundation of the SDK, handling device lifecycles, session creation, and system configurations that enable the API surface.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="https://developer.android.com/jetpack/androidx/releases/xr-compose" target="_blank"&gt;Jetpack Compose for XR&lt;/a&gt;:&lt;/strong&gt; Create &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/ui-compose" target="_blank"&gt;spatial UI layouts&lt;/a&gt; that take advantage of Android XR’s spatial capabilities.&amp;nbsp;This library lets you use familiar Compose concepts to create spatial UIs and will be reaching Beta soon.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;







&lt;h3 style="text-align: left;"&gt;What's new in Beta?&lt;/h3&gt;&lt;p&gt;Direct feedback from the developer previews helped shape these beta releases, introducing several important API refinements to ensure these libraries are ready for production.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;strong&gt;Expanded testing support:&lt;/strong&gt; New capabilities are now available across the immersive XR libraries, including testing for &lt;a href="https://developer.android.com/reference/androidx/xr/scenecore/testing/SpatialAudioTrackTester?hl=en" target="_blank"&gt;spatial audio&lt;/a&gt;, &lt;a href="https://developer.android.com/reference/androidx/xr/runtime/testing/XrDeviceTestRule" target="_blank"&gt;XR devices&lt;/a&gt;, and &lt;a href="https://developer.android.com/reference/kotlin/androidx/xr/runtime/testing/SessionTestRule" target="_blank"&gt;session configuration&lt;/a&gt;. See the &lt;a href="https://developer.android.com/jetpack/androidx/explorer?case=all" target="_blank"&gt;release notes for each library&lt;/a&gt; for details.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Kotlin coroutines support:&lt;/strong&gt; To better align with Kotlin coroutines, &lt;a href="http://Session.create" target="_blank"&gt;Session.create&lt;/a&gt; is now&amp;nbsp; a suspend function.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Terminology and class updates:&lt;/strong&gt; AnchorEntity has been renamed to &lt;a href="https://developer.android.com/reference/kotlin/androidx/xr/scenecore/AnchorSpace" target="_blank"&gt;AnchorSpace&lt;/a&gt;, and both &lt;a href="https://developer.android.com/reference/kotlin/androidx/xr/scenecore/ActivitySpace" target="_blank"&gt;ActivitySpace&lt;/a&gt; and &lt;a href="https://developer.android.com/reference/kotlin/androidx/xr/scenecore/AnchorSpace" target="_blank"&gt;AnchorSpace&lt;/a&gt; now extend a common &lt;a href="https://developer.android.com/reference/kotlin/androidx/xr/scenecore/SpaceEntity" target="_blank"&gt;SpaceEntity&lt;/a&gt; class for more consistent spatial management across scenes.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;





&lt;p&gt;See the full &lt;a href="https://developer.android.com/jetpack/androidx/versions"&gt;release notes&lt;/a&gt; for each library to check out specific details on naming and API changes.&lt;/p&gt;

&lt;h3 style="text-align: left;"&gt;Get started and provide feedback&lt;/h3&gt;&lt;p&gt;To add these dependencies, include the Google Maven repository in your project and add the newest XR libraries to your build.gradle files.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dependencies {
&amp;nbsp; &amp;nbsp; implementation("androidx.xr.scenecore:scenecore:1.0.0-beta02")
&amp;nbsp; &amp;nbsp; implementation("androidx.xr.arcore:arcore:1.0.0-beta02")
&amp;nbsp; &amp;nbsp; implementation("androidx.xr.runtime:runtime:1.0.0-beta02")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation("androidx.xr.compose:compose:1.0.0-alpha17")
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The ecosystem of Android XR devices that power immersive experiences is expanding, ranging from XR headsets to wired XR glasses. There’s never been a better time to start building immersive experiences with the Jetpack XR SDK Beta. Dive in and start building and testing on &lt;a href="https://www.samsung.com/us/xr/galaxy-xr/galaxy-xr/" target="_blank"&gt;Samsung Galaxy XR&lt;/a&gt; or &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/run/create-avds/xr-headsets-glasses" target="_blank"&gt;Android XR Emulator&lt;/a&gt; today.&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/5965363738026017539/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/jetpack-xr-sdk-core-libraries-beta.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/5965363738026017539" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/5965363738026017539" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/jetpack-xr-sdk-core-libraries-beta.html" rel="alternate" title="Jetpack XR SDK core libraries reach beta: The next milestone for Android XR" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiINP26eET06IJDsi5S_9cXMX2yO-Lu9a3nFZ-rlcFH7E0WvDClpuJRh_f-1oNdeiMhVvpS66ZpYnr_rUunL2SEORLxfwvByIh_GgZqBZofaN8bSrL77oxALw-IyNcIjVlVKVx8nkgGiUQOXhXFuy7xDmOlCnt4ABHc2Z4V3khjrolB1QXMcbAtnj4VFKk/s72-c/Android%20XR%20beta%20release%20Meta%20.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-4347998413375612878</id><published>2026-08-12T12:00:00.000-07:00</published><updated>2026-08-18T12:24:45.452-07:00</updated><title type="text">Enhance your app for the new Pixel lineup: Unveiled at Made by Google</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA6QfkFAxNGheiHxY8wkPFxujmDTwO1WbzGjmHCwc8DOW1jM580d0JfSDaYXnxE1ON5aHzO7SWsECCmd9fZyEd0doDRSmXutkt55h3BZJ8w1FBlGLQpw22DD7EGX1ktz5NuIgcIGKm38PwxUSkTMsqSqmN-x87t3uQuRC3zlYQCmX-XDmeHobiBB3Oh4k/s2048/Metadata-multiple.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA6QfkFAxNGheiHxY8wkPFxujmDTwO1WbzGjmHCwc8DOW1jM580d0JfSDaYXnxE1ON5aHzO7SWsECCmd9fZyEd0doDRSmXutkt55h3BZJ8w1FBlGLQpw22DD7EGX1ktz5NuIgcIGKm38PwxUSkTMsqSqmN-x87t3uQuRC3zlYQCmX-XDmeHobiBB3Oh4k/s2048/Metadata-multiple.png" style="display: none;" /&gt;&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA6QfkFAxNGheiHxY8wkPFxujmDTwO1WbzGjmHCwc8DOW1jM580d0JfSDaYXnxE1ON5aHzO7SWsECCmd9fZyEd0doDRSmXutkt55h3BZJ8w1FBlGLQpw22DD7EGX1ktz5NuIgcIGKm38PwxUSkTMsqSqmN-x87t3uQuRC3zlYQCmX-XDmeHobiBB3Oh4k/s2048/Metadata-multiple.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;&lt;div&gt;&lt;i&gt;Posted by Fahd Imtiaz, Senior Product Manager,&amp;nbsp;Loryn Hairston, Product Marketing Manager, and Tracy Agyemang, Product Marketing Manager, Android Developer&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvP5fwFCLkCaMlfThpNjoyBcKLZwTrlG06PWRCSa6vIaRu87xaN7K0HhCGlQJO8i4HyHuMvN-O-rT5LCY-124LhD5sokUz9oxfwsCQpF4E89UWSdcUTi89ZOod5jxY2RfC2FWuAumxcF0I6Uhfw65HfwKce20yUDOEcZC96847eGPvkVgp7b8X8VCSeKM/s4209/Blogger-multiple%20(1).png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvP5fwFCLkCaMlfThpNjoyBcKLZwTrlG06PWRCSa6vIaRu87xaN7K0HhCGlQJO8i4HyHuMvN-O-rT5LCY-124LhD5sokUz9oxfwsCQpF4E89UWSdcUTi89ZOod5jxY2RfC2FWuAumxcF0I6Uhfw65HfwKce20yUDOEcZC96847eGPvkVgp7b8X8VCSeKM/s1600/Blogger-multiple%20(1).png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;&lt;a href="https://blog.google/products-and-platforms/devices/pixel/made-by-google-2026/" target="_blank"&gt;Made by Google&lt;/a&gt; expands what's possible across the Android ecosystem. With the introduction of the &lt;a href="https://blog.google/products-and-platforms/devices/pixel/google-pixel-11-pro-fold/" target="_blank"&gt;Pixel 11 Pro Fold&lt;/a&gt;, &lt;a href="https://blog.google/products-and-platforms/devices/pixel/pixel-watch-5/" target="_blank"&gt;Pixel Watch 5&lt;/a&gt;, and the entire Pixel family, users are moving seamlessly across diverse screen sizes, unique postures, and intelligent experiences. For you, the developer, this represents a massive opportunity: foldable users spend about 14x more than standard phone users. To help you elevate your existing experience without starting from scratch, we’re sharing our latest platform guidance alongside real-world examples from developers already putting these features into production.&lt;/p&gt;

&lt;h2&gt;Deliver adaptive experiences across foldables and expanded displays&lt;/h2&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUCMOYr_J10h7WvM9ZDGYXq_hiGdlpoW4_3x-KSkkuOiDj6efyShTAcjwho2T5Vkq-v0I7IZwwVcIvmG2dp1PXZvosMnNtySZ74Sek58pdBKoN44G5oyAH1YgZw_fwOddP0LHlbHNirDcLzy97twdmJ49i29mZ4_n47S_gt93F8ImHHOTyC4GWqjmXSBY/s1920/crop%20pixelfold.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="911" data-original-width="1920" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUCMOYr_J10h7WvM9ZDGYXq_hiGdlpoW4_3x-KSkkuOiDj6efyShTAcjwho2T5Vkq-v0I7IZwwVcIvmG2dp1PXZvosMnNtySZ74Sek58pdBKoN44G5oyAH1YgZw_fwOddP0LHlbHNirDcLzy97twdmJ49i29mZ4_n47S_gt93F8ImHHOTyC4GWqjmXSBY/s1600/crop%20pixelfold.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;The Pixel 11 Pro Fold gives your app a chance to flex its capabilities with an expanded inner display and a standard size outer screen. Building for the foldable form factor requires dropping hardcoded layout rules and designing around available window space. Leveraging Jetpack Compose APIs like &lt;a href="https://developer.android.com/guide/navigation/navigation-3" target="_blank"&gt;Navigation 3&lt;/a&gt; with &lt;a href="https://developer.android.com/guide/navigation/navigation-3/scenes" target="_blank"&gt;Scene&lt;/a&gt; strategies or our newest layout APIs like &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/grid" target="_blank"&gt;Grid&lt;/a&gt; and &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/flexbox" target="_blank"&gt;FlexBox&lt;/a&gt; allows your layout containers to automatically wrap, span, and reflow. You can also use the experimental &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/mediaquery" target="_blank"&gt;MediaQuery&lt;/a&gt; API to dynamically adapt your UI to environmental signals like foldable posture, and keyboard states.&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Building adaptively requires tracking actual app dimensions rather than physical device size, especially during split-screen and multitasking flows. Using &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/use-window-size-classes" target="_blank"&gt;Window Size Classes&lt;/a&gt; from the &lt;a href="https://developer.android.com/blog/posts/jetpack-window-manager-1-5-is-stable" target="_blank"&gt;WindowManager library&lt;/a&gt; allows your layout to respect folds and hinges as natural content separators.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqeGVhyphenhyphenA6wBtlSYvbvZS6hCUU6aFrwK13ctl5VFW0S-p6qt6Dnrvrhj66tpI1EncSPAo32EgqMoAWnuON1-5H2jyQ8FLupTR8Jiq_iXvYsoIVGJvXyXSGwlVYw-7PYcKPbv4F8s52RZGkhHhLuBwPo0HyUBJMKnuMhtKPwlSL7g9BU4WaSnLmzGgSGp_4/s2899/Ryan%20Shea%20-%20Notability%20simple.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1547" data-original-width="2899" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqeGVhyphenhyphenA6wBtlSYvbvZS6hCUU6aFrwK13ctl5VFW0S-p6qt6Dnrvrhj66tpI1EncSPAo32EgqMoAWnuON1-5H2jyQ8FLupTR8Jiq_iXvYsoIVGJvXyXSGwlVYw-7PYcKPbv4F8s52RZGkhHhLuBwPo0HyUBJMKnuMhtKPwlSL7g9BU4WaSnLmzGgSGp_4/s1600/Ryan%20Shea%20-%20Notability%20simple.png" /&gt;&lt;/a&gt;&lt;/div&gt;For instance, Notability leveraged Material 3 Window Size Classes to create a responsive two-pane layout that transitions smoothly between folded and expanded screens. As Ryan Shea, Android Engineering Manager at Notability, shared, tracking the window itself allows their layout and canvas zoom to ensure notes stay fit to the page through every fold, rotation, or split-screen resize, noting that they wanted the app "to feel native at every size, not just stretched to fit."&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTPInYRTfD2YMniWtRr9KR2S_jZKXyVeiRrhRyNN_XVpSmQ0xQSr_E4N31Qx9-l131uRr87XpMyXbBjx9otBBHKQIAVsIc7iQbC7btN3Ky366J0e98aX7p64VUh4Ce9S4kp9W-VywHNcbVPdbGOEzIP1fGD-9iLubuwzjOI0MhJrJ1rhecbGGB1776gPM/s3840/Foldable-quiz.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2522" data-original-width="3840" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTPInYRTfD2YMniWtRr9KR2S_jZKXyVeiRrhRyNN_XVpSmQ0xQSr_E4N31Qx9-l131uRr87XpMyXbBjx9otBBHKQIAVsIc7iQbC7btN3Ky366J0e98aX7p64VUh4Ce9S4kp9W-VywHNcbVPdbGOEzIP1fGD-9iLubuwzjOI0MhJrJ1rhecbGGB1776gPM/w400-h263/Foldable-quiz.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Notability’s quiz UI adapted for expanded screens&lt;/div&gt;

&lt;p&gt;Ensuring these transitions feel seamless also requires state preservation across configuration changes. Using &lt;a href="https://developer.android.com/topic/libraries/architecture/viewmodel?hl=en" target="_blank"&gt;ViewModel&lt;/a&gt; retains UI state so interactions like scroll position, form inputs, and open dialogs remain uninterrupted when transitioning between inner and outer screens.&lt;/p&gt;

&lt;p&gt;Taking this approach, Flo Health used Jetpack Compose state primitives, ViewModel, and Window Size Classes to make their highest-traffic user journeys resilient to rotation, fold/unfold and resizing transitions. As Aleksandr Kolodiazhnyi, Senior Android Engineer at Flo Health, shared, “Android's adaptive guidance turned what looked like a major refactor into a templated rollout," allowing them to adopt Compose primitives without a rewrite, "cutting [their] state-preservation code by roughly 30% while fixing lifecycle and analytics correctness issues that improved the app on every form factor."&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLAjtvzoJauPxkpO-JB63tFCuErrfO79GwjMnWm1i59LXVOvJ6ILeZU_Za52RfuVQ3rmSOJ2kkOobLdh9U86I3uezcdoReDDnRj-sPAGCKRbf9FS3VewB0BiQSlBMKu4sHNTARPaXsIH1co2DbDEd_dYe1ZPcyB1HTxwDWMh2_Xv_ylKb1z2OwwjkdPdo/s5798/Alexander%20-%20Pixel%20quote.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="3094" data-original-width="5798" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLAjtvzoJauPxkpO-JB63tFCuErrfO79GwjMnWm1i59LXVOvJ6ILeZU_Za52RfuVQ3rmSOJ2kkOobLdh9U86I3uezcdoReDDnRj-sPAGCKRbf9FS3VewB0BiQSlBMKu4sHNTARPaXsIH1co2DbDEd_dYe1ZPcyB1HTxwDWMh2_Xv_ylKb1z2OwwjkdPdo/s1600/Alexander%20-%20Pixel%20quote.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;To take full advantage of the foldable form factor, leverage &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/foldables/make-your-app-fold-aware" target="_blank"&gt;FoldingFeature updates&lt;/a&gt; to trigger posture-specific layouts. When a user partially folds their device into tabletop posture, you can split your UI automatically by placing primary controls on the lower display and main content or viewfinders on the upper display.&lt;/p&gt;

&lt;p&gt;Handling camera previews across foldable state changes, requires managing orientation shifts carefully. Migrating to the &lt;a href="https://developer.android.com/training/camerax" target="_blank"&gt;CameraX library&lt;/a&gt; ensures automatic handling of sensor rotation and display scaling across screens, while existing &lt;a href="https://developer.android.com/media/camera/camera2" target="_blank"&gt;Camera2&lt;/a&gt; codebases can also achieve stability using the &lt;a href="https://developer.android.com/media/camera/camera2/camera-preview#cameraviewfinder" target="_blank"&gt;CameraViewfinder&lt;/a&gt; library. These &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/foldables/support-foldable-display-modes"&gt;camera and display capabilities&lt;/a&gt; allow you to power dual-screen previewing and high-resolution rear camera selfies with minimal custom logic.&lt;/p&gt;

&lt;p&gt;Prepare your app for these form factors today by exploring our complete adaptive development guidance at &lt;a href="http://developer.android.com/adaptive-apps" target="_blank"&gt;Build adaptive apps&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Bring delightful, gesture-driven experiences to the wrist&lt;/h2&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_4eMKGw93_Uu7cW0frkS_x68SImIM_b1ytieDrsmPOzobGTB_fhkhN9aQDDfkNp3jPISFm8cP0AahvllaBoLL6Nq3D6aja-qxpWWoh9SHrGjvoiFK9BWHK3R-vP-F-wnG1w6p1VibS4Q7nrq7veVOpUDGMU7ShtypJiqwqE2QQXr2yrwiN8kT68L1o3c/s1920/croppixelwatch.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="872" data-original-width="1920" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_4eMKGw93_Uu7cW0frkS_x68SImIM_b1ytieDrsmPOzobGTB_fhkhN9aQDDfkNp3jPISFm8cP0AahvllaBoLL6Nq3D6aja-qxpWWoh9SHrGjvoiFK9BWHK3R-vP-F-wnG1w6p1VibS4Q7nrq7veVOpUDGMU7ShtypJiqwqE2QQXr2yrwiN8kT68L1o3c/s1600/croppixelwatch.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;The new Pixel Watch 5 is here, and we’ve optimized it to take advantage of the intelligent, power-efficient, touch-free convenience of &lt;a href="https://developer.android.com/blog/posts/what-s-new-in-wear-os-7" target="_blank"&gt;Wear OS 7&lt;/a&gt;. Thanks to system-wide performance optimizations and a collection of new features built to help users complete tasks efficiently, you can provide rich experiences that require only a single user action to complete.&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://android-developers.googleblog.com/2026/08/one-handed-gestures-wear-os.html" target="_blank"&gt;one-handed gestures framework&lt;/a&gt; provides a convenient way for users to interact with their watches without needing to touch the screen with their opposite hand. Starting with the &lt;a href="https://developer.android.com/jetpack/androidx/releases/wear-compose" target="_blank"&gt;1.7 beta release of Compose for Wear OS 7&lt;/a&gt;, you can seamlessly integrate one-handed gesture control into your Wear Compose apps with simple physical inputs on the watch-wearing arm, like a double-pinch or wrist turn.&lt;/p&gt;

&lt;p&gt;Spotify is &lt;a href="https://developer.android.com/design/ui/wear/guides/patterns/gestures" target="_blank"&gt;adopting this framework&lt;/a&gt; to make controlling media more effortless. By mapping Wear OS gesture events directly to the media player state, users will be able to pause or resume playback using a simple double-pinch, keeping music controls accessible even when their hands are full.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqQAVxEkOTJgeixZl-64stGWUaxA4SJ4lwPY19W58CzVk6Y58_9Wdwyj7_IClhtGWQB7EptJ0c734e6nWFJeu1sKAfRLooOKWa7dvUyOd7pehQMKf7LkGrkBYRkYOYqQYywKInle3bAFMjjRVk_Oe77MpX2jV6H3H3jZ02IN7Ca3kahnYsaY6TGD-SdMk/s640/image6.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="360" data-original-width="640" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqQAVxEkOTJgeixZl-64stGWUaxA4SJ4lwPY19W58CzVk6Y58_9Wdwyj7_IClhtGWQB7EptJ0c734e6nWFJeu1sKAfRLooOKWa7dvUyOd7pehQMKf7LkGrkBYRkYOYqQYywKInle3bAFMjjRVk_Oe77MpX2jV6H3H3jZ02IN7Ca3kahnYsaY6TGD-SdMk/s320/image6.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Pause Spotify media with a pinch gesture&lt;/div&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Wear OS 7 also brings &lt;a href="https://developer.android.com/develop/ui/views/notifications/live-update" target="_blank"&gt;Live Updates&lt;/a&gt; directly to the wrist to surface real-time information like live sports scores, workout progress, and delivery status, which can also appear in the At-a-Glance surface on Pixel Watch 5. For example, Just Eat uses Live Updates to keep users informed on order arrival times at a glance. You can publish updates locally from your watch app or leverage phone notification bridging on supported devices to deliver real-time tracking across screens.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOYERMYpwwnIZORfzqQKNu4Iq9ZftFyBRuhrMKvSyoiIdrt8rViH4HmSeiqaZnfW-IOxcvQgoauIu_f4u_e7tpK15bV8fhLQ2YJKMTsaT1-SunDKUwXrPI5VTjSBOTsGMoPD2GfugNI1HCOTRV3MUCQ4OsE77Qjg3_ic7_POKrDnRWbbrJKKdpMDTU-zE/s2000/Untitled%20design.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1127" data-original-width="2000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOYERMYpwwnIZORfzqQKNu4Iq9ZftFyBRuhrMKvSyoiIdrt8rViH4HmSeiqaZnfW-IOxcvQgoauIu_f4u_e7tpK15bV8fhLQ2YJKMTsaT1-SunDKUwXrPI5VTjSBOTsGMoPD2GfugNI1HCOTRV3MUCQ4OsE77Qjg3_ic7_POKrDnRWbbrJKKdpMDTU-zE/s1600/Untitled%20design.jpg" /&gt;&lt;/a&gt;Live Updates from Just Eat delivering real-time status and delivery ETAs at a glance&lt;/div&gt;

&lt;p&gt;You can also extend glanceable interactions across watch surfaces on Wear OS 7 by using Wear Widgets, powered by &lt;a href="https://developer.android.com/jetpack/androidx/releases/glance-wear" target="_blank"&gt;Jetpack Glance&lt;/a&gt; and &lt;a href="https://developer.android.com/jetpack/androidx/releases/compose-remote" target="_blank"&gt;RemoteCompose&lt;/a&gt;. Wear Widgets with Compose offer greater expressiveness and consistency than the old Tiles framework, and the two available widget layouts—small and large– align perfectly with the 2x1 and 2x2 formats on mobile, ensuring your designs feel cohesive across devices.&lt;/p&gt;

&lt;p&gt;On top of all these great new features, Wear OS 7 delivers up to a 10 percent improvement in battery life over Wear OS 6, making the Pixel Watch 5 a truly indispensable all-day companion for your users.&lt;/p&gt;

&lt;p&gt;To get started developing for Wear OS 7, use the new &lt;a href="https://developer.android.com/training/wearables/versions/7/setup" target="_blank"&gt;emulator&lt;/a&gt;, and check out all of our Wear OS resources and guidance at &lt;a href="https://developer.android.com/wear" target="_blank"&gt;Build apps for the wrist with Wear OS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Unlock on-device intelligence with Gemini Nano 4&lt;/h2&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlF382lfc8sv0ljI0-glN8BJwWKS5VejXVJBSiICxureg5eJ_ZWjQTw99H0bYy2jHjuEZy_JZJYBCRuM1CRjqVZnn777xzjyY6-fKYEFQIWz5D0e_DjY092I0_VZsafdg-SZESsyTBBiOBJAdvkV0Ur6G9gMH1-kpVrvWPzYQGfoHGlagG2AamI_l5LYA/s1915/crop%20pixel11.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="836" data-original-width="1915" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlF382lfc8sv0ljI0-glN8BJwWKS5VejXVJBSiICxureg5eJ_ZWjQTw99H0bYy2jHjuEZy_JZJYBCRuM1CRjqVZnn777xzjyY6-fKYEFQIWz5D0e_DjY092I0_VZsafdg-SZESsyTBBiOBJAdvkV0Ur6G9gMH1-kpVrvWPzYQGfoHGlagG2AamI_l5LYA/s1600/crop%20pixel11.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Pixel 11 devices are built to run Gemini Nano 4, bringing fast, responsive, on-device intelligence to the hardware. By running AI workflows directly on device, you can offer low-latency, real-time interactions that feel instant and integrated without needing round trips to the cloud.&lt;/p&gt;

&lt;p&gt;Through the &lt;a href="https://developers.google.com/ml-kit/genai" target="_blank"&gt;ML Kit GenAI Prompt API&lt;/a&gt;, you can send natural language requests directly to Gemini Nano on device. The model supports over 140 languages, better multimodal understanding, and &lt;a href="https://developers.google.com/ml-kit/release-notes#july_14_2026" target="_blank"&gt;much more&lt;/a&gt;. Build intelligent on-device features using advanced capabilities like &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/structured-output" target="_blank"&gt;structured output&lt;/a&gt; and &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/thinking-mode" target="_blank"&gt;thinking mode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Build smart capabilities into your app using our self-service tools and &lt;a href="https://developer.android.com/ai/overview" target="_blank"&gt;Gemini models&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Shape the next generation of experiences for the Pixel ecosystem today&lt;/h2&gt;

&lt;p&gt;Made by Google showcases what's possible when hardware and software evolve together, and you are at the center of that innovation. You can begin optimizing your apps today by exploring our updated &lt;a href="https://developer.android.com/develop/adaptive-apps" target="_blank"&gt;adaptive guidance&lt;/a&gt;, creating &lt;a href="https://developer.android.com/wear" target="_blank"&gt;glanceable experiences&lt;/a&gt; for Wear OS 7, and integrating on-device AI with &lt;a href="https://developers.google.com/ml-kit" target="_blank"&gt;ML Kit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To help you implement these updates even faster, you can now leverage &lt;a href="https://developer.android.com/tools/agents/android-skills" target="_blank"&gt;Android skills&lt;/a&gt;, which provide AI-optimized instructions for agents and tools. Whether you are using Gemini in Android Studio or running the &lt;a href="https://developer.android.com/tools/agents/android-cli" target="_blank"&gt;Android CLI&lt;/a&gt; through other agents, Android skills give your AI tools the context needed to execute complex workflows automatically. For instance, you can prompt your agent with the &lt;a href="https://github.com/android/skills/tree/main/camera/camerax" target="_blank"&gt;CameraX skill&lt;/a&gt; to handle camera display scaling across foldables, or use the &lt;a href="https://github.com/android/skills/tree/main/jetpack-compose/adaptive" target="_blank"&gt;Adaptive skill&lt;/a&gt; to set up dynamic Compose layouts without additional manual work.&lt;/p&gt;

&lt;p&gt;Take advantage of these new surfaces, accelerate your workflow with agentic tools, and share your latest builds with the Android community! Head over to &lt;a href="https://developer.android.com"&gt;developer.android.com&lt;/a&gt; to access full documentation, explore the &lt;a href="https://goo.gle/android-skills" target="_blank"&gt;Android skills GitHub repository&lt;/a&gt;, and start building today.&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</content><link href="http://android-developers.googleblog.com/feeds/4347998413375612878/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/pixel-app-experience-made-by-google.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/4347998413375612878" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/4347998413375612878" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/pixel-app-experience-made-by-google.html" rel="alternate" title="Enhance your app for the new Pixel lineup: Unveiled at Made by Google" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA6QfkFAxNGheiHxY8wkPFxujmDTwO1WbzGjmHCwc8DOW1jM580d0JfSDaYXnxE1ON5aHzO7SWsECCmd9fZyEd0doDRSmXutkt55h3BZJ8w1FBlGLQpw22DD7EGX1ktz5NuIgcIGKm38PwxUSkTMsqSqmN-x87t3uQuRC3zlYQCmX-XDmeHobiBB3Oh4k/s72-c/Metadata-multiple.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-2798697072776672466</id><published>2026-08-12T10:00:00.000-07:00</published><updated>2026-08-12T10:28:26.399-07:00</updated><title type="text">Bring one-handed gestures to your Wear OS app</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaeeM1JYV7L4tEddXDUrgZGLlprNlBrlghIljPvSwDyq756kf5-J7Ogw6IroXrIzyECmybkmiCz_cEhHvSmrx6gkMCJZ81Q4Tty4JKfZUrXkl7Alm3g1FnXLXpryfOnb5hGAaP9Ro4Y5QttFU3Rd1pZPxHB9WY4j4f0OlqjSBzIeabTGyB62bP45OASTo/s2469/Bring-one-handed-gestures_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaeeM1JYV7L4tEddXDUrgZGLlprNlBrlghIljPvSwDyq756kf5-J7Ogw6IroXrIzyECmybkmiCz_cEhHvSmrx6gkMCJZ81Q4Tty4JKfZUrXkl7Alm3g1FnXLXpryfOnb5hGAaP9Ro4Y5QttFU3Rd1pZPxHB9WY4j4f0OlqjSBzIeabTGyB62bP45OASTo/s2469/Bring-one-handed-gestures_Meta.png" style="display: none;" /&gt;&lt;div&gt;&lt;i&gt;Posted by Chiara Chiappini, Developer Relation Engineer, Android Developer Relations&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc6KkXKMNtc5kEU9yQZfYwSHPVnNlb3zuFl6tykF2SlyfoWMNE6C4907CRXF1ZCxGIIC2IjkMe2zVqYiibKzq93-G7fhZqTs8_aJy-pptJV9BThOdmtoufBI5Au_J21Anm1uHZJjlq_kveSOUbXmfwtEH1jzvrOKJK_M8Pu_D-5zob1E85V_uUAplVRMo/s4291/Bring-one-handed-gestures-to-your-Wear-OS-app-_Blog.gif" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1300" data-original-width="4291" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc6KkXKMNtc5kEU9yQZfYwSHPVnNlb3zuFl6tykF2SlyfoWMNE6C4907CRXF1ZCxGIIC2IjkMe2zVqYiibKzq93-G7fhZqTs8_aJy-pptJV9BThOdmtoufBI5Au_J21Anm1uHZJjlq_kveSOUbXmfwtEH1jzvrOKJK_M8Pu_D-5zob1E85V_uUAplVRMo/s1600/Bring-one-handed-gestures-to-your-Wear-OS-app-_Blog.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;One-handed gestures offer a convenient and touch-free way for users to interact with their watches, enabling them to perform key actions using only the hand on which the device is worn.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;First introduced on Pixel Watch with Wear OS 6.1, one-handed gestures made quick interactions effortless, such as starting and stopping a timer, accepting calls, and controlling media.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Now, with Wear OS 7, we're expanding this functionality with a new Gestures framework that allows OEMs to map gestures to primary actions and dismissals, and an API to bring gesture control to the developer community.&lt;/p&gt;

&lt;p&gt;Starting with the 1.7 &lt;a href="https://developer.android.com/jetpack/androidx/releases/wear-compose"&gt;beta release of Compose for Wear OS&lt;/a&gt;, you can seamlessly integrate gesture control into your Wear Compose apps. To use this release, upgrade your Wear Compose dependency to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;androidx.wear.compose:compose-material3:1.7.0-beta01&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Designing for one-handed interaction&lt;/h3&gt;
&lt;p&gt;The one-handed gestures framework is designed around two primary interaction patterns that allow users to take action without touching the screen:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Primary action, which on Pixel Watch is mapped to a double-pinch gesture: this action should be mapped to the most important task in a given context. For example, users can perform this gesture to take a photo in a camera app, start/stop a timer, or accept an incoming call.&amp;nbsp;&lt;/li&gt;
    &lt;li&gt;Dismiss action, which on Pixel Watch is mapped to a wrist turn gesture: this action is mapped to system back by default and provides an intuitive way to close interruptive screens or get back to the watch face. It may be overridden for specific use cases, such as silencing an incoming phone call.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These gestures are currently available on Pixel Watch 3 and newer, and the Wear OS gesture framework is available to all Wear OS device manufactures to adopt.&lt;/p&gt;

&lt;p&gt;Check out our new &lt;a href="https://developer.android.com/design/ui/wear/guides/patterns/gestures"&gt;design guidance&lt;/a&gt; for integrating one-handed gestures into your Wear app.&lt;/p&gt;

&lt;h3&gt;Integrating gestures with Compose on Wear OS&lt;/h3&gt;
&lt;p&gt;To provide seamless gesture support in Wear OS 7, we are introducing a new &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/oneHandedGesture.modifier"&gt;Modifier.oneHandedGesture&lt;/a&gt; that you can apply to any existing interactive composable to make it gesture-aware.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Implementing gestures with Compose on Wear OS requires these steps:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Define the gesture configuration. Start by using &lt;code&gt;rememberOneHandedGestureConfiguration&lt;/code&gt; to define the nature of the interaction. This configuration dictates the basic behavior by providing the &lt;code&gt;GestureAction&lt;/code&gt; (e.g. tracking a primary pinch or a dismiss wrist flick).&lt;/li&gt;
    &lt;li&gt;Initialize the indicator state. Depending on your UI component, initialize a specific state object, such as &lt;code&gt;OneHandedGestureClickIndicatorState&lt;/code&gt; for buttons or &lt;code&gt;OneHandedGestureScrollIndicatorState&lt;/code&gt; for scrollable lists. This state is used to coordinate visual feedback between the gesture detection modifier and the visual UI indicators, seamlessly managing visibility, timing, and animations.&lt;/li&gt;
    &lt;li&gt;Apply &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/oneHandedGesture.modifier"&gt;Modifier.oneHandedGesture&lt;/a&gt; to your interactive component. You'll pass in your configuration and state, and you’ll provide standard callbacks: &lt;code&gt;onGestureAvailable&lt;/code&gt; to activate the visual hint when the system prepares the gesture, and &lt;code&gt;onGesture&lt;/code&gt; to execute your action when the gesture happens.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following sample shows how those three steps translate into code when configuring an &lt;code&gt;IconButton&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val gestureConfig = rememberOneHandedGestureConfiguration(action = OneHandedGestureAction.Primary)
val indicatorState = remember { OneHandedGestureClickIndicatorState() }
val coroutineScope = rememberCoroutineScope()

OutlinedIconButton(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick = onPlayPauseButtonClicked,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier = Modifier.touchTargetAwareSize(IconButtonDefaults.LargeButtonSize)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.oneHandedGesture(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gestureConfiguration = gestureConfig,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;interactionSource = interactionSource,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGestureLabel = "play or pause",
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGestureAvailable = {&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;coroutineScope.launch { indicatorState.showIndicator() }&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGesture = onPlayPauseButtonClicked,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// button content goes here
&amp;nbsp; &amp;nbsp; // See "Guided discovery with gesture indicators" section of this post for recommendations on adding a gesture indicator.
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;GestureAction.Primary&lt;/code&gt; can also be used to scroll when the content is the end goal of the user journey, or there is a gesture actionable button off screen that the user can scroll to. Some examples include:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Scrolling through a notification to view the content and/or initiate a reply (available in &lt;code&gt;TransformingLazyColumn&lt;/code&gt; and &lt;code&gt;ScalingLazyColumn&lt;/code&gt;).&lt;/li&gt;
    &lt;li&gt;Paging through workout metrics or other content that doesn’t require the user to tap to continue the user journey (available in&amp;nbsp; &lt;code&gt;HorizontalPager&lt;/code&gt; and &lt;code&gt;VerticalPager&lt;/code&gt;).&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;pre&gt;&lt;code&gt;val scrollGestureConfig = rememberOneHandedGestureConfiguration(action = GestureAction.Primary)
val scrollIndicatorState = remember { OneHandedGestureScrollIndicatorState() }
val coroutineScope = rememberCoroutineScope()

TransformingLazyColumn(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;state = scrollState,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentPadding = contentPadding,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier = Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxSize()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.oneHandedGesture(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gestureConfiguration = scrollGestureConfig,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGestureLabel = "scroll",
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGestureAvailable = {&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;coroutineScope.launch { scrollIndicatorState.showIndicator() }&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// list content goes here
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// See "Guided discovery with gesture indicators" section of this post for recommendations on adding a gesture indicator.
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Guided discovery with gesture indicators&lt;/h3&gt;
&lt;p&gt;To help users learn which gestures are available, gesture indicators work as hints to help discovery about which gestures are available on a screen.&lt;/p&gt;
&lt;p&gt;These hints provide animated cues that inform users where they can perform a gesture. The framework manages the cadence and appearance of these hints, ensuring that they are helpful without being intrusive. System settings let users change the cadence to something less frequent if desired.&lt;/p&gt;
&lt;p&gt;To integrate with hints, the API provides the following gesture indicator components:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;the &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/OneHandedGestureClickIndicator.composable" target="_blank"&gt;OneHandedGestureClickIndicator&lt;/a&gt; for components like a&amp;nbsp; &lt;code&gt;Button&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;the &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/OneHandedGestureScrollIndicator.composable" target="_blank"&gt;OneHandedGestureScrollIndicator&lt;/a&gt; component for scrolling&lt;/li&gt;
    &lt;li&gt;the &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/OneHandedGestureHorizontalPageIndicator.composable" target="_blank"&gt;OneHandedGestureHorizontalPageIndicator&lt;/a&gt; for the &lt;code&gt;HorizontalPager&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;the &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/OneHandedGestureVerticalPageIndicator.composable" target="_blank"&gt;OneHandedGestureVerticalPageIndicator&lt;/a&gt; for the &lt;code&gt;VerticalPager&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following example shows how to use the &lt;code&gt;OneHandedGestureClickIndicator&lt;/code&gt; for a &lt;code&gt;Button&lt;/code&gt;. See another example for using the &lt;a href="https://developer.android.com/reference/kotlin/androidx/wear/compose/material3/onehandedgesture/OneHandedGestureScrollIndicator.composable" target="_blank"&gt;OneHandedGestureScrollIndicator&lt;/a&gt; in our &lt;a href="https://developer.android.com/training/wearables/compose/one-handed-gestures" target="_blank"&gt;guidance&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val gestureConfig = rememberOneHandedGestureConfiguration(action = GestureAction.Primary)
val indicatorState = remember { OneHandedGestureClickIndicatorState() }
val coroutineScope = rememberCoroutineScope()

OutlinedIconButton(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick = onPlayPauseButtonClicked,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier = Modifier.touchTargetAwareSize(IconButtonDefaults.LargeButtonSize)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.oneHandedGesture(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gestureConfiguration = gestureConfig,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;interactionSource = interactionSource,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGestureLabel = "play or pause",
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGestureAvailable = {&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;coroutineScope.launch { indicatorState.showIndicator() }&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onGesture = onPlayPauseButtonClicked,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OneHandedGestureClickIndicator(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gestureConfiguration = gestureConfig,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;indicatorState = indicatorState,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val icon = if (playerUiModel.playbackState.isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Icon(icon, contentDescription = "Play or Pause")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTbGTNKsdUX6X_kz-Gsk95kyJLktmdHkX-vsDjkvNRCSnRlTaoDM8jw7sa3cpInvyEY7bL3z___jzsGY02fs6McCycswCNB8KiiXQt-mIEx8pfao8I_kk3VjQPedE58iMJdRyZV4WaSC_29cZfjLdO9Fwyo7duwKxO-cDgvtDAd8yXBA3KGUmevAxb2L0/s1046/sample-app.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="588" data-original-width="1046" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTbGTNKsdUX6X_kz-Gsk95kyJLktmdHkX-vsDjkvNRCSnRlTaoDM8jw7sa3cpInvyEY7bL3z___jzsGY02fs6McCycswCNB8KiiXQt-mIEx8pfao8I_kk3VjQPedE58iMJdRyZV4WaSC_29cZfjLdO9Fwyo7duwKxO-cDgvtDAd8yXBA3KGUmevAxb2L0/w640-h360/sample-app.gif" width="640" /&gt;&lt;/a&gt;Sample app showing gesture hint for media controls&lt;/div&gt;&lt;p&gt;We are already seeing early adoption of these APIs from partners like Spotify, who are using one-handed gestures to make music control more seamless on the go. By adopting the &lt;code&gt;Modifier.oneHandedGesture&lt;/code&gt; into their Wear OS app, Spotify allows users to play or pause their music with the primary gesture action, which on Pixel Watch devices is the double-pinch gesture. This action triggers the same behavior as the physical play/pause button, and the user doesn’t&amp;nbsp; need to touch the screen.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" data-original-height="360" data-original-width="640" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTueO6IjqBhWueD19XiP8PL8E2OJg2bBGwY9RGSuvezkot1iLygPSmnY6CWstxKFPpJ8s6Fjj7XltBTFW1LKQ8F5_6Riq-PvA6BNoOwOc_E8y9dpv9CBm46UM75K8cNWlVdoYQCGBNFa3wc0P3lrOEnPDPschQ1GV5Sz98uWyjR1wKRLS4H7ICfOksGjA/w640-h360/spotify.gif" width="640" /&gt;.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Spotify app with gesture integration&lt;/div&gt;

&lt;h3&gt;Bring one-handed gestures to your app&lt;/h3&gt;
&lt;p&gt;You can begin experimenting with one-handed gestures today in the 1.7 beta release of Compose for Wear OS.&lt;/p&gt;
&lt;p&gt;Ensure your app is running on Wear OS 7, which provides the underlying platform support for gesture detection. Check out our new &lt;a href="https://developer.android.com/training/wearables/compose/one-handed-gestures" target="_blank"&gt;one-handed gestures developer guide&lt;/a&gt;&amp;nbsp; to see how you can start building more convenient experiences for your users.&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/2798697072776672466/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/one-handed-gestures-wear-os.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/2798697072776672466" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/2798697072776672466" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/one-handed-gestures-wear-os.html" rel="alternate" title="Bring one-handed gestures to your Wear OS app" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaeeM1JYV7L4tEddXDUrgZGLlprNlBrlghIljPvSwDyq756kf5-J7Ogw6IroXrIzyECmybkmiCz_cEhHvSmrx6gkMCJZ81Q4Tty4JKfZUrXkl7Alm3g1FnXLXpryfOnb5hGAaP9Ro4Y5QttFU3Rd1pZPxHB9WY4j4f0OlqjSBzIeabTGyB62bP45OASTo/s72-c/Bring-one-handed-gestures_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-8497185682650112021</id><published>2026-08-12T09:00:00.000-07:00</published><updated>2026-08-13T07:59:00.337-07:00</updated><title type="text">What's new in the Jetpack Compose August '26 release</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvR5TrjJE4Z1NMYxATN7zx3pmkOMm1lDAhV3u8h7RKVvQJzUsf2XJEwK7dY1b_d8eEEBvAV6wYIqtgKrh4xnkBv6EHGKr524At__nz0qbmlPNC402UFGtH1OrwlWtlxNB0XPRWdQd4FUwlaeOkOaDw-lCn47U_snuzIC-wZIaKkTceBrGcfCM8k2ifMsM/s1024/Social%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvR5TrjJE4Z1NMYxATN7zx3pmkOMm1lDAhV3u8h7RKVvQJzUsf2XJEwK7dY1b_d8eEEBvAV6wYIqtgKrh4xnkBv6EHGKr524At__nz0qbmlPNC402UFGtH1OrwlWtlxNB0XPRWdQd4FUwlaeOkOaDw-lCn47U_snuzIC-wZIaKkTceBrGcfCM8k2ifMsM/s1024/Social%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" style="display: none;" /&gt;&lt;div&gt;&lt;i&gt;Posted by Nick Butcher, Product Manager, Jetpack Compose&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6uEKoqS22NIh_MtD-vsVMr_jVbeHVDM9HVaw08aF5TzACF9eiqOpEsjGP-8KgLogXLbv0Q9bfdQCYIoSXWFVoXqmOyR8j17cwY9uxsue7gA01WCwU2iCJSKQcUTB4x5wNvMpzf9Moff0kWh5ACzK_B2Qi70IKl-rAnZkl6H1Kgj05nfiHCXtG3WoHXzY/s1600/Header%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="476" data-original-width="1600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6uEKoqS22NIh_MtD-vsVMr_jVbeHVDM9HVaw08aF5TzACF9eiqOpEsjGP-8KgLogXLbv0Q9bfdQCYIoSXWFVoXqmOyR8j17cwY9uxsue7gA01WCwU2iCJSKQcUTB4x5wNvMpzf9Moff0kWh5ACzK_B2Qi70IKl-rAnZkl6H1Kgj05nfiHCXtG3WoHXzY/s1600/Header%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Today, the Jetpack Compose August ‘26 release is stable! This release brings version 1.12 across core Compose modules (see the full &lt;a href="https://developer.android.com/develop/ui/compose/bom/bom-mapping" target="_blank"&gt;BOM mapping&lt;/a&gt;), introducing rich visual APIs like Mesh Gradients and Wide Color Gamut (WCG) support, structural layout features like named areas in Grid, seamless integration with Android’s Credential Manager, and significant testing and performance improvements.&lt;/p&gt;

&lt;p&gt;To update your project to today’s release, upgrade your &lt;a href="https://developer.android.com/develop/ui/compose/bom" target="_blank"&gt;Compose BOM&lt;/a&gt; version to &lt;code&gt;2026.08.00&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;implementation(platform("androidx.compose:compose-bom:2026.08.00"))&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Breaking Changes&lt;/h2&gt;
&lt;p&gt;AGP &amp;amp; Compile SDK: Compose 1.12 updates &lt;code&gt;compileSdk&lt;/code&gt; to API 37, requiring a minimum AGP 9.1.1. As a reminder, Compose will always target the latest &lt;code&gt;compileSdk&lt;/code&gt;. Learn more about this change &lt;a href="https://developer.android.com/develop/ui/compose/setup-compose-dependencies-and-compiler#agp-compatibility" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Modifier.onFirstVisible()&lt;/code&gt; is deprecated: Migrate to &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/onVisibilityChanged.modifier" target="_blank"&gt;Modifier.onVisibilityChanged()&lt;/a&gt;&lt;/code&gt;, which provides more precise visibility threshold tracking.&lt;/p&gt;

&lt;h3&gt;Graphics&lt;/h3&gt;
&lt;h2&gt;Mesh Gradients&lt;/h2&gt;
&lt;p&gt;Compose 1.12 introduces &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/MeshGradientPainter" target="_blank"&gt;MeshGradientPainter&lt;/a&gt;&lt;/code&gt; to help you create multi-point, organic color gradients.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM-ha8Gsg6B6VjQung23xPKQ2bacwFr4WkFjTMRGZlYNi-GkDeEaPDi27pXasdGTEzBJ5dyRosimPK4aXLEiMfhBrh5nSpPU3tfHnoa13SAIIXsqy18csHZwiq3vhchjdLvKc2RepZU9brcQmjs9GKbiQJjCmPRtfbnjRKMiwJaFJqiheWV_CJADAp0jo/s1111/mesh_gradient2.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1111" data-original-width="500" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM-ha8Gsg6B6VjQung23xPKQ2bacwFr4WkFjTMRGZlYNi-GkDeEaPDi27pXasdGTEzBJ5dyRosimPK4aXLEiMfhBrh5nSpPU3tfHnoa13SAIIXsqy18csHZwiq3vhchjdLvKc2RepZU9brcQmjs9GKbiQJjCmPRtfbnjRKMiwJaFJqiheWV_CJADAp0jo/w180-h400/mesh_gradient2.gif" width="180" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val rows = 1
val columns = 1

val gradientPainter = remember {
    MeshGradientPainter(rows, columns) {
        // Parameters: row, column, position, color
        setVertex(0, 0, Offset(0f, 0f), Color.Red)     // Top-Left
        setVertex(0, 1, Offset(1f, 0f), Color.Blue)    // Top-Right
        setVertex(1, 0, Offset(0f, 1f), Color.Green)   // Bottom-Left
        setVertex(1, 1, Offset(1f, 1f), Color.Yellow)  // Bottom-Right
    }
}

Box(
    modifier = modifier
        .aspectRatio(16/9f)
        .fillMaxWidth()
        .paint(gradientPainter)
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more information and examples, see the &lt;a href="https://developer.android.com/develop/ui/compose/graphics/draw/mesh-gradient" target="_blank"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Wide Color Gamut &amp;amp; HDR Support&lt;/h2&gt;
&lt;p&gt;Modern displays offer extended color fidelity and higher dynamic range. In Compose 1.12, full pipeline support for &lt;b&gt;Wide Color Gamut (P3)&lt;/b&gt; and &lt;b&gt;HDR rendering&lt;/b&gt; has been enabled across Compose graphics, paint, and shaders. Colors defined in non-sRGB color spaces (such as Display P3) are preserved through to platform rendering without color clamping. Colors will safely fall back to sRGB if they use an unsupported color space (e.g. CieXyz, CieLab, or Oklab), rely on a color space on an unsupported Android version (e.g Bt2020Hlg on Android 13 and below), or if the app is running on Android 9 (API 28) and below.&lt;/p&gt;

&lt;p&gt;Other notable changes:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/LayerOutsets"&gt;LayerOutsets&lt;/a&gt;&lt;/code&gt; was added to &lt;code&gt;GraphicsLayer&lt;/code&gt; &amp;amp; &lt;code&gt;Modifier.graphicsLayer&lt;/code&gt;, which you can use to increase the visual bounds of the layer beyond its measured size. Apply &lt;code&gt;LayerOutsets&lt;/code&gt; to avoid the implicit &lt;code&gt;clipToBounds&lt;/code&gt; behavior when the layer is promoted to an offscreen buffer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Styles&lt;/h3&gt;
&lt;p&gt;At Google I/O, we shared our early vision for the Compose &lt;a href="https://developer.android.com/develop/ui/compose/styles" target="_blank"&gt;Styles API&lt;/a&gt;—a unified, performant way to style components. Since then, we have continued building the underlying architecture to guarantee strict type safety and predictable correctness, and to support building custom design systems.&lt;/p&gt;
&lt;p&gt;To ensure we get this foundational layer correct, the API will remain experimental, and you can expect breaking changes.&lt;/p&gt;

&lt;h3&gt;Runtime Optimizations&lt;/h3&gt;
&lt;h2&gt;Keyed SideEffect Overload&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/SideEffect.composable" target="_blank"&gt;SideEffect&lt;/a&gt;&lt;/code&gt; now supports key arguments, which lets you fire one-shot side effects whenever specific keys change. This can lead to better performance compared to using a &lt;code&gt;LaunchedEffect&lt;/code&gt; or &lt;code&gt;DisposableEffect&lt;/code&gt; when you don’t need the coroutine or dispose block. &lt;code&gt;SideEffect&lt;/code&gt; is up to 90% faster than &lt;code&gt;LaunchedEffect&lt;/code&gt; and around 20% faster than &lt;code&gt;DisposableEffect&lt;/code&gt;. Note that &lt;code&gt;SideEffect&lt;/code&gt; runs its effect before &lt;code&gt;DisposableEffect&lt;/code&gt; and &lt;code&gt;LaunchedEffect&lt;/code&gt;, so use caution if migrating existing effects to this API, especially for &lt;code&gt;LaunchedEffects&lt;/code&gt; that rely on being dispatched to start after the current frame is completed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
    SideEffect(key1 = userId, key2 = screenName) {
        analytics.logScreenView(userId, screenName)
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Animation&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/animation/core/DeferredTargetAnimation" target="_blank"&gt;DeferredTargetAnimation&lt;/a&gt;&lt;/code&gt; has graduated out of experimental status.&lt;/p&gt;
&lt;h2&gt;Interactive Two-Stage Transitions&lt;/h2&gt;
&lt;p&gt;New composables: &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/animation/DeferredAnimatedContent.composable" target="_blank"&gt;DeferredAnimatedContent&lt;/a&gt;&lt;/code&gt; and &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/animation/DeferredAnimatedVisibility.composable" target="_blank"&gt;DeferredAnimatedVisibility&lt;/a&gt;&lt;/code&gt; allow creating delightful two-stage transitions, e.g. for predictive back gesture tracking.&lt;/p&gt;
&lt;p&gt;Manual animation control: During a transition's deferred phase, animated properties (like scale or offset) can now be manually manipulated in real-time (e.g., tracking a swipe gesture).&lt;/p&gt;
&lt;p&gt;Seamless handoff: Once the deferred phase ends, the transition engine takes over and performs a seamless handoff, including velocity transfer, to the automatic transition.&lt;/p&gt;
&lt;p&gt;Shared element support: A new &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/animation/SharedTransitionScope.SharedContentConfig?hl=en#permitTransformDuringDeferredTransition()" target="_blank"&gt;permitTransformDuringDeferredTransition&lt;/a&gt;&lt;/code&gt; flag in &lt;code&gt;SharedContentConfig&lt;/code&gt; controls whether shared elements visually transform along with their parent containers during the deferred transition phase.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)

if (predictiveBackInProgress) {
    state.defer(targetScreen)
} else {
    state.animateTo(targetScreen)
}

transition.DeferredAnimatedContent(
    targetState = targetScreen,
    mutableTransformSpec = {
       MutableContentTransform {
           // Manually manipulate properties during the deferred phase
           initialContentTransform { scale = swipeProgress }
       }
    }
) { screen -&amp;gt;
    ScreenContent(screen)
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Below are two demos of use cases where a gesture-driven animation is handed off to a triggered animation:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlq52T3KC9iksfRG4bJ0Z_CrO-7tDqx9XgIqogGeApllKFnTPBLOwKz_HkL-2IwQe0W7s0dLDhHkdu9pHeGhFcQyUqlixMIA5r85nZXTuYQ6V0Vu5BSKWlimWH9Ro2PX2LRZdKm5Hhjl-LOkPwxFIv0-RRIugGF4Bt0VoL2FhIjOHPZKxHNIRmpGvNNT8/s480/deferred.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="480" data-original-width="428" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlq52T3KC9iksfRG4bJ0Z_CrO-7tDqx9XgIqogGeApllKFnTPBLOwKz_HkL-2IwQe0W7s0dLDhHkdu9pHeGhFcQyUqlixMIA5r85nZXTuYQ6V0Vu5BSKWlimWH9Ro2PX2LRZdKm5Hhjl-LOkPwxFIv0-RRIugGF4Bt0VoL2FhIjOHPZKxHNIRmpGvNNT8/s320/deferred.gif" width="285" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Text, Input &amp;amp; Platform Integrations&lt;/h3&gt;

&lt;h2&gt;Editable Text Formatting&lt;/h2&gt;
&lt;p&gt;New APIs offer rich-text formatting for editable text in &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/BasicTextField.composable" target="_blank"&gt;BasicTextField&lt;/a&gt;&lt;/code&gt;. You can now programmatically apply and manipulate inline character and paragraph formatting using &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/text/SpanStyle" target="_blank"&gt;SpanStyle&lt;/a&gt;&lt;/code&gt; and &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/text/ParagraphStyle" target="_blank"&gt;ParagraphStyle&lt;/a&gt;&lt;/code&gt; via the new &lt;code&gt;addStyle()&lt;/code&gt; method inside a &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer" target="_blank"&gt;TextFieldBuffer&lt;/a&gt;&lt;/code&gt; scope (such as inside &lt;code&gt;textFieldState.edit { ... }&lt;/code&gt; or an &lt;code&gt;InputTransformation&lt;/code&gt;). Additionally, &lt;code&gt;TextFieldBuffer&lt;/code&gt; provides &lt;code&gt;getSpanStyles()&lt;/code&gt; and &lt;code&gt;getParagraphStyles()&lt;/code&gt; APIs that return &lt;code&gt;TrackedRange&lt;/code&gt; objects, allowing you to read, update, or remove applied styles. To complement formatting creation, &lt;code&gt;TextFieldState&lt;/code&gt; now exposes a read-only &lt;code&gt;textStyles&lt;/code&gt; property for querying active styles across ranges, while &lt;code&gt;TextFieldBuffer&lt;/code&gt; provides &lt;code&gt;originalTextStyles&lt;/code&gt; to inspect formatting state prior to an edit. Text formatting and custom annotations are persisted across configuration changes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val state = rememberTextFieldState("Formatted text in Compose 1.12")

// Apply bold and color styles to a range of text
state.edit {
    addStyle(
        SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
        start = 0,
        end = 9
    )
}

// Query active styles from TextFieldState
val currentStyles = state.textStyles&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Text Selection&lt;/h2&gt;
&lt;p&gt;A new &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/selection/SelectionState" target="_blank"&gt;SelectionState&lt;/a&gt;&lt;/code&gt; API provides programmatic control and observability over text selection within a &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/selection/SelectionContainer.composable#SelectionContainer(androidx.compose.ui.Modifier,kotlin.Function0)" target="_blank"&gt;SelectionContainer&lt;/a&gt;&lt;/code&gt;. Hoisting a &lt;code&gt;SelectionState&lt;/code&gt; object via &lt;code&gt;rememberSelectionState()&lt;/code&gt; and passing into &lt;code&gt;SelectionContainer&lt;/code&gt; exposes &lt;code&gt;selectedTexts&lt;/code&gt; as a reactive list of &lt;code&gt;AnnotatedStrings&lt;/code&gt; and provides methods like &lt;code&gt;selectAll()&lt;/code&gt;, &lt;code&gt;clear()&lt;/code&gt;, &lt;code&gt;select(TextRange)&lt;/code&gt;, and &lt;code&gt;extendSelectionByWord()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, use &lt;code&gt;getSelectableTexts()&lt;/code&gt; to retrieve all selectable text items in layout order and select text across composables in the &lt;code&gt;SelectionContainer&lt;/code&gt; using a global range.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@Composable
fun ProgrammaticSelectionExample() {
    val selectionState = rememberSelectionState()

    Column {
        Button(
            onClick = { selectionState.selectAll() },
            modifier = Modifier.disableSelectionClearOnTap()
        ) {
            Text("Select All")
        }

        SelectionContainer(state = selectionState) {
            Text("Text content to be selected programmatically.")
        }
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Credential Manager Integration&lt;/h2&gt;
&lt;p&gt;Compose text fields now natively integrate with Android’s Credential Manager (API 34+) via the Autofill framework (below API 34 is handled by &lt;code&gt;&lt;a href="https://developer.android.com/jetpack/androidx/releases/credentials"&gt;androidx.credentialslibrary&lt;/a&gt;&lt;/code&gt;). By attaching the new &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/SemanticsPropertyReceiver#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).credentialRequest()" target="_blank"&gt;credentialRequest&lt;/a&gt;&lt;/code&gt; semantics property with &lt;code&gt;CredentialRequestData&lt;/code&gt;, text inputs can prompt passkeys, saved credentials, or sign-in requests directly within the user input flow.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@Composable
fun LoginField(textFieldState: TextFieldState) {
    val credentialData = remember {
        CredentialRequestData(
            // Specify Credential Manager request options
        )
    }

    BasicTextField(
        state = textFieldState,
        modifier = Modifier.semantics {
            credentialRequest = credentialData
        }
    )
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Other notable changes:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Support for font variation settings in &lt;a href="https://developer.android.com/develop/ui/compose/text/fonts#downloadable-fonts" target="_blank"&gt;downloadable fonts&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;Enabled auto-scrolling when dragging text selection beyond the viewport in &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/selection/SelectionContainer.composable" target="_blank"&gt;SelectionContainer&lt;/a&gt;&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Added support for automatic interaction sounds (clicks and focus navigation) to Compose components, with a new &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/SoundEffectOnInteraction.composable" target="_blank"&gt;SoundEffectOnInteraction&lt;/a&gt;&lt;/code&gt; composable to allow opt-out. Note that as a consequence of this change, semantics click listeners must now be called from the main thread, which may affect a small number of test cases.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/text/input/KeyboardType" target="_blank"&gt;KeyboardType&lt;/a&gt;&lt;/code&gt; now includes &lt;code&gt;Date&lt;/code&gt;, &lt;code&gt;Time&lt;/code&gt;, &lt;code&gt;DateTime&lt;/code&gt;, and &lt;code&gt;SignedDecimal&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/BasicSecureTextField.composable" target="_blank"&gt;BasicSecureTextField&lt;/a&gt;&lt;/code&gt; now uses &lt;code&gt;TextObfuscationMode.System&lt;/code&gt; by default, while &lt;code&gt;RevealLastTyped&lt;/code&gt; serves as an absolute override.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Layout Enhancements&lt;/h3&gt;
&lt;h2&gt;Named Areas in Grid Layout&lt;/h2&gt;
&lt;p&gt;Building complex 2D layouts is now easier with named areas in the &lt;code&gt;@Experimental&lt;/code&gt; &lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/Grid.composable" target="_blank"&gt;Grid&lt;/a&gt; component. Rather than managing numeric column and row indices across items, you can define semantic regions in your &lt;code&gt;GridConfigurationScope&lt;/code&gt; and position composables by area name.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
    Grid(
        config = {
            area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
            area("sidebar", row = 1, column = 0)
            area("content", row = 1, column = 1)
            gap(16.dp)
        }
    ) {
        HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
        NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
        MainContentView(modifier = Modifier.gridItem(areaId = "content"))
    }
}&lt;/code&gt;&lt;/pre&gt;

For more information, see the &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/grid/container-properties#named-area"&gt;documentation&lt;/a&gt;.&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;As with every release, we continue to invest in Compose's performance to ensure that the framework helps you to build beautiful, performant apps. In this release we've focused on improving startup performance and are now seeing Time to Initial Display (the time it takes for an app to produce its first frame) that is comparable to Views in our &lt;a href="https://developer.android.com/develop/ui/compose/performance/herobenchmark" target="_blank"&gt;benchmarks&lt;/a&gt;.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj72jjYb7EkeE07CYGMo6W0Xk9RFVR4ZleNo6fp5p36lJJ2ku3D-gdm8Jk8In6u-HQ4Kn5XM08uK5-exdOSK3Ajr4GmDNVCLztXnRsdUQ-77l_GXps1d8Q4vdpqdrNUsrYsKhbHOTndzh0hOtgs72ww28zaZPUVGcH1ITrog09t8QohS8E4V76sqpWQxdQ/s1414/timetoinitialdisplay@2x%20_v2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1390" data-original-width="1414" height="315" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj72jjYb7EkeE07CYGMo6W0Xk9RFVR4ZleNo6fp5p36lJJ2ku3D-gdm8Jk8In6u-HQ4Kn5XM08uK5-exdOSK3Ajr4GmDNVCLztXnRsdUQ-77l_GXps1d8Q4vdpqdrNUsrYsKhbHOTndzh0hOtgs72ww28zaZPUVGcH1ITrog09t8QohS8E4V76sqpWQxdQ/s320/timetoinitialdisplay@2x%20_v2.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;

&lt;h3&gt;Testing &amp;amp; Tooling Upgrades&lt;/h3&gt;
&lt;h2&gt;Test Synchronization&lt;/h2&gt;
&lt;p&gt;Compose 1.12 introduces new test APIs designed to reduce test execution times and eliminate flakiness during state sampling:&lt;/p&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeUiTest#hasPendingWork()" target="_blank"&gt;hasPendingWork&lt;/a&gt;:&lt;/code&gt; Passively checks if the UI has pending work without advancing the clock, which is ideal for manual animation loops.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/test/ComposeUiTest#runWithoutImplicitWait(kotlin.Function0)"&gt;runWithoutImplicitWait&lt;/a&gt;:&lt;/code&gt; Temporarily disables implicit synchronization when stepping through manual clock frames (e.g. animation tests).&lt;/p&gt;&lt;/li&gt;

&lt;pre&gt;&lt;code&gt;@Test
fun testAnimationStateFast() {

composeTestRule.mainClock.autoAdvance = false
    
    while (composeTestRule.hasPendingWork()) {
        composeTestRule.mainClock.advanceTimeByFrame()
        composeTestRule.waitForIdle()
        
        composeTestRule.runOnUiThread {
            composeTestRule.runWithoutImplicitWait {
                // This is most effective when querying multiple nodes in a single frame. 
                // It prevents the redundant synchronization overhead that would 
                // otherwise occur on every individual query.
                val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
                val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
                
                assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Other notable changes:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;The &lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/test/package-summary#(androidx.compose.ui.test.SemanticsNodeInteraction).captureToImage()" target="_blank"&gt;captureToImage&lt;/a&gt;&lt;/code&gt; API now allows you to capture a popup or dialog together with its anchor in a single bitmap.&lt;/li&gt;
    &lt;li&gt;Added &lt;code&gt;&lt;a href="https://developer.android.com/develop/ui/compose/testing/interoperability#viewscoped-semantics" target="_blank"&gt;onRootWithViewInteraction&lt;/a&gt;&lt;/code&gt; to scope Compose semantic searches to specific Android Views. This simplifies testing hybrid UIs, such as RecyclerViews, without requiring unique test tags in production code.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href="https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewWrapper" target="_blank"&gt;@PreviewWrapper&lt;/a&gt;&lt;/code&gt; annotations can now be applied to custom &lt;code&gt;@MultiPreview&lt;/code&gt; classes, enabling reusable preview setups (such as custom themes) across multiple components.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Happy Composing!&lt;/h3&gt;
&lt;p&gt;Compose 1.12 makes app development easier and more expressive than ever, with mesh gradients, wide color gamut support, downloadable variable fonts, Credential Manager integration, and faster testing tools. As always, we value your input, so please share your feedback on these changes or what you'd like to see next on our &lt;a href="https://issuetracker.google.com/issues/new?component=612128"&gt;issue tracker&lt;/a&gt;. Happy composing!&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;</content><link href="http://android-developers.googleblog.com/feeds/8497185682650112021/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/jetpack-compose-august-2026-release.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8497185682650112021" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8497185682650112021" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/jetpack-compose-august-2026-release.html" rel="alternate" title="What's new in the Jetpack Compose August '26 release" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvR5TrjJE4Z1NMYxATN7zx3pmkOMm1lDAhV3u8h7RKVvQJzUsf2XJEwK7dY1b_d8eEEBvAV6wYIqtgKrh4xnkBv6EHGKr524At__nz0qbmlPNC402UFGtH1OrwlWtlxNB0XPRWdQd4FUwlaeOkOaDw-lCn47U_snuzIC-wZIaKkTceBrGcfCM8k2ifMsM/s72-c/Social%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-8539179489937049654</id><published>2026-08-11T09:00:00.000-07:00</published><updated>2026-08-12T06:59:53.780-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Audio"/><category scheme="http://www.blogger.com/atom/ns#" term="ExoPlayer"/><category scheme="http://www.blogger.com/atom/ns#" term="Jetpack"/><category scheme="http://www.blogger.com/atom/ns#" term="Media"/><category scheme="http://www.blogger.com/atom/ns#" term="media3"/><category scheme="http://www.blogger.com/atom/ns#" term="playback"/><category scheme="http://www.blogger.com/atom/ns#" term="Video"/><title type="text">Media3 1.11 - What's new?</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFmJ7cctYTrLDGDFhZpNbKvN_eKBf7y1UYhJuvp4yERf_-bWyK7kVYhqCxj0WrLcPBOA2C9Unj-Y1pyRtPShF_hNxmjvXVZAF198-Ci7YLOToR6Pxzblw0piXk0a4hyphenhyphenZeBlg_-lmUw-QY6b-F-Ej1R3ci_AJ0Mmk5x9HCOgL2n5tpqobgirOI5M3OgNQ/s2469/AFD%20-%20%5BABL_101%5D%20Media3%201.11%20is%20out%20_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFmJ7cctYTrLDGDFhZpNbKvN_eKBf7y1UYhJuvp4yERf_-bWyK7kVYhqCxj0WrLcPBOA2C9Unj-Y1pyRtPShF_hNxmjvXVZAF198-Ci7YLOToR6Pxzblw0piXk0a4hyphenhyphenZeBlg_-lmUw-QY6b-F-Ej1R3ci_AJ0Mmk5x9HCOgL2n5tpqobgirOI5M3OgNQ/s2469/AFD%20-%20%5BABL_101%5D%20Media3%201.11%20is%20out%20_Meta.png" style="display: none;" /&gt;
&lt;div&gt;&lt;i&gt;Posted by Toni Heidenreich, Software Engineer, Android&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_gJCo2h7iOyQG5LwWPBDlV9Qp6uUWCY887K1Ks_eueHtzJtCdDivF4nHillSk5Qklbt2-rDge9GTsKQuY1MrnWeI8g_C480HZkbfl8LH_tuAQXdxZO6DarMl0Uy9o0eQCmbR_ahBntC76eZAcUJPxey1Wsfsu59HmQ674guNEZS-OsctCNhuINFPtnEc/s8583/AFD%20-%20%5BABL_101%5D%20Media3%201.11%20is%20out%20_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_gJCo2h7iOyQG5LwWPBDlV9Qp6uUWCY887K1Ks_eueHtzJtCdDivF4nHillSk5Qklbt2-rDge9GTsKQuY1MrnWeI8g_C480HZkbfl8LH_tuAQXdxZO6DarMl0Uy9o0eQCmbR_ahBntC76eZAcUJPxey1Wsfsu59HmQ674guNEZS-OsctCNhuINFPtnEc/s1600/AFD%20-%20%5BABL_101%5D%20Media3%201.11%20is%20out%20_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;
  &lt;/p&gt;&lt;p&gt;Media3 1.11 is out. Powering the vast majority of top Android media apps, this release brings new features, bug fixes, and improvements across playback, editing, and UI components. We're expanding our Jetpack Compose UI modules with customizable &lt;code&gt;Player&lt;/code&gt; slots and easy to use defaults, interactive gestures, state observers, and short-form video preloading using &lt;code&gt;PlayerPool&lt;/code&gt;. We also modernized the Media3 Cast integration with SystemUI Output Switcher support, introduced a new Ktor HTTP client network extension, and added new muxing utilities for Ogg and WAV files.&lt;/p&gt;

  &lt;p&gt;Read on for key highlights, and check out the full &lt;a href="https://github.com/androidx/media/releases/tag/1.11.0" target="_blank"&gt;release notes&lt;/a&gt; for a comprehensive list of changes.&lt;/p&gt;

  &lt;h2&gt;Playback UI and Compose&lt;/h2&gt;
  &lt;p&gt;With Android becoming Compose-first, we are continuing to expand the &lt;code&gt;media3-ui-compose&lt;/code&gt; and &lt;code&gt;media3-ui-compose-material3&lt;/code&gt; modules. This update introduces more granular control over your player layout, richer interaction patterns, and deeper integration with Material3.&lt;/p&gt;

  &lt;h3&gt;Customizable Player layout&lt;/h3&gt;
  &lt;p&gt;The Material 3 Player Composable now supports dedicated content slots for &lt;code&gt;topControls&lt;/code&gt;, &lt;code&gt;centerControls&lt;/code&gt;, &lt;code&gt;bottomControls&lt;/code&gt;, and &lt;code&gt;errorOverlay&lt;/code&gt;. You can drop in your own Composables or use the ready-made defaults published in &lt;code&gt;PlayerDefaults&lt;/code&gt;:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;Player(
  player = player,
  topControls = { PlayerDefaults.TopControls(player) },
  centerControls = { PlayerDefaults.CenterControls(player) },
  bottomControls = { PlayerDefaults.BottomControls(player) },
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;Player&lt;/code&gt; Composable also integrates &lt;code&gt;FocusRequester&lt;/code&gt; support, enabling seamless D-pad and keyboard navigation on Android TV, foldables, and desktop environments.&amp;nbsp;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOvklguB2-POGNSBrDcol5m4qsdxyp4SSGOUbjMKL07MAqEcPYUeyn1WlaJ1erDJUFu9Snd7qdXfFUVJgmQtz5mmSO2dJSnftIyaph5FksrY0oxg5wgJAnL5ZTHzv_U-vCRo7nOA28616QfDcJnJ3ElB1W8NEmK2abtTMoXDiPPACKqqHtgdm1MtgK-74/s1064/player_video.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="848" data-original-width="1064" height="510" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOvklguB2-POGNSBrDcol5m4qsdxyp4SSGOUbjMKL07MAqEcPYUeyn1WlaJ1erDJUFu9Snd7qdXfFUVJgmQtz5mmSO2dJSnftIyaph5FksrY0oxg5wgJAnL5ZTHzv_U-vCRo7nOA28616QfDcJnJ3ElB1W8NEmK2abtTMoXDiPPACKqqHtgdm1MtgK-74/w640-h510/player_video.png" width="640" /&gt;&lt;/a&gt;&lt;span style="text-align: left;"&gt;Example for a Composable Player with customized controls&lt;/span&gt;&lt;/div&gt;

  &lt;h3&gt;Gestures and playback speed control&lt;/h3&gt;
  &lt;p&gt;&lt;code&gt;PlaybackSpeedState&lt;/code&gt; now provides a fast-forward/slow-motion API. The &lt;a href="https://github.com/androidx/media/tree/release/demos/compose" target="_blank"&gt;&lt;code&gt;demo-compose&lt;/code&gt; app&lt;/a&gt; showcases this with a long-press gesture to fast-forward playback and seeking with double tap. Combined with the &lt;code&gt;ProgressSlider&lt;/code&gt; introduced in 1.10, the Compose player UI now offers rich touch and gesture interactions out of the box.&lt;/p&gt;

  &lt;h3&gt;Short-form video preloading with PlayerPool&lt;/h3&gt;
  &lt;p&gt;For apps with sliding-window media feeds (for example, short-form vertical video), managing multiple ExoPlayer instances efficiently is a common challenge. Media3 1.11 introduces &lt;code&gt;PlayerPool&lt;/code&gt; (in &lt;code&gt;common-ktx&lt;/code&gt;) and &lt;code&gt;rememberPooledPlayer&lt;/code&gt; (in &lt;code&gt;ui-compose&lt;/code&gt;) to handle player recycling and preloading automatically.&lt;/p&gt;

  &lt;p&gt;The new &lt;code&gt;ShortFormPlayerScreen&lt;/code&gt; in &lt;code&gt;demo-compose&lt;/code&gt; shows this in action, a vertically paging feed where players are pooled, preloaded, and seamlessly recycled as the user scrolls.&lt;/p&gt;

  &lt;h3&gt;MiniController&lt;/h3&gt;
  &lt;p&gt;A new &lt;code&gt;MiniController&lt;/code&gt; Composable in &lt;code&gt;media3-ui-compose-material3&lt;/code&gt; provides a compact playback bar displaying the current item's title, artist, artwork, and progress alongside play/pause controls. As all our default Composables in &lt;code&gt;media3-ui-compose-material3&lt;/code&gt;, the &lt;code&gt;MiniController&lt;/code&gt; supports Material3 Dynamic Color integration, allowing it to automatically adapt to the user's wallpaper theme.This is ideal for persistent bottom-sheet or mini-player affordances, for example while the user browses content or during active Cast sessions.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5oaDCWuBtfos3_ynVEvQHwcV_G4cdziIk_0hO1Ws0taS0pRQdvvwGec51Kvh8en95V_8DcLqjCfGoPPM7mvyvSLLyUJn7mOp2qG6RK5I1mEcUHMe1HH3-7_MCSGWn2jKAojODVCSYYhIZVr8beSnLAXWdy3CD2VNzx4v997eYRfZIVVS_4cvROFGZF6o/s1080/mini_player.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="218" data-original-width="1080" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5oaDCWuBtfos3_ynVEvQHwcV_G4cdziIk_0hO1Ws0taS0pRQdvvwGec51Kvh8en95V_8DcLqjCfGoPPM7mvyvSLLyUJn7mOp2qG6RK5I1mEcUHMe1HH3-7_MCSGWn2jKAojODVCSYYhIZVr8beSnLAXWdy3CD2VNzx4v997eYRfZIVVS_4cvROFGZF6o/s1600/mini_player.png" /&gt;&lt;/a&gt;&lt;span style="text-align: left;"&gt;The Media3 MiniController showing album art, media metadata and basic controls&lt;/span&gt;&lt;/div&gt;

  &lt;h3&gt;Expanded state holders for metadata and errors&lt;/h3&gt;
  &lt;p&gt;We added several new reactive state holders to &lt;code&gt;media3-ui-compose&lt;/code&gt;:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;rememberCurrentMediaItemState&lt;/code&gt; – observe metadata about the currently playing item&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;rememberPlaylistState&lt;/code&gt; – observe the full playlist and active indices&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;rememberErrorState&lt;/code&gt; – track playback errors, with a matching &lt;code&gt;ErrorText&lt;/code&gt; Composable and default &lt;code&gt;ErrorOverlay&lt;/code&gt; in Material3&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;We'll continue working on new additions and more customization options in upcoming releases. Please share your thoughts on the &lt;a href="https://github.com/androidx/media/issues" target="_blank"&gt;project issue tracker&lt;/a&gt;.&lt;/p&gt;

  &lt;h2&gt;Modernized Cast integration&lt;/h2&gt;
  &lt;p&gt;Media3 1.11 updates the Cast extension with programmatic configuration options and support for OS-level routing.&lt;/p&gt;

  &lt;h3&gt;CastParams and SystemUI Output Switcher&lt;/h3&gt;
  &lt;p&gt;You can now configure the Cast extension using &lt;code&gt;CastParams&lt;/code&gt;:&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;val castParams = CastParams.Builder()
  .setShowSystemOutputSwitcherOnCastButtonClick(true)
  .build()

Cast.getSingletonInstance(context).initialize(castParams)&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;Setting &lt;code&gt;setShowSystemOutputSwitcherOnCastIconClick(true)&lt;/code&gt; configures the &lt;code&gt;MediaRouteButton&lt;/code&gt; to open Android's native SystemUI Output Switcher on supported platform versions, providing a unified output picker experience.&lt;/p&gt;

  &lt;h3&gt;Reactive MediaRouteButton state in Compose&lt;/h3&gt;
  &lt;p&gt;Apps using Jetpack Compose can now easily add the Media routing button (also known as Cast button), which automatically observes the dialog state and updates accordingly. No further logic needed when used together with Media3's &lt;code&gt;CastPlayer&lt;/code&gt;!&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;@Composable
fun TopAppBarWithCast() {
  Row {
    Text(text = "App Title")
    MediaRouteButton()
  }
}&lt;/code&gt;&lt;/pre&gt;

  &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidQ-Xe-lcSB9FXluhjtqdpynCjvU4WKxIHIxLJVHKDPHULzbV_gEhFckoVMhvdArTFNWI0673TcgpOLMDAPugEdxVbf4ZHn7b6LUnBf8cEwvLkIE1MNtw3wq0xiaQLYGSoxYm6Vt98GebZJeX2vL4S1EjrBfLwTvpLg9Pv44gY9JKiKvxNlEni-uf0kaE/s3230/cast_button_2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="861" data-original-width="3230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidQ-Xe-lcSB9FXluhjtqdpynCjvU4WKxIHIxLJVHKDPHULzbV_gEhFckoVMhvdArTFNWI0673TcgpOLMDAPugEdxVbf4ZHn7b6LUnBf8cEwvLkIE1MNtw3wq0xiaQLYGSoxYm6Vt98GebZJeX2vL4S1EjrBfLwTvpLg9Pv44gY9JKiKvxNlEni-uf0kaE/s1600/cast_button_2.png" /&gt;&lt;/a&gt;&lt;span style="text-align: left;"&gt;Media3 media route button in an app launching the default output switcher dialog&lt;/span&gt;&lt;/div&gt;

  &lt;h2&gt;Core playback and session enhancements&lt;/h2&gt;
  &lt;h3&gt;Eclipsa Video - HAGC dynamic HDR metadata (API 37+)&lt;/h3&gt;
  &lt;p&gt;&lt;a href="https://developer.android.com/blog/posts/eclipsa-video-hdr-that-looks-right-on-every-screen" target="_blank"&gt;Eclipsa Video&lt;/a&gt; promises a more consistent HDR experience across devices, with a consistent baseline HDR white, adaptive headroom depending on the screen and the surroundings, ensuring the creative intent is preserved on all devices.&lt;/p&gt;

  &lt;p&gt;ExoPlayer now supports playback of the necessary HAGC (ST 2094-50) timed metadata for progressive media (MP4, Matroska). The player automatically merges HAGC metadata tracks with the associated video track and delivers the metadata out-of-band to the decoder on API 37+ devices. On older devices, ExoPlayer seamlessly falls back to providing a standard HDR playback experience without the adjustments.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggfp9FGFl6dWGw7EO8JUA1m56Y4TZBb9Yw7nUN3cBH2AVsTtewmAUsAflgQvAgAahMQLi4KJn0g8iD7GjKK103WwlKdJ7ID5RR0iYFl0-ddSaJoTtr4rGsJI6W2CIAwv9jpBHIPZ_AJvqZb6j7q2lcZe6Snp25x36zsioh5QzQqXDhoawr17m4CyQV-48/s1288/eclipsa.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="450" data-original-width="1288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggfp9FGFl6dWGw7EO8JUA1m56Y4TZBb9Yw7nUN3cBH2AVsTtewmAUsAflgQvAgAahMQLi4KJn0g8iD7GjKK103WwlKdJ7ID5RR0iYFl0-ddSaJoTtr4rGsJI6W2CIAwv9jpBHIPZ_AJvqZb6j7q2lcZe6Snp25x36zsioh5QzQqXDhoawr17m4CyQV-48/s1600/eclipsa.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span style="text-align: left;"&gt;Illustration to show benefits of Eclipsa Video HDR, like more consistent color contract&lt;/span&gt;&lt;/div&gt;

  &lt;h3&gt;New Ktor HTTP client extension&lt;/h3&gt;
  &lt;p&gt;A new &lt;code&gt;media3-datasource-ktor&lt;/code&gt; extension module provides &lt;code&gt;KtorDataSource&lt;/code&gt;, backed by the &lt;a href="https://ktor.io/" target="_blank"&gt;Ktor&lt;/a&gt; HTTP stack. This offers a Kotlin-first, coroutine-friendly alternative to the existing Cronet and OkHttp data source modules.&lt;/p&gt;

  &lt;h3&gt;Asynchronous MediaSession connections&lt;/h3&gt;
  &lt;p&gt;&lt;code&gt;MediaSession.Callback&lt;/code&gt; now includes &lt;code&gt;onConnectAsync()&lt;/code&gt;, which lets you process controller connection attempts asynchronously — for example, to verify authorization before accepting a connection. You can return an immediate Future with &lt;code&gt;Futures.immediateFuture(ConnectionResult)&lt;/code&gt; for the same behavior as the existing &lt;code&gt;onConnect&lt;/code&gt;.&lt;/p&gt;

  &lt;pre&gt;&lt;code&gt;override fun onConnectAsync(
  session: MediaSession,
  controller: MediaSession.ControllerInfo
): ListenableFuture&amp;lt;MediaSession.ConnectionResult&amp;gt; {
  return authenticateControllerAsync(controller)
}&lt;/code&gt;&lt;/pre&gt;

  &lt;h3&gt;Safer MediaSession defaults&lt;/h3&gt;
  &lt;p&gt;For apps that don’t override &lt;code&gt;onConnect&lt;/code&gt; or &lt;code&gt;onConnectAsync&lt;/code&gt; in &lt;code&gt;MediaSession.Callback&lt;/code&gt;, the library now defaults to a more secure configuration. Specifically, session data is no longer shared by default with untrusted controllers, meaning third-party or non-system apps lacking notification access are restricted from accessing session data unless you explicitly implement these callback methods to authorize the connection.&lt;/p&gt;

  &lt;h2&gt;New Muxer implementations &amp;amp; container parsing&lt;/h2&gt;
  &lt;h3&gt;OggMuxer and WavMuxer&lt;/h3&gt;
  &lt;p&gt;We've added two new dedicated muxers: &lt;code&gt;OggMuxer&lt;/code&gt; for muxing OPUS and VORBIS streams into standard .ogg files, and &lt;code&gt;WavMuxer&lt;/code&gt; for generating uncompressed and floating-point PCM .wav audio files.&lt;/p&gt;

  &lt;h3&gt;Container parsing and track references&lt;/h3&gt;
  &lt;ul&gt;
    &lt;li&gt;MP4 Track References (tref): &lt;code&gt;Mp4Muxer.addTrackReference&lt;/code&gt; allows linking dependent metadata or aux tracks to primary video streams.&lt;/li&gt;
    &lt;li&gt;Chapter Extraction: QuickTime and Nero chapter from MP4 files (.m4a, .m4b), and Matroska chapters, are now extracted as Chapter metadata entries for audiobook and podcast navigation.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;Please use the &lt;a href="https://github.com/androidx/media/issues" target="_blank"&gt;issue tracker&lt;/a&gt; to report any bugs, or if you have questions or feature requests. We look forward to hearing from you!&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/8539179489937049654/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/media3-1-11-whats-new.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8539179489937049654" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8539179489937049654" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/media3-1-11-whats-new.html" rel="alternate" title="Media3 1.11 - What's new?" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFmJ7cctYTrLDGDFhZpNbKvN_eKBf7y1UYhJuvp4yERf_-bWyK7kVYhqCxj0WrLcPBOA2C9Unj-Y1pyRtPShF_hNxmjvXVZAF198-Ci7YLOToR6Pxzblw0piXk0a4hyphenhyphenZeBlg_-lmUw-QY6b-F-Ej1R3ci_AJ0Mmk5x9HCOgL2n5tpqobgirOI5M3OgNQ/s72-c/AFD%20-%20%5BABL_101%5D%20Media3%201.11%20is%20out%20_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-8100987187420918726</id><published>2026-08-06T09:00:00.000-07:00</published><updated>2026-08-06T09:02:37.620-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AI-assisted coding"/><category scheme="http://www.blogger.com/atom/ns#" term="Android skills"/><title type="text">Inside Android Skills - Built for deprecation</title><content type="html">&lt;i&gt;Posted by Jose Alcérreca, Developer Relations Engineer, Android Developer Relations&lt;/i&gt;&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8ln8L4mIkAKvPGo4pncpuh0f3-nhaEgXAqmsg2-QiDpkz0Bfowftt9pZJZxvgK78Eg5JXrvqdfvtiP7y7_MsGNhAAuZGy1ExKE01KfZisOs_0hCeCodS0v-bmQJA1WQO7k3tbeUUrRZjQM-mHbPECDLoQa1OmqqORsLJXF8ge0gB5MzV8gl5eIiUJBI0/s8659/Inside%20Android%20Skills%20-%20Built%20for%20deprecation_Blog_V01.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2765" data-original-width="8659" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8ln8L4mIkAKvPGo4pncpuh0f3-nhaEgXAqmsg2-QiDpkz0Bfowftt9pZJZxvgK78Eg5JXrvqdfvtiP7y7_MsGNhAAuZGy1ExKE01KfZisOs_0hCeCodS0v-bmQJA1WQO7k3tbeUUrRZjQM-mHbPECDLoQa1OmqqORsLJXF8ge0gB5MzV8gl5eIiUJBI0/s1600/Inside%20Android%20Skills%20-%20Built%20for%20deprecation_Blog_V01.png" /&gt;&lt;/a&gt;We released the official &lt;a href="https://github.com/android/skills" target="_blank"&gt;Android Skills&lt;/a&gt; in April, and the response surpassed all our expectations. In this blog post, I'll address some of the feedback we received, explaining the philosophy and methodology behind the project. Hopefully, this will also help you understand what happens behind the scenes when you install and use skills, allowing you to make better use of tokens and your own time.&lt;/p&gt;

&lt;h2&gt;Why are there so few official skills?&lt;/h2&gt;
&lt;p&gt;Currently, we only consider new skills when there's a verifiable knowledge gap in state-of-the-art (SOTA) models. Put simply: you don't need to teach the model what it already knows. (Though there are a few exceptions—read on!)&lt;/p&gt;

&lt;p&gt;We’ve released around 20 official skills so far, and they intentionally target highly specific, fast-moving areas that standard models aren't fully grounded on yet—things like AGP 9, Navigation 3, advanced Camera APIs, and Perfetto SQL.&lt;/p&gt;

&lt;p&gt;What about core, more general, skills? Every installed skill injects 100–200 tokens into the baseline context of every task you start. If that skill actually activates, that count can quickly jump into the thousands. In most cases, hoarding basic skills is both counterproductive and expensive. Before installing a skill for writing basic Kotlin or Compose, consider if your LLM of choice really needs it, or if it knows those topics well enough already.&lt;/p&gt;

&lt;h2&gt;Evaluating skills&lt;/h2&gt;
&lt;p&gt;Before their release, each skill is tested against a comprehensive set of evals that prove that the skill delivers clear value. These evals should pass when the skill is active, and fail otherwise. Evals are to skills what integration tests are to code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;timeout_s: 1200
repository:
  url: [redacted - internal git repo]
  working_dir: wear_compose_m3_empty_app
category_ids:
  - wear
prompt: |-
  Add a horizontal pager to MainActivity.kt. Have three pages in the pager. Each page should contain
  the text "Page 1", "Page 2", and "Page 3" respectively in the center of the screen.
commands:
  build:
    - ./gradlew assembleDebug
acceptance_criteria:
  project_builds: true
  llm_diff_judge:
    - Must use `HorizontalPagerScaffold`.
    - Each page should use `AnimatedPage` to wrap a `ScreenScaffold`.&lt;/code&gt;&lt;/pre&gt;

&lt;p style="text-align: center;"&gt;&lt;em&gt;Example eval that checks the correct implementation of a horizontal pager on a wear app&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At a minimum, we test the skill in Android Studio using the latest Gemini Flash model. Depending on the skill, we also ensure compatibility with other models such as Gemini Pro and other agents such as Antigravity, and third-party systems.&lt;/p&gt;

&lt;p&gt;All of the evals run with access to the &lt;a href="https://developer.android.com/studio/gemini/access-helpful-resources#android-knowledge-base" target="_blank"&gt;Knowledge Base&lt;/a&gt;, so if the information is in the documentation, and models decide to search for it, we don't publish a skill for it.&lt;/p&gt;

&lt;h2&gt;Using the Android Knowledge Base (Android Studio or Android CLI)&lt;/h2&gt;
&lt;p&gt;If you develop Android apps, you should always use the Android Knowledge Base to have access to the official documentation. If you use the agent in Android Studio, it's already available as a tool, but if you use another agent, &lt;a href="https://developer.android.com/tools/agents" target="_blank"&gt;install Android CLI&lt;/a&gt;. Among other things, it contains the docs command, which gives your agent access to the official Android documentation. Having a single tool is much more efficient than installing hundreds of skills.&lt;/p&gt;

&lt;p&gt;If your model is acting overconfident, and you want it to consult the documentation more often, a very common way to motivate it is to add "Always consult the official Android documentation when dealing with Android APIs" to your AGENTS.md file or equivalent. Of course, you can also force this by asking the agent to check the documentation directly in your prompts.&lt;/p&gt;

&lt;h2&gt;Why are pull requests disabled?&lt;/h2&gt;
&lt;p&gt;Because our evaluation framework depends on internal infrastructure that cannot be open-sourced, we are unable to accept direct pull requests for new skills—without this infrastructure, we would have no way to re-evaluate incoming PR changes. However, we actively monitor community feedback. If you want to report a bug, suggest an optimization, or request a new official skill, please file an &lt;a href="https://github.com/android/skills/issues" target="_blank"&gt;issue&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;When do core or basic skills make sense?&lt;/h2&gt;
&lt;p&gt;While SOTA models generally don't need basic skills, there are some scenarios where enabling core or community-built skills adds real value. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;You're using vague prompts:&lt;/strong&gt; Skills amplify your intent. If you give a loose prompt like "add animations to this screen," a specific Compose animation skill can inspire the model, pushing it toward modern APIs or screenshot testing patterns it might not have otherwise considered.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;You want to use smaller, cheaper models:&lt;/strong&gt; Frontier LLMs are expensive. If you are offloading routine tasks to smaller open-weight models like Gemma 4, enabling basic skills fills the knowledge gaps that smaller parameters miss.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;You're refactoring or reviewing legacy code:&lt;/strong&gt; Models excel at generating code that works, but when editing old codebases, they often prioritize staying consistent with the surrounding legacy patterns over rewriting things with modern accuracy. A specialized reviewer agent equipped with core skills can help break that habit.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;You deviate from the norm:&lt;/strong&gt; LLMs love the standard "Google way" of architecting Android apps. If your team uses a highly customized view-layer architecture, the model will struggle to stay aligned. A custom skill explicitly describing your architecture goes a long way.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Where can I find core skills?&lt;/h2&gt;
&lt;p&gt;The Android community has your back. Chris Banes has &lt;a href="https://github.com/chrisbanes/skills" target="_blank"&gt;a comprehensive collection of skills for Compose and Kotlin&lt;/a&gt;, Ivan Morgillo published &lt;a href="https://github.com/hamen/compose_skill" target="_blank"&gt;a skill that audits Compose projects&lt;/a&gt;, and Jaewoong Eum created two on &lt;a href="https://github.com/skydoves/compose-performance-skills" target="_blank"&gt;testing&lt;/a&gt; and &lt;a href="https://github.com/skydoves/compose-performance-skills" target="_blank"&gt;performance&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Always download skills from reputable sources! I personally wouldn't trust repositories containing dozens or hundreds of Android skills as they're probably AI-generated and untested, and they could even contain malicious or biased instructions. Also, don't install general software engineering skills blindly; a lot of them are tailored for web development.&lt;/p&gt;

&lt;h2&gt;Goal: deprecation&lt;/h2&gt;
&lt;p&gt;Loosely paraphrasing Karpathy: Skills of today will be in the models of tomorrow. As SOTA models keep improving, we expect skills to be obsolete, especially those built around new APIs. To figure out when to retire them, we run our evals when new models drop. If they pass, we'll keep them around for a few months until most users have transitioned over.&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/8100987187420918726/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/android-skills-philosophy.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8100987187420918726" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8100987187420918726" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/08/android-skills-philosophy.html" rel="alternate" title="Inside Android Skills - Built for deprecation" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8ln8L4mIkAKvPGo4pncpuh0f3-nhaEgXAqmsg2-QiDpkz0Bfowftt9pZJZxvgK78Eg5JXrvqdfvtiP7y7_MsGNhAAuZGy1ExKE01KfZisOs_0hCeCodS0v-bmQJA1WQO7k3tbeUUrRZjQM-mHbPECDLoQa1OmqqORsLJXF8ge0gB5MzV8gl5eIiUJBI0/s72-c/Inside%20Android%20Skills%20-%20Built%20for%20deprecation_Blog_V01.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-4296509647035928483</id><published>2026-07-29T06:00:00.000-07:00</published><updated>2026-07-29T11:28:04.581-07:00</updated><title type="text">Delivering safer, age-appropriate experiences on Google Play</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Em0UEKqDqhBIensqI38iULJEsiDOwA6nhPMuJHDAlX2PO-t4D_23woJNm_YFcijJCszieB98dpJi7sNgNpqe5tunH9Cr5O6M1YAMHMhEpB_O-Hoq14a1Yw4oFvuopsDkn719Bu6s4NR0BSfOcsN3DQpfsO1HW-TGpv3FTYk2eINnH-smtlNf8ihOVr0/s2048/Google-Play-Age-Signals-API-Blog-Metadata.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Em0UEKqDqhBIensqI38iULJEsiDOwA6nhPMuJHDAlX2PO-t4D_23woJNm_YFcijJCszieB98dpJi7sNgNpqe5tunH9Cr5O6M1YAMHMhEpB_O-Hoq14a1Yw4oFvuopsDkn719Bu6s4NR0BSfOcsN3DQpfsO1HW-TGpv3FTYk2eINnH-smtlNf8ihOVr0/s2048/Google-Play-Age-Signals-API-Blog-Metadata.png" style="display: none;" /&gt;&lt;div&gt;&lt;i&gt;Posted by Paul Feng, VP of Product Management, Google Play&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCpyp7yWQ-4XkfYfI6bwCUkYoNP1_XpR7xhhC52pwFsyohWxu4pegX6w23S_ZKHj8aENsVN4c1dCJvXrWmVNIeH0dUvyOVTeFvfAWg7TDzjv4BdV-wwUWVmT9MBVYMBBvkG4ZeEQrJelf3i4Rzxy5_Jk0bXpV73XHmk78UQOrUkP13cq5XvOLqTsCAM3I/s4209/Google-Play-Age-Signals-API-Blog-A.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCpyp7yWQ-4XkfYfI6bwCUkYoNP1_XpR7xhhC52pwFsyohWxu4pegX6w23S_ZKHj8aENsVN4c1dCJvXrWmVNIeH0dUvyOVTeFvfAWg7TDzjv4BdV-wwUWVmT9MBVYMBBvkG4ZeEQrJelf3i4Rzxy5_Jk0bXpV73XHmk78UQOrUkP13cq5XvOLqTsCAM3I/s1600/Google-Play-Age-Signals-API-Blog-A.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Providing a safe online experience and protecting users from harm is a top priority at Google Play. We take this responsibility seriously and have been investing continuously to offer baseline protections on our platform while also empowering parents with the tools they need to make decisions for their families. Importantly, we also want to empower Play developers with the capabilities to deliver age-appropriate experiences based on their app's content.&lt;/p&gt;

&lt;p&gt;To support this, today, we are taking another big step in our ongoing partnership with parents and developers by announcing the expansion of the &lt;a href="https://developer.android.com/google/play/age-signals/overview" target="_blank"&gt;Google Play Age Signals API &lt;/a&gt;to all Play developers globally. Building on current availability in Brazil, we will expand this experience first to users in Australia and Canada by mid-August, with a full global rollout to all users later this year.&lt;/p&gt;

&lt;h2&gt;Empowering developers to create age-appropriate experiences&lt;/h2&gt;

&lt;p&gt;The Play Age Signals API is a privacy-preserving tool that puts parents in the driver's seat allowing them to share their child's age range (e.g. 16-17) directly with apps. It also enables adults to easily share their age when prompted by the app developer. In turn, developers receive the signals they need to tailor their own in-app safety experiences and content for users in an age-appropriate way.&lt;/p&gt;

&lt;p&gt;We want to give developers the ability to choose the right protections for the nature of their app. A weather app, for example, shouldn't need the same safety settings as entertainment or media apps. Rather than enforcing one-size-fits-all rules, we give developers the flexibility to choose how they integrate safety signals. With this reliable signal, you retain complete agency to tailor your app's content, features, and settings to match your audience.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWX2huHl1jcWSRmn2YiJaYQ0v8Y_U5HpHJ3o0RvlAf3XPr_tADCW17wCgQjp7g9gBbS0iYETcbReZco_jDbpO8FvEmC6bRugSs6zL8uHGWd7KG1RuT28c6Cyi2D_Tt33ZuIB1imLgGZsiZ7hSS-Fm_deQy2XVmeH76S2naCAmYgJMHLlZ33aNDSSUaqAE/s1924/Production_InApp%20(1).png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1924" data-original-width="1424" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWX2huHl1jcWSRmn2YiJaYQ0v8Y_U5HpHJ3o0RvlAf3XPr_tADCW17wCgQjp7g9gBbS0iYETcbReZco_jDbpO8FvEmC6bRugSs6zL8uHGWd7KG1RuT28c6Cyi2D_Tt33ZuIB1imLgGZsiZ7hSS-Fm_deQy2XVmeH76S2naCAmYgJMHLlZ33aNDSSUaqAE/w296-h400/Production_InApp%20(1).png" width="296" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;Users have a choice to share their age range in a privacy-friendly way&lt;/i&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;Simplifying controls for parents&lt;/h2&gt;

&lt;p&gt;Parents shouldn't have to manage complex safety settings across dozens of different apps to keep their children safe. The Play Age Signals API simplifies this by putting age-sharing controls in one place, directly inside the &lt;a href="https://families.google/"&gt;Google Family Link app&lt;/a&gt;. Parents have a choice to share their child’s age range, and if they choose to share, all Play apps that use Play Age Signals API can receive age signals. This lets children jump straight into age-appropriate content without parents having to manually configure settings inside these apps. Age ranges are never shared by default, and parents can update or turn off these settings at any time.&lt;br /&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6VNiLBGhSTQeC09ObM-U8nF6oJjSSDfYy3fJLAzVBgrJn-0_tGtNJN7Hefp2eUFr1b7CmOvirjVkAGSGSwIT7uV_Hu2xb2714_938t_XLuDUr2MqZdnSfBRvheoUpu5i-dyYiAjJi5vNNLcGWrQuKXBNOhtbWplwNbNkqzbirwDCitzHdF9gTAFFGtFU/s3672/FL_Settings%20(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="3672" data-original-width="1664" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6VNiLBGhSTQeC09ObM-U8nF6oJjSSDfYy3fJLAzVBgrJn-0_tGtNJN7Hefp2eUFr1b7CmOvirjVkAGSGSwIT7uV_Hu2xb2714_938t_XLuDUr2MqZdnSfBRvheoUpu5i-dyYiAjJi5vNNLcGWrQuKXBNOhtbWplwNbNkqzbirwDCitzHdF9gTAFFGtFU/w290-h640/FL_Settings%20(1).png" width="290" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;Centralized and easy way to manage age sharing settings for parents via Family Link App&lt;/i&gt;&lt;/div&gt;

&lt;h2&gt;Building on our broader safety tools&lt;/h2&gt;

&lt;p&gt;The Play Age Signals API builds upon a strong foundation of established safety features and strict policies we have long enforced on Google Play. Today, we already mandate that apps designed for families meet &lt;a href=" https://support.google.com/googleplay/android-developer/answer/9893335?hl=en"&gt;rigorous safety standards&lt;/a&gt;, and we continuously review and scan applications to ensure they are safe for children. For developers, we also offer built-in tools like &lt;a href="https://support.google.com/googleplay/android-developer/answer/9867159#age-groups-18-and-over" target="_blank"&gt;Restrict Minor Access&lt;/a&gt; in the Play Console to help them manage who can discover their apps. For parents, Google Family Link remains a trusted, central dashboard where they can manage screen-time limits, &lt;a href="https://support.google.com/googleplay/answer/1075738" target="_blank"&gt;PIN-based content filters&lt;/a&gt;, and app download approvals.&lt;/p&gt;

&lt;p&gt;Expanding the Play Age Signals API globally adds a powerful new tool to our existing safety suite, helping parents and developers work together to make Google Play an even safer, more trustworthy place for families.&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;</content><link href="http://android-developers.googleblog.com/feeds/4296509647035928483/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/google-play-age-signals-api-safer-experiences.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/4296509647035928483" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/4296509647035928483" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/google-play-age-signals-api-safer-experiences.html" rel="alternate" title="Delivering safer, age-appropriate experiences on Google Play" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Em0UEKqDqhBIensqI38iULJEsiDOwA6nhPMuJHDAlX2PO-t4D_23woJNm_YFcijJCszieB98dpJi7sNgNpqe5tunH9Cr5O6M1YAMHMhEpB_O-Hoq14a1Yw4oFvuopsDkn719Bu6s4NR0BSfOcsN3DQpfsO1HW-TGpv3FTYk2eINnH-smtlNf8ihOVr0/s72-c/Google-Play-Age-Signals-API-Blog-Metadata.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-8693766666920532872</id><published>2026-07-28T09:00:00.000-07:00</published><updated>2026-07-30T07:41:41.322-07:00</updated><title type="text">Celebrating 5 years of Jetpack Compose</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqdSbNmK_9vJR4DQPvGN0oUtQK8s0T2HsgPAsNsl9Kqvd49M3ODh7wlGPZrCRVHEC30oArKNrqmLtuO-zwoZHkfN3_AQz2NNBG6S1st34TOCYx9Mu9cM-ut-rSN8-U1o9Q4ufBwY1l3ukPRjw8QxHWdpxAeeoKRVDPvEjysPwORA3TRhbtpMyTctDQsdY/s320/Jetpack%20compose_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqdSbNmK_9vJR4DQPvGN0oUtQK8s0T2HsgPAsNsl9Kqvd49M3ODh7wlGPZrCRVHEC30oArKNrqmLtuO-zwoZHkfN3_AQz2NNBG6S1st34TOCYx9Mu9cM-ut-rSN8-U1o9Q4ufBwY1l3ukPRjw8QxHWdpxAeeoKRVDPvEjysPwORA3TRhbtpMyTctDQsdY/s320/Jetpack%20compose_Meta.png" style="display: none;" /&gt;Posted by Rebecca Franks, Developer Relations Engineer, Nick Butcher, Product Manager, Loryn Hairston, Product Marketing Manager, Android&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw3DKaw8qASt6AVjsnSTjRqXf81sJAoY9cVQ84H5nyPhcSCrQpsCqGMqt_xHvvCcr5AiUjgOkenszO-Gv0iDi_jvrzXuetPHwRkiNDNXTSF3HAS5q1OMGY7_iHxQMt77_7TvYiNFZGrJSNw6_RrepymprGBh4T1vk11NPgp11l8jd9pUv8CD78jqWjr_I/s8419/Jetpack%20compose_Blog%20banner.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2507" data-original-width="8419" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw3DKaw8qASt6AVjsnSTjRqXf81sJAoY9cVQ84H5nyPhcSCrQpsCqGMqt_xHvvCcr5AiUjgOkenszO-Gv0iDi_jvrzXuetPHwRkiNDNXTSF3HAS5q1OMGY7_iHxQMt77_7TvYiNFZGrJSNw6_RrepymprGBh4T1vk11NPgp11l8jd9pUv8CD78jqWjr_I/s1600/Jetpack%20compose_Blog%20banner.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Today, we officially celebrate five years since the release of Jetpack Compose 1.0. From version &lt;a href="https://android-developers.googleblog.com/2021/07/jetpack-compose-announcement.html" target="_blank"&gt;1.0, announced on July 28th, 2021&lt;/a&gt;, to our latest &lt;a href="https://android-developers.googleblog.com/2026/04/jetpack-compose-april-2026-updates.html" target="_blank"&gt;1.11 release&lt;/a&gt;, we’ve seen the APIs evolve significantly over the years, and we’re taking a moment to celebrate.&lt;/p&gt;

&lt;p&gt;When we officially announced the 1.0 release, we promised a simpler, faster, and more intuitive way to build native interfaces on Android. Looking back, it's safe to say that Compose didn’t just deliver on that promise, but also completely changed the Android ecosystem, with more than 68% of the top 1,000 apps using it in production today.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;"&gt;
  &lt;iframe 
    src="https://www.youtube.com/embed/6qyCXugCU6w" 
    class="BLOG_video_class" 
    allowfullscreen="" 
    youtube-src-id="6qyCXugCU6w"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;p&gt;Over the last five years, Compose has grown steadily. In the &lt;a href="https://www.youtube.com/watch?v=VsStyq4Lzxo"&gt;early days&lt;/a&gt;,  we explored showing you how to build layouts with the basic Box, Row, and Column. Today, we’ve expanded Compose to work not just on mobile devices, but to other form factors such as &lt;a href="https://developer.android.com/training/tv/playback/compose"&gt;Compose for TV&lt;/a&gt;, &lt;a href="https://developer.android.com/training/wearables/compose?version=3"&gt;WearOS&lt;/a&gt;, &lt;a href="https://developer.android.com/develop/ui/compose/glance"&gt;Glance for Widgets&lt;/a&gt;, and even display glasses with &lt;a href="https://developer.android.com/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer"&gt;Jetpack Compose Glimmer&lt;/a&gt;.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWh8CsCAq-H6bDDYNx7rg-C2Ok49rbVuMXWelUJhj-jivPZl-ZsSyoJuyisNxqvWCsiMCYvpdOAgGXG1Fqm8JLhkDr8iwD0leU8U_Yi3C-eW6Yqk-Gdp4AhgrpIIoUzETs0bTNNLmZRPiLzNPph9yA7hRCTm0-WDhsZu70dDYMX2uPwuVG50Sm8Ra8fko/s1999/jetpack_compose_everywhere.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="743" data-original-width="1999" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWh8CsCAq-H6bDDYNx7rg-C2Ok49rbVuMXWelUJhj-jivPZl-ZsSyoJuyisNxqvWCsiMCYvpdOAgGXG1Fqm8JLhkDr8iwD0leU8U_Yi3C-eW6Yqk-Gdp4AhgrpIIoUzETs0bTNNLmZRPiLzNPph9yA7hRCTm0-WDhsZu70dDYMX2uPwuVG50Sm8Ra8fko/s1600/jetpack_compose_everywhere.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;We recorded an Android Developers Backstage episode with &lt;a href="https://uk.linkedin.com/in/clara-bayarri-815b7333"&gt;Clara Bayarri&lt;/a&gt;, Engineering Lead for Jetpack, and two former leads of the team, &lt;a href="https://www.romainguy.dev/"&gt;Romain Guy&lt;/a&gt; and &lt;a href="https://www.chethaase.com/"&gt;Chet Haase&lt;/a&gt;, along with &lt;a href="https://www.linkedin.com/in/tor-norbye"&gt;Tor Norbye&lt;/a&gt;, Senior Engineering Director. In this episode, they discuss the history of Compose and the early days of development.&lt;/p&gt;&lt;div class="separator" style="clear: both;"&gt;
&lt;div class="separator" style="clear: both; text-align: center; width: 100%;"&gt;
  &lt;div style="height: 0px; max-width: 100%; overflow: hidden; padding-bottom: 56.25%; position: relative;"&gt;
    &lt;iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/HEqXwUm6vd0" style="border: 0; height: 100%; left: 0; position: absolute; top: 0; width: 100%;" width="320" youtube-src-id="HEqXwUm6vd0"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjASmtolyBoNVHRjLZlHPzpVlJPfXuw4eKAphJtUQWYE0JOMbboZSL9nmyyBnsOTtHXDxpD0guDehRU7hBnGN1kR0D3zP7MVb75f1ldqlv2Xe6QQVVrr4zDRDKrpbSJ3xzp99O9tK-sMnxKynzH2MPe5HU3C5RS2g2kiz3Hf0BKIwsEy207YS2oesGTBsw/s3200/timeline.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1200" data-original-width="3200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjASmtolyBoNVHRjLZlHPzpVlJPfXuw4eKAphJtUQWYE0JOMbboZSL9nmyyBnsOTtHXDxpD0guDehRU7hBnGN1kR0D3zP7MVb75f1ldqlv2Xe6QQVVrr4zDRDKrpbSJ3xzp99O9tK-sMnxKynzH2MPe5HU3C5RS2g2kiz3Hf0BKIwsEy207YS2oesGTBsw/s1600/timeline.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;i&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;Compose highlights over the years&lt;/i&gt;&lt;/div&gt;&lt;/i&gt;&lt;h2 style="text-align: left;"&gt;Looking back&lt;/h2&gt;&lt;p style="text-align: left;"&gt;The beginnings of Compose were very different from what you know today. Two projects were happening in parallel inside the Android team.&lt;/p&gt;

&lt;p style="text-align: left;"&gt;At the time, the Views toolkit team was thinking of unbundling the UI Toolkit into a library to help with development speed, and make it easier for developers to adopt and control updates. Meanwhile, a team was working on a novel idea to build declarative layouts by embedding XML inside Kotlin, which looked something like this:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2MclbgogkD1Ofd5aD6Y1SuoWOQM_Yp7kJHGwxWZ1VMPsH8xxe7BHRUFXQgZqGzyECAvwSHkh9ZAk7350DxuzGyKQkkzqzMTnoWMycVuTXnmZ17WHRS9PHHst-mcA2_D_ofSdOVvxHWv8J3b4i92qZ5jJCvOUigN3Vmh4mHFSEnZtsi9DRRkMfQIgg6h8/s2560/jetpack_compose_early_code.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1440" data-original-width="2560" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2MclbgogkD1Ofd5aD6Y1SuoWOQM_Yp7kJHGwxWZ1VMPsH8xxe7BHRUFXQgZqGzyECAvwSHkh9ZAk7350DxuzGyKQkkzqzMTnoWMycVuTXnmZ17WHRS9PHHst-mcA2_D_ofSdOVvxHWv8J3b4i92qZ5jJCvOUigN3Vmh4mHFSEnZtsi9DRRkMfQIgg6h8/s1600/jetpack_compose_early_code.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p style="text-align: left;"&gt;Those two efforts merged to produce what you know today - a fully declarative UI Toolkit that utilizes the power of a compiler plugin, runtime, and Kotlin:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@Composable
fun Newsfeed(stories: List&amp;lt;Story&amp;gt;) {
    LazyColumn {
        items(stories) { story -&amp;gt;
            Card {
                val author = story.author
                Image(painterResource(author.profilePhoto),
                    contentDescription = author.name)
                Text(author.name)
                Text(story.content)
                if (story.hasCommentsEnabled()) {
                    for(comment in story.comments) {
                        Text(comment.mainContent)
                    }
                }
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p style="text-align: left;"&gt;And you, the community, helped us very early on! Before 2021, Compose had a pre-alpha phase, which helped ensure Compose was fit to solve the problems of our developers.&lt;/p&gt;

&lt;p style="text-align: left;"&gt;One of our favorite memories is the Android Dev Challenge. We challenged the community to build four different tasks with Compose, filling our feeds with Puppy apps, clocks, and weather apps, and giving us a ton of direct feedback that helped shape the 1.0 release.&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center; width: 100%;"&gt;
  &lt;div style="height: 0px; max-width: 100%; overflow: hidden; padding-bottom: 56.25%; position: relative;"&gt;
    &lt;iframe allowfullscreen="" class="BLOG_video_class" height="266" src="https://www.youtube.com/embed/9AAmOcgdA2s" style="border: 0; height: 100%; left: 0; position: absolute; top: 0; width: 100%;" width="320" youtube-src-id="9AAmOcgdA2s"&gt;&lt;/iframe&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p style="text-align: left;"&gt;Compose has continued to evolve, from launching with a set of Material 2 components to now supporting &lt;a href="https://m3.material.io/blog/building-with-m3-expressive" target="_blank"&gt;Material 3 Expressive&lt;/a&gt;.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXwWhSDIyKO9B9ZUFvjOiIvotw-uC2maZp71vl3qC8GFk01I_xg00AY0JtqZHtAsRofj2G8i-zNG9odM31EWc4mGs00kTvjvfzuX0jD8-2kG4mASj6mFOJOCABsD5c9b4FUXjJZCmgx0hoK1xkGWfVx6ds64JXk2vLVuVO3Xz2zhzrkFrMTXlSJnCAai0/s1064/material2.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="784" data-original-width="1064" height="295" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXwWhSDIyKO9B9ZUFvjOiIvotw-uC2maZp71vl3qC8GFk01I_xg00AY0JtqZHtAsRofj2G8i-zNG9odM31EWc4mGs00kTvjvfzuX0jD8-2kG4mASj6mFOJOCABsD5c9b4FUXjJZCmgx0hoK1xkGWfVx6ds64JXk2vLVuVO3Xz2zhzrkFrMTXlSJnCAai0/w400-h295/material2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;i&gt;Material 2 in Compose&lt;/i&gt;&lt;/div&gt;&lt;i&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" data-original-height="686" data-original-width="1342" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtmkVTKomIpyOR2aAls-hmHJ95o5jgjkGC3a3YeVzNlu9IlNI624el3d_b5somGHvsVIGLkQC5n9bcxci1jXm-1wF_WwHler0XcYNlZgEKs8N_8vBJsweBc5Ev8io-Y9xwxchl7YPXJp7XFc0O99z0nwR0R-poiuztvv9ep9pup6ePghH19WuQri_eMsQ/s1600/m9d3dbjl-00_Hero%20Expressive%20New_Export.gif" /&gt;&lt;i&gt;Material 3 Expressive in Compose&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;/i&gt;&lt;h2 style="text-align: left;"&gt;Looking ahead&lt;/h2&gt;
&lt;p style="text-align: left;"&gt;As of today, Compose 1.11 is the latest version with 1.12 coming soon, offering so much more than 1.0, 5 years ago. This year, we introduced  more adaptive APIs, such as &lt;code&gt;&lt;a href="https://developer.android.com/develop/adaptive-apps/guides/flexbox"&gt;FlexBox&lt;/a&gt;&lt;/code&gt;, &lt;code&gt;&lt;a href="https://developer.android.com/develop/adaptive-apps/guides/grid"&gt;Grid&lt;/a&gt;&lt;/code&gt;, &lt;code&gt;&lt;a href="https://developer.android.com/develop/adaptive-apps/guides/mediaquery"&gt;MediaQuery&lt;/a&gt;&lt;/code&gt;, and &lt;a href="https://developer.android.com/develop/ui/compose/styles"&gt;Styles&lt;/a&gt;. These APIs let you advance to the next level of premium, adaptive UI development with Compose.&lt;/p&gt;

&lt;p style="text-align: left;"&gt;At Google I/O 2026, we announced that we are now &lt;a href="https://developer.android.com/develop/ui/compose/first"&gt;Compose-first&lt;/a&gt;, meaning that all future UI development will happen only in Compose, while the Views toolkit enters maintenance mode. Material Design is also &lt;a href="https://m3.material.io/blog/material-is-compose-first" target="_blank"&gt;shifting focus&lt;/a&gt; entirely to Compose, signaling an end to the &lt;code&gt;findViewById era&lt;/code&gt;.&lt;/p&gt;

&lt;h2 style="text-align: left;"&gt;Community is at the heart of Compose&amp;nbsp;&lt;/h2&gt;
&lt;p style="text-align: left;"&gt;Over the years, you’ve inspired us with creative examples of how you’ve used Compose, and we’d love to highlight a few more examples of where we’ve seen exciting work. JetBrains has been a great partner for Google with Compose, expanding Compose to work across platforms with &lt;a href="https://kotlinlang.org/compose-multiplatform/" target="_blank"&gt;Compose Multiplatform&lt;/a&gt; and enabling desktop, iOS, and web developers to also enjoy the benefits of Compose.&lt;/p&gt;

&lt;p style="text-align: left;"&gt;We’ve really enjoyed following our most beloved newsletters from &lt;a href="https://www.jetpackcompose.app/newsletter" target="_blank"&gt;JetpackCompose.app’s Dispatch&lt;/a&gt;,  &lt;a href="https://androidweekly.net/" target="_blank"&gt;AndroidWeekly&lt;/a&gt;, to&lt;a href="https://jetc.dev/" target="_blank"&gt; jetc&lt;/a&gt; - helping Android Developers stay up-to-date with the latest in the world of Compose and Android.&lt;/p&gt;

&lt;p style="text-align: left;"&gt;Another standout contributor is &lt;a href="https://www.sinasamaki.com/"&gt;sinasamaki&lt;/a&gt;. They’ve created many delightful experiences using Compose, such as this fun ribbon modifier and the glitchy effect:&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhULTmBhLhA3t_xyz4cyCcVjxnF4_kCxoQh5ndyzOwMOVDhhsiDSZwINKcpLlxJm1usnULmoMNVRCO8HqSFfHcm6yCkAfqnhyphenhyphengjavPuxlYnoNwtDiUnWsC0aNqphG6to5J1FWsLnvato0l3mlc1YOcxXFrXZ-gEqL58BCR4oHzPRCCjFaGOngvQlwg_65s/s1282/glitch%20(1).gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="718" data-original-width="1282" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhULTmBhLhA3t_xyz4cyCcVjxnF4_kCxoQh5ndyzOwMOVDhhsiDSZwINKcpLlxJm1usnULmoMNVRCO8HqSFfHcm6yCkAfqnhyphenhyphengjavPuxlYnoNwtDiUnWsC0aNqphG6to5J1FWsLnvato0l3mlc1YOcxXFrXZ-gEqL58BCR4oHzPRCCjFaGOngvQlwg_65s/s320/glitch%20(1).gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCyqX6q5ZTclPBK-WChrNnNQlQ96ysOddRQeDQbtEji4u1DzbuPDIN7Xpov6QCZ-gjVMLlIKHr_3v_D0ZZKJQuEAe3M3Q24LbKxcz9jyk9tulTi-YBMwC0mOJSP0PVebWn-LJO15AT77t6Gp70VUcsiwz8U04w5tEN9pAbOqlobAw7hYe4Uuz7taGm_6w/s990/ribbon_modifier_sinasamaki.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="990" data-original-width="990" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCyqX6q5ZTclPBK-WChrNnNQlQ96ysOddRQeDQbtEji4u1DzbuPDIN7Xpov6QCZ-gjVMLlIKHr_3v_D0ZZKJQuEAe3M3Q24LbKxcz9jyk9tulTi-YBMwC0mOJSP0PVebWn-LJO15AT77t6Gp70VUcsiwz8U04w5tEN9pAbOqlobAw7hYe4Uuz7taGm_6w/s320/ribbon_modifier_sinasamaki.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p style="text-align: left;"&gt;&lt;a href="https://github.com/saket" target="_blank"&gt;Saket Narayan&lt;/a&gt; has also always been an inspiration when it comes to creating useful tools for Compose, such as &lt;a href="https://github.com/saket/telephoto" target="_blank"&gt;telephoto&lt;/a&gt;, a library featuring support for pan and zoom gestures and automatic sub-sampling of large images, or the latest library, &lt;a href="https://github.com/saket/touch-robot" target="_blank"&gt;Touch Robot&lt;/a&gt;, which allows you to easily test interaction animations:&lt;/p&gt;

&lt;table border="1" style="border-collapse: collapse; table-layout: fixed; width: 100%;"&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style="box-sizing: border-box; padding: 10px; vertical-align: top; width: 50%;"&gt;
        &lt;pre style="margin: 0px; white-space: pre-wrap; word-break: break-word;"&gt;&lt;code&gt;paparazzi.gif(end = 3_000) {
  DebitCard(
    Modifier.testTag("card")
  )

  val touchRobot = rememberTouchRobot()
  LaunchedEffect(Unit) {
    touchRobot.onNode(hasTestTag("card")).performGesture {
      draw(
        path = createAndroidHeadPath(),
        duration = 3.seconds,
      )
    }
  }
}

/** A path drawing the Android head. */
fun createAndroidHeadPath(bounds: Rect): Path = TODO()&lt;/code&gt;&lt;/pre&gt;
      &lt;/td&gt;
      &lt;td style="box-sizing: border-box; padding: 10px; vertical-align: top; width: 50%;"&gt;
        &lt;div class="separator" style="clear: both;"&gt;
          &lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBz8urkhKEeFAuw1Xm4-pVS9PxZmAkaAx9c2IB6U5ZeVhVkwLqUeBmTjtA6zzbZAMzvZVYqw4tLIh2pVRJWy5J8SEu24LW5rDdpnJYpMYqYy-fGkGXQ4p6wryqpeFFdBlNkIx_TITAsYqreNKluyEZpTlH6Gr48nmltIZie5bkDmpd82qJx0FxsK0k1dk/s461/saket_touch_robot.gif" style="display: block; padding: 1em 0px; text-align: center;"&gt;
            &lt;img alt="" border="0" data-original-height="349" data-original-width="461" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBz8urkhKEeFAuw1Xm4-pVS9PxZmAkaAx9c2IB6U5ZeVhVkwLqUeBmTjtA6zzbZAMzvZVYqw4tLIh2pVRJWy5J8SEu24LW5rDdpnJYpMYqYy-fGkGXQ4p6wryqpeFFdBlNkIx_TITAsYqreNKluyEZpTlH6Gr48nmltIZie5bkDmpd82qJx0FxsK0k1dk/s400/saket_touch_robot.gif" style="height: auto; max-width: 100%;" /&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p style="text-align: left;"&gt;&lt;a href="https://jakewharton.com/" target="_blank"&gt;Jake Wharton&lt;/a&gt;, who has used Compose in innovative ways (like &lt;a href="https://github.com/cashapp/molecule" target="_blank"&gt;molecule&lt;/a&gt;, and even building UI with Compose for the terminal with &lt;a href="https://github.com/JakeWharton/mosaic" target="_blank"&gt;mosaic&lt;/a&gt;). &lt;a href="https://chrisbanes.me/" target="_blank"&gt;Chris Banes&lt;/a&gt;, who has built many Compose libraries over the years, with our most recent favourite - &lt;a href="https://github.com/chrisbanes/haze" target="_blank"&gt;Haze&lt;/a&gt; for background blurring, and many of the &lt;a href="https://developers.google.com/community/experts" target="_blank"&gt;Android Google Developer Experts&lt;/a&gt; like &lt;a href="https://github.com/AkshayChordiya" target="_blank"&gt;Akshay Chordiya&lt;/a&gt;, &lt;a href="https://www.randomlytyping.com/" target="_blank"&gt;Huyen Tue Dao&lt;/a&gt;, and &lt;a href="https://katiebarnett.dev/" target="_blank"&gt;Katie Barnett&lt;/a&gt;, who’ve contributed to the success of Compose. But this is not about selecting individuals - there have been so many great contributors to the Compose codebase, and many of you continue to inspire us with your fun examples, libraries, and in-depth talks.  Without the community, Jetpack Compose wouldn’t be as successful as it is today.&lt;/p&gt;

&lt;h2 style="text-align: left;"&gt;Cheers to the next 5 years, and more!&amp;nbsp;&lt;/h2&gt;
&lt;p style="text-align: left;"&gt;Jetpack Compose has grown from an experimental idea into the standard for Android UI Development. Thank you to the entire Toolkit team at Google, and to the incredible global developer community that wrote libraries, filed bugs, and pushed the boundaries of what declarative UI can do.&lt;/p&gt;

&lt;p style="text-align: left;"&gt;This week, we’ll be celebrating with some in-person birthday parties across the globe, and a live “Birthday party” on the &lt;a href="https://www.youtube.com/user/androiddevelopers" target="_blank"&gt;Android Developers YouTube channel&lt;/a&gt; on July 30th at 13:00 UTC.  During this time, we’ll hang out and discuss Compose and answer your questions!&lt;/p&gt;

&lt;p style="text-align: left;"&gt;Cheers to the next 5 years, and happy composing!&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/8693766666920532872/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/five-years-of-jetpack-compose.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8693766666920532872" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8693766666920532872" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/five-years-of-jetpack-compose.html" rel="alternate" title="Celebrating 5 years of Jetpack Compose" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqdSbNmK_9vJR4DQPvGN0oUtQK8s0T2HsgPAsNsl9Kqvd49M3ODh7wlGPZrCRVHEC30oArKNrqmLtuO-zwoZHkfN3_AQz2NNBG6S1st34TOCYx9Mu9cM-ut-rSN8-U1o9Q4ufBwY1l3ukPRjw8QxHWdpxAeeoKRVDPvEjysPwORA3TRhbtpMyTctDQsdY/s72-c/Jetpack%20compose_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-1305649857865852540</id><published>2026-07-27T06:00:00.000-07:00</published><updated>2026-07-27T21:48:52.868-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android Gradle Plugin"/><category scheme="http://www.blogger.com/atom/ns#" term="app performance"/><category scheme="http://www.blogger.com/atom/ns#" term="atomic"/><category scheme="http://www.blogger.com/atom/ns#" term="Compose"/><category scheme="http://www.blogger.com/atom/ns#" term="Coroutines"/><category scheme="http://www.blogger.com/atom/ns#" term="R8"/><title type="text">How R8 made Kotlin Coroutines on Android 2x faster</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHiv_LIAZ9QEJ4RWJSvZphTWmkDaVoseyWsbSPkfJDKd0DXjq53xtLOMiVtTEzlW6dAwXUlcucsBDKxjp9MjET4MB1b4ymZkd-b7jhm-PczdvyFqQCpZ39MXVjaVrWg4Y6WD4KLYOL3PbmYBDumMULpZQDX0052163RVUWZnfUAUPFtfwZMVflqjT9AnQ/s2469/0707%20Faster%20Kotlin%20coroutines%20on%20Android%20with%20R8_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHiv_LIAZ9QEJ4RWJSvZphTWmkDaVoseyWsbSPkfJDKd0DXjq53xtLOMiVtTEzlW6dAwXUlcucsBDKxjp9MjET4MB1b4ymZkd-b7jhm-PczdvyFqQCpZ39MXVjaVrWg4Y6WD4KLYOL3PbmYBDumMULpZQDX0052163RVUWZnfUAUPFtfwZMVflqjT9AnQ/s2469/0707%20Faster%20Kotlin%20coroutines%20on%20Android%20with%20R8_Meta.png" style="display: none;" /&gt;&lt;i&gt;Posted by Andrei Shikov, Senior Software Engineer, Android Toolkit and Jonathan Starup, Software Engineer, R8 Team&lt;/i&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYQ0hvP8noS5d46xLL2ca89fUyDM7ONaSVUIn8QhZxuB8GKNdGi_IIQNt3c8dAT67nO1TMfcPrmXMXfBjggYafmHV6cYH86vFyoEnIEgaFJ2uOYQIH4l9zA4GlQvduoJEVUNzIUX1qJmaxY3qRGn9TKwuRD_HR87trMxuaU0x29FXcx7Pr-DdP0ZhxZhQ/s8582/0707%20Faster%20Kotlin%20coroutines%20on%20Android%20with%20R8_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8582" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYQ0hvP8noS5d46xLL2ca89fUyDM7ONaSVUIn8QhZxuB8GKNdGi_IIQNt3c8dAT67nO1TMfcPrmXMXfBjggYafmHV6cYH86vFyoEnIEgaFJ2uOYQIH4l9zA4GlQvduoJEVUNzIUX1qJmaxY3qRGn9TKwuRD_HR87trMxuaU0x29FXcx7Pr-DdP0ZhxZhQ/s1600/0707%20Faster%20Kotlin%20coroutines%20on%20Android%20with%20R8_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Starting from AGP 9.2.0, R8 optimizes most &lt;code&gt;Atomic*FieldUpdater&lt;/code&gt; calls into &lt;code&gt;Unsafe&lt;/code&gt; variants that perform &lt;a href="https://github.com/Kotlin/kotlinx.coroutines/issues/3950"&gt;2x to 4x better on common operations&lt;/a&gt;. This has a particularly large impact on the kotlinx.atomicfu library that implements atomics for &lt;code&gt;kotlinx.coroutines&lt;/code&gt;, making launching and cancelling coroutines up to 2x faster. In order to get the benefits, update your AGP to 9.2.0 or above.&lt;/p&gt;

&lt;p&gt;With the majority of Android apps adopting Kotlin as their main language of choice, &lt;code&gt;&lt;a href="https://github.com/Kotlin/kotlinx.coroutines" target="_blank"&gt;kotlinx.coroutines&lt;/a&gt;&lt;/code&gt; has become a de-facto standard for asynchronous programming. The library offers a well-designed and structured way of managing concurrent flows that is native to Kotlin. Jetpack Compose was no exception, adopting coroutines for managing pointer events, animations and other interactions. At the time of writing, most concurrent APIs in Compose call &lt;code&gt;suspend&lt;/code&gt; functions under the hood and are launching and/or cancelling coroutines to handle updates.&lt;/p&gt;

&lt;p&gt;As the Compose team started to investigate performance, coroutines were discovered to be a bottleneck for many operations that happen outside of composition. As an example, 80% of the time spent on creating and updating &lt;code&gt;Modifier.clickable&lt;/code&gt; was consumed by launching and cancelling internal coroutines that handled &lt;code&gt;InteractionSource&lt;/code&gt; updates. Based on those observations, much of early performance work was focused on removing coroutines from the default path and delaying initialization until necessary.&lt;/p&gt;

&lt;h2&gt;The cost of a coroutine&lt;/h2&gt;

&lt;p&gt;The easiest way to analyze a function's internal behavior on Android is to capture an Android Runtime (ART) method trace. An ART method trace is a tool that records the execution flow of an app, showing exactly which methods are called, their order, and how much time is spent in each, allowing developers to identify performance bottlenecks. For an empty &lt;code&gt;LaunchedEffect { }&lt;/code&gt; call, it would look something like this:&amp;nbsp;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtNkPVicdJLFrYlTBtffjL73QsWm8LztGzRCLSVrzpHy-FiyMEcOIJPkDYAjUKI0ZAgQDgATjjZXIcmjZlf7iusLjC9E5F6GaIPMvZbTh1hP4N7OsnUPgkz5atS5PcsrPh5ulpSAqJ9K8T6eviqTwy4NB5zMu8HAnBZgK2PaZwX3ajJFXSRuoH35T4TZk/s7680/pic01_enhanced.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="3432" data-original-width="7680" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtNkPVicdJLFrYlTBtffjL73QsWm8LztGzRCLSVrzpHy-FiyMEcOIJPkDYAjUKI0ZAgQDgATjjZXIcmjZlf7iusLjC9E5F6GaIPMvZbTh1hP4N7OsnUPgkz5atS5PcsrPh5ulpSAqJ9K8T6eviqTwy4NB5zMu8HAnBZgK2PaZwX3ajJFXSRuoH35T4TZk/s1600/pic01_enhanced.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p style="text-align: center;"&gt;&lt;i&gt;LaunchedEffect method trace visualized in the Perfetto UI&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;The method trace above can be separated into three parts:&lt;br /&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;
Initializing a new coroutine&lt;/li&gt;&lt;li&gt;
Starting coroutine&lt;/li&gt;&lt;li&gt;
Completing coroutine (because it exits immediately)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Cancelling &lt;code&gt;LaunchedEffect&lt;/code&gt; is similar to normal completion, except it also creates a &lt;code&gt;CancellationException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From the profile above, one thing that is immediately suspicious is frequent calls into &lt;code&gt;java.util.concurrent.AtomicReferenceFieldUpdater&lt;/code&gt; (purple or green boxes with j… labels). While each call is relatively fast, the frequency is concerning; any non-negligible overhead that is spread out across multiple invocations might add up to a noticeable regression. Zooming in on a call reveals that most of the time is spent on... reflection checks?&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirqmZk8TeN6KsUrqnCFT_AigbT3IdjfMDxabgQEM7izThyphenhyphenubMyvsFzkd3zR6SSxfvovJb5QeaoeIYPG9pFoNCegLDizYwfTOnKFv9sWfp1whDlFB9gUf3VMS9qU2-smyKEHrmsrPlN4htYxmLQ3yGfgZlWzjpwi6nTXbTcghvutTmJQjSo2s9c8xG-LOM/s13034/pic02-enhanced.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="4102" data-original-width="13034" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirqmZk8TeN6KsUrqnCFT_AigbT3IdjfMDxabgQEM7izThyphenhyphenubMyvsFzkd3zR6SSxfvovJb5QeaoeIYPG9pFoNCegLDizYwfTOnKFv9sWfp1whDlFB9gUf3VMS9qU2-smyKEHrmsrPlN4htYxmLQ3yGfgZlWzjpwi6nTXbTcghvutTmJQjSo2s9c8xG-LOM/s1600/pic02-enhanced.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;An up-close look at the method trace of AtomicReferenceFieldUpdater.get during LaunchedEffect initialization&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Coroutines implement a lock-free tree structure for parent-child relationships that makes structured concurrency possible. Turns out, the &lt;code&gt;kotlinx.atomicfu&lt;/code&gt; library implements lock-free atomic operations using a well-known JVM primitive, &lt;code&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.html" target="_blank"&gt;AtomicReferenceFieldUpdater&lt;/a&gt;&lt;/code&gt;. The updater uses a class reference and a field name to perform atomic operations at runtime, and it has to run several reflective safety checks to make sure the field exists and is accessible. Each operation in coroutines (starting, suspending, cancelling, completing) calls at least one atomic operation, so if it is slow, coroutines will not perform well.&lt;/p&gt;

&lt;h2&gt;Investigating AtomicReferenceFieldUpdater&lt;/h2&gt;

&lt;p&gt;But let's not get ahead of ourselves. &lt;code&gt;AtomicReferenceFieldUpdater&lt;/code&gt; is actually well-optimized on JVM &lt;a href="https://shipilev.net/blog/2015/faster-atomic-fu/"&gt;for over 10 years now&lt;/a&gt;, and method traces might capture overhead that is completely removed by a VM level optimization: just-in-time (JIT) or ahead-of-time (AOT) compilations. To verify performance, let's write a few benchmarks to measure the difference between atomic references from &lt;code&gt;kotlinx.atomicfu&lt;/code&gt; and &lt;code&gt;java.util.concurrent.atomic&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@RunWith(AndroidJUnit4::class)
class AtomicReferenceBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()
    
    private val atomicReference = java.util.concurrent.atomic.AtomicReference(false)
    private val atomicRef = kotlinx.atomicfu.atomic&amp;lt;Boolean&amp;gt;(false)
    
    @Test
    fun atomicReference_compareAndSet() {
        benchmarkRule.measureRepeated { 
            atomicReference.compareAndSet(true, false)
            atomicReference.compareAndSet(false, true)
        }
    }

     @Test
    fun atomicRef_compareAndSet() {
        benchmarkRule.measureRepeated {
            atomicRef.compareAndSet(true, false)
            atomicRef.compareAndSet(false, true)
        }
    }

    /* measuring other methods from the method traces above */
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Running this benchmark on a Pixel 5 (while ensuring &lt;code&gt;AtomicReferenceFieldUpdater#compareAndSet&lt;/code&gt; is JIT compiled during warmup), yields the following results on Pixel 5 (API 33):&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code&gt; 50.7 ns  atomicReference_compareAndSet
135   ns  atomicRef_compareAndSet
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The measurements confirm the gap, with &lt;code&gt;kotlinx.atomicfu&lt;/code&gt; version clearly being approximately 2.7x slower. This confirms that ART does not perform any hidden optimization and reflective access checks add real overhead during runtime.&lt;/p&gt;

&lt;p&gt;Looking back at the original method trace, the only meaningful work performed by the &lt;code&gt;AtomicReferenceFieldUpdater&lt;/code&gt; is the internal call into &lt;code&gt;Unsafe.getObjectVolatile&lt;/code&gt; that actually executes the underlying atomic operation. In most cases, the updater initializer is static, and can be proved to be always correct based on the structure of the surrounding class. Thus, one could statically analyze most of the &lt;code&gt;AtomicReferenceFieldUpdater&lt;/code&gt; usages and replace them with an internal &lt;code&gt;Unsafe&lt;/code&gt; variant during compilation. It also just happens that Android build toolchain has its very own optimizing compiler that can do exactly that.&lt;/p&gt;

&lt;h2&gt;Optimization with R8&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Atomic*FieldUpdater&lt;/code&gt; classes support subtle, dynamic and reflection-based use,  but are often used in statically obvious patterns. This both explains the slow baseline performance and the want for optimization. R8 is a full-program optimizing compiler and is well-suited to see through the simpler patterns to skim the overhead of the reflective safety checks. R8 receives JVM bytecode after the Java or the Kotlin compiler, but to ease readability these examples are presented in Java syntax. This is why there are no type arguments for &lt;code&gt;AtomicReferenceFieldUpdater&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Example {
    volatile String data = "";
    static final AtomicReferenceFieldUpdater updater =
        AtomicReferenceFieldUpdater.newUpdater(Example.class, String.class, "data");

    void example() {
        // ...
        updater.compareAndSet(this, "", "new");
        // ...
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The base example creates a static final updater which accesses a volatile field with simple constant arguments for the holder, the type, and the name of the field. The reflection used is totally transparent. It is clear to see this updater references a valid field and that the site of the updater creation has valid access to the field.&lt;/p&gt;

&lt;p&gt;In its essence, &lt;code&gt;Atomic*FieldUpdater&lt;/code&gt; is a wrapper around a field offset and calls to &lt;code&gt;Unsafe&lt;/code&gt;. The best case scenario for the optimization is to replace the updater field with an offset field and replace the updater calls with calls to &lt;code&gt;Unsafe&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Optimizing Atomic*FieldUpdater&lt;/h3&gt;

&lt;p&gt;The optimization is implemented in three parts: Instrumentation, Replacement, and Clean-up.&lt;/p&gt;

&lt;h2&gt;Instrumentation&lt;/h2&gt;

&lt;p&gt;The first step is to introduce offset fields alongside the updater field in order to facilitate direct access via the &lt;code&gt;Unsafe&lt;/code&gt; call.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;static final long updater$offset =
    SyntheticUnsafe.UNSAFE.objectFieldOffset(Example.class.getDeclaredField("data"))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The field is accessed via reflection, and &lt;code&gt;Unsafe&lt;/code&gt; is used to extract the field offset on the class. This code represents the internals of &lt;code&gt;Atomic*FieldUpdater&lt;/code&gt; if you disregard reflection validation. Instead, the holder type of the updater and the field type of the volatile field are tracked statically in the compiler.&lt;/p&gt;

&lt;p&gt;Note that the original field and its initialization are left as-is. The optimization process optimistically facilitates and optimizes uses and then later cleans up. This is a simple approach to the implementation but also allows partial optimization of updater fields, where some uses are left as they were while others are optimized.&lt;/p&gt;

&lt;h2&gt;Replacement&lt;/h2&gt;

&lt;p&gt;At this point in the compiler, after a suitable concurrency join point, we have a list of instrumented updater fields. This means that we can optimize each call site individually based on a few conditions. Consider an example call:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;updater.compareAndSet(holder, expectedValue, newValue);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The conditions that &lt;code&gt;Atomic*FieldUpdater&lt;/code&gt; requires are these:&lt;br /&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;
  Does &lt;code&gt;updater&lt;/code&gt; come from an instrumented field? That is, can static analysis track the value of the object back to a field read of an instrumented updater?&lt;/li&gt;&lt;li&gt;
  Is &lt;code&gt;holder&lt;/code&gt; the same class or a subclass of the originally defined holder type?&lt;/li&gt;&lt;li&gt;
  Is &lt;code&gt;newValue&lt;/code&gt; the same class or a subclass of the originally defined field type?&lt;/li&gt;&lt;/ul&gt;
  If all conditions are met, then the call is replaced by a call to &lt;code&gt;Unsafe&lt;/code&gt; without any of the reflection checks.&lt;p&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SyntheticUnsafe.UNSAFE.compareAndSwapObject(holder, Example.updater$offset, expectedValue, newValue)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This new call is faster and simpler but it differs from the original call in regards to its handling of null values in &lt;code&gt;updater&lt;/code&gt; and &lt;code&gt;holder&lt;/code&gt;. Unless statically ruled out, null-checks are inserted for both.&lt;/p&gt;

&lt;h2&gt;Clean-up&lt;/h2&gt;

&lt;p&gt;At this point, the holding class has the original updater field and the new offset field along with call sites that might use either one of the two. If  none of the call sites were optimized, then the offset field should be removed and if all of the call sites were optimized, then the updater field should be removed. In both cases the initializing call should also be deleted. The deletion of unused fields and removal of dead code is already done in the compiler, but removing the initializing code here requires a few more tricks.&lt;/p&gt;

&lt;p&gt;Both the call to &lt;code&gt;newUpdater&lt;/code&gt; and &lt;code&gt;getDeclaredField&lt;/code&gt; might have side effects as they can throw exceptions (and their implementation is also unknown since it depends on the API version). This means that by generic optimization, they cannot safely be removed. So this clean-up required explicit consideration of the instrumented fields, since those are statically known to be free of exceptions.&lt;/p&gt;

&lt;p&gt;In the end, the simple updater example shown above looks like this after optimization:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Example {
    volatile String data = "";
    static final long updater$offset =
        SyntheticUnsafe.UNSAFE.objectFieldOffset(Example.class.getDeclaredField("data"))

    void example() {
        // ...
        SyntheticUnsafe.UNSAFE.compareAndSwapObject(this, Example.updater$offset, "", "new")
        // ...
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Results&lt;/h3&gt;

&lt;p&gt;After these optimizations, &lt;code&gt;kotlinx.atomicfu&lt;/code&gt; and most explicit uses of &lt;code&gt;AtomicInt/Long/ReferenceFieldUpdater&lt;/code&gt; now match &lt;code&gt;AtomicReference&lt;/code&gt; performance with R8 applied. In fact, it is even faster in some benchmarks; &lt;code&gt;kotlinx.atomicfu&lt;/code&gt; has a compiler plugin that can inline &lt;code&gt;atomic&lt;/code&gt; instances into fields, reducing allocations required to create an atomically updated field.&lt;/p&gt;

&lt;p&gt;Jetpack Compose was the main beneficiary of this work. Compose runtime has a number of microbenchmarks that track coroutine performance very closely to catch performance regressions early. When the benchmarks were updated to a new version of R8, we noticed a 2x improvement when launching and cancelling coroutines in &lt;code&gt;LaunchedEffect&lt;/code&gt;!&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5VYYOudfoQzHlELVMmmiLkRxUd80bqzqB8ykvBedO0VpCROTeK63gXhyphenhyphenYZWed99FWOFl58qqj34aQP9GLPJGW_Ls2w5ez0o-TIOqdt9hlIn5NFmpT7N83sKuhnCdbazdVSFcz0h2e4Zu12GCaW_ss9t-7v7t9J26WgqKpIWUyCkKz4X8L95H2fYjA6i0/s9600/pic03_enhanced.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="5580" data-original-width="9600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5VYYOudfoQzHlELVMmmiLkRxUd80bqzqB8ykvBedO0VpCROTeK63gXhyphenhyphenYZWed99FWOFl58qqj34aQP9GLPJGW_Ls2w5ez0o-TIOqdt9hlIn5NFmpT7N83sKuhnCdbazdVSFcz0h2e4Zu12GCaW_ss9t-7v7t9J26WgqKpIWUyCkKz4X8L95H2fYjA6i0/s1600/pic03_enhanced.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;i&gt;Benchmark graph illustrating the time taken when starting and cancelling coroutines in LaunchedEffect (lower is better). The change in the graph corresponds to an R8 update, showcasing 2x improvement.&lt;/i&gt;&lt;/div&gt;

&lt;p&gt;Aside from that, the ART team is implementing these optimizations natively at the VM level. If your app is targeting API 37 and is running on a recent version of Android, it is possible that your device is already optimizing coroutines in a similar way. The coroutine benchmarks above observed ~15% improvement in performance after JIT updates in the recent versions of ART.&lt;/p&gt;

&lt;p&gt;Your app will receive this optimization by default when upgrading to AGP 9.2.0 or by using R8 9.2.0 directly. For more information, see &lt;a href="https://r8.googlesource.com/r8/+/refs/heads/main/README.md#replacing-r8-in-agp" target="_blank"&gt;D8 dexer and R8 shrinker&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/1305649857865852540/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/how-r8-made-kotlin-coroutines-2x-faster.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/1305649857865852540" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/1305649857865852540" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/how-r8-made-kotlin-coroutines-2x-faster.html" rel="alternate" title="How R8 made Kotlin Coroutines on Android 2x faster" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHiv_LIAZ9QEJ4RWJSvZphTWmkDaVoseyWsbSPkfJDKd0DXjq53xtLOMiVtTEzlW6dAwXUlcucsBDKxjp9MjET4MB1b4ymZkd-b7jhm-PczdvyFqQCpZ39MXVjaVrWg4Y6WD4KLYOL3PbmYBDumMULpZQDX0052163RVUWZnfUAUPFtfwZMVflqjT9AnQ/s72-c/0707%20Faster%20Kotlin%20coroutines%20on%20Android%20with%20R8_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-7230493561349571062</id><published>2026-07-22T12:00:00.000-07:00</published><updated>2026-07-22T12:06:26.700-07:00</updated><title type="text">Optimize your apps for the next generation of Samsung Galaxy devices</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-c747avSj9Z8JO4DTK4kSfO3SjSpd5aTuVvR_TBeD3bXV6cc8lzNLGrWCngNXdyZBeiNjQqwQZCcU4QCrovwL99gu0t5bQrlTXa0PIBGIivwyS8y226MgeraphZr4VITWYe0x7ckFto0dsD8rBLM1J_P3dV0CBj5Ctlwm8jsgAPZA7W2XnKnRz59H9I/s2049/MM_Adaptive_and_device_Meta%20(1).png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-c747avSj9Z8JO4DTK4kSfO3SjSpd5aTuVvR_TBeD3bXV6cc8lzNLGrWCngNXdyZBeiNjQqwQZCcU4QCrovwL99gu0t5bQrlTXa0PIBGIivwyS8y226MgeraphZr4VITWYe0x7ckFto0dsD8rBLM1J_P3dV0CBj5Ctlwm8jsgAPZA7W2XnKnRz59H9I/s2049/MM_Adaptive_and_device_Meta%20(1).png" style="display: none;" /&gt;&lt;div&gt;



&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;i&gt;Posted by Fahd Imtiaz, Senior Product Manager and Miguel Montemayor, Developer Relations Engineer, Android Developer Experience&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGrEplk_My1fOfyw851kt92Jc2wyODN6bwWJaL5EGFV6_5grP3-pS7jrMzI4MOXgo1W1yVHcwj8J7AIO3olxlHDoNWxzTTlQLc9_D6CWB6bUtWLyvxmXN-JQQ92_HWYErsdMVuNkynTjXpZSKoaUTFiY_4aiffEDsfdCrl9om05MRVqqMac0YGExE4XLQ/s4210/MM_Adaptive_and_device_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1254" data-original-width="4210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGrEplk_My1fOfyw851kt92Jc2wyODN6bwWJaL5EGFV6_5grP3-pS7jrMzI4MOXgo1W1yVHcwj8J7AIO3olxlHDoNWxzTTlQLc9_D6CWB6bUtWLyvxmXN-JQQ92_HWYErsdMVuNkynTjXpZSKoaUTFiY_4aiffEDsfdCrl9om05MRVqqMac0YGExE4XLQ/s1600/MM_Adaptive_and_device_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Today at Galaxy Unpacked, Samsung &lt;a href="https://blog.google/products-and-platforms/platforms/android/galaxy-unpacked-2026" target="_blank"&gt;unveiled&lt;/a&gt; its latest lineup of foldable and wearable devices. For developers, this means that the variety of form factors, screen sizes, and device postures your app needs to support is expanding once again.&lt;/p&gt;

&lt;p&gt;With devices like the Galaxy Z Fold8, the ecosystem is expanding to include hardware with a landscape-first natural orientation and a wider aspect ratio in its main display state. Whether a user is unfolding a large display, flipping open a cover screen, or glancing at their wrist, users expect a flawless experience. To help you meet this moment, we’re sharing actionable guidance and new tooling updates to enable you to build adaptively proactively.&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
  &lt;iframe allowfullscreen="" class="BLOG_video_class" height="450" src="https://www.youtube.com/embed/pLNJ-fNYTKU" style="border: 0; height: 450px; width: 100%;" width="100%" youtube-src-id="pLNJ-fNYTKU"&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;h2&gt;Rethink layout architecture for dynamic displays, including ultra-wide foldables&lt;/h2&gt;

&lt;p&gt;Building for the latest foldables means dropping assumptions about display orientation and size. This is especially true for the Galaxy Z Fold8, which adopts an ultra-wide display, adding to the variety of aspect ratios to account for.&amp;nbsp; Devices with this landscape-first natural orientation show the limitations of hardcoded layout rules when users unfold the device. That’s why we’ve introduced &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/foldables/trifolds-and-landscape-foldables" target="_blank"&gt;dedicated guidance for building for landscape foldables and trifolds.&lt;/a&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrdDMq9mmhR2NzEVD5cgQgT3Y5DgMZOV5FrjsJb-wSiZVvJjIiDQuUkfv0cjBHQMREjOKPqz9n6wPf-x5Hn6H7uT2_JiXA3Nykcr1UwnwDRK9jGFurhTRKR-5t1BN62ISXFznXhQ_e-03Mo6uIh5-BDVmNbA1Q4RY9rSg4VxBO0K6E6Dc4kViNpvuYefY/s1302/Samsung%20fold8%20phones.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="442" data-original-width="1302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrdDMq9mmhR2NzEVD5cgQgT3Y5DgMZOV5FrjsJb-wSiZVvJjIiDQuUkfv0cjBHQMREjOKPqz9n6wPf-x5Hn6H7uT2_JiXA3Nykcr1UwnwDRK9jGFurhTRKR-5t1BN62ISXFznXhQ_e-03Mo6uIh5-BDVmNbA1Q4RY9rSg4VxBO0K6E6Dc4kViNpvuYefY/s1600/Samsung%20fold8%20phones.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;To build a responsive UI that handles these physics seamlessly, focus on the following core pillars:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;Build fluid, adaptive layouts: &lt;/b&gt;Wide aspect ratios and compact vertical heights require fluid UIs that scale responsively. Our updated &lt;a href="https://developer.android.com/design/ui/mobile/guides/layout-and-content/adapt-layout" target="_blank"&gt;adaptive design guidance&lt;/a&gt; advises considering the window class width first to determine layout changes, then adjusting for height. To let individual components fluidly adapt to the grid, structure your layout using flexible containers that allow your content to automatically wrap, span, and reflow. For design inspiration browse our &lt;a href="https://developer.android.com/design/ui/gallery/social/pawparazzi" target="_blank"&gt;adaptive sample app&lt;/a&gt; and &lt;a href="https://developer.android.com/design/ui/gallery/social/dual-screen?hl=en" target="_blank"&gt;dual-screen&lt;/a&gt; design galleries.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Track actual app space:&lt;/b&gt; Your app's display space rarely matches the physical device size, especially on an ultra-wide screen during multi-window, split-screen, or multitasking states. Sometimes even the orientations differ. Leverage &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/use-window-size-classes?hl=en" target="_blank"&gt;Window Size Classes&lt;/a&gt; using the &lt;a href="https://developer.android.com/blog/posts/jetpack-window-manager-1-5-is-stable" target="_blank"&gt;Jetpack Window Manager library&lt;/a&gt; to calculate the exact space your app occupies.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
  
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
  &lt;iframe allowfullscreen="" class="BLOG_video_class" height="450" src="https://www.youtube.com/embed/thfNTC9x_Ys" style="border: 0; height: 450px; width: 100%;" width="100%"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;Leverage the latest Jetpack Compose Update: &lt;/b&gt;Start by adopting the stable &lt;a href="https://android-developers.googleblog.com/2026/04/jetpack-compose-april-2026-updates.html" target="_blank"&gt;Jetpack Compose April '26 release&lt;/a&gt; (&lt;a href="https://developer.android.com/develop/ui/compose/bom" target="_blank"&gt;Compose BOM&lt;/a&gt; version &lt;code&gt;2026.04.01&lt;/code&gt;).Take advantage of the new structural layout tools to manage complex architectures. The new &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/grid" target="_blank"&gt;Grid&lt;/a&gt; API allows you to define dynamic tracks and column spans without the performance overhead of a lazy list. Pair Grid with the new &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/flexbox" target="_blank"&gt;FlexBox&lt;/a&gt; layout API to easily handle multi-axis alignment and dynamic item wrapping. You can also use the new &lt;a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/mediaquery" target="_blank"&gt;MediaQuery&lt;/a&gt; API to adapt your UI to its environment, using conditions to detect signals like device posture, window size, and keyboard types.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Make your app fold aware: &lt;/b&gt;Use the Jetpack WindowManager library, which provides an API surface for foldable device window features such as folds and hinges. When your app is&lt;a href="https://developer.android.com/develop/adaptive-apps/guides/foldables/make-your-app-fold-aware" target="_blank"&gt; fold aware&lt;/a&gt;, it can adapt its layout to avoid placing important content in the area of folds or hinges and use folds and hinges as natural separators.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Maintain app continuity:&lt;/b&gt; Avoid breaking the user journey when the device configuration shifts. Retain your UI state using &lt;a href="https://developer.android.com/topic/libraries/architecture/viewmodel?hl=en" target="_blank"&gt;ViewModel&lt;/a&gt; to ensure smooth transitions when a user folds or unfolds their device.&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdxp09YbiUc9EzTGhIJ2fcoV67rLKb6Sm9UOVCISO4Xa0VVVnFUJG9PXSAYCq7gnHILLx8xoIx-L2C0blhugbADUa3nM0AOx8UQzGImu194B94Kt-CKAuK1CrGHUz10fBFs02Lmly-HO-fmBHFuZ9knuYRb6EP9v4-SpR7Ja-oeJZErJDUVEgEje0d7J8/s1920/7.22_MorphToTablet_Gif.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1080" data-original-width="1920" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdxp09YbiUc9EzTGhIJ2fcoV67rLKb6Sm9UOVCISO4Xa0VVVnFUJG9PXSAYCq7gnHILLx8xoIx-L2C0blhugbADUa3nM0AOx8UQzGImu194B94Kt-CKAuK1CrGHUz10fBFs02Lmly-HO-fmBHFuZ9knuYRb6EP9v4-SpR7Ja-oeJZErJDUVEgEje0d7J8/w640-h360/7.22_MorphToTablet_Gif.gif" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h2 style="text-align: left;"&gt;Ensure seamless camera capture on foldable devices&lt;/h2&gt;&lt;div&gt;Camera implementation on foldables brings unique hardware quirks. Moving from a compact outer display to an expanded inner display introduces distinct layout aspect ratios while device rotation remains unchanged. If an app assumes a fixed portrait relationship between the camera sensor and the device layout, the app will likely suffer from sideways, stretched, or cropped previews during these folding transitions.&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;When optimizing your app's media pipeline, migrate your capture experiences to &lt;a href="https://developer.android.com/media/camera/camerax" target="_blank"&gt;CameraX&lt;/a&gt; using the CameraX migration &lt;a href="https://github.com/android/skills/blob/main/camera/camerax/SKILL.md"&gt;skill&lt;/a&gt;. The library’s &lt;a href="https://developer.android.com/reference/kotlin/androidx/camera/view/PreviewView" target="_blank"&gt;PreviewView&lt;/a&gt; automatically handles sensor orientation, device rotation, and scaling behind the scenes. This guarantees a clean, stable preview regardless of how the user holds or positions the device. If you are maintaining an existing Camera2 codebase, integrate the &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/foldables/trifolds-and-landscape-foldables#solution_2_cameraviewfinder" target="_blank"&gt;CameraViewfinder&lt;/a&gt; library to apply these complex aspect ratio and rotation transformations automatically without needing a total architecture overhaul.&lt;/div&gt;&lt;/div&gt;&lt;h2 style="text-align: left;"&gt;Extend glanceable interactions to Wear OS 7&lt;/h2&gt;&lt;div&gt;The opportunity to build for this new generation of devices extends right to the wrist. Launching with Wear OS 7, Wear Widgets give you a fresh surface to provide users with instant, glanceable access to their essential updates. You can build these highly expressive experiences using &lt;a href="https://developer.android.com/jetpack/androidx/releases/glance-wear" target="_blank"&gt;Jetpack Glance&lt;/a&gt; and &lt;a href="https://developer.android.com/jetpack/androidx/releases/compose-remote" target="_blank"&gt;RemoteCompose&lt;/a&gt;. Crucially, Widgets built with this framework can now populate multi-widget tiles that were previously reserved for first-party widgets.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
    
 &lt;div class="separator" style="clear: both; text-align: center;"&gt;
  &lt;iframe allowfullscreen="" class="BLOG_video_class" height="450" src="https://www.youtube.com/embed/VnjgKzAa0ws" style="border: 0; height: 450px; width: 100%;" width="100%"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;h2 style="clear: both; text-align: left;"&gt;Build intelligent features&amp;nbsp;&lt;/h2&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;a href="https://blog.google/products-and-platforms/platforms/android/gemini-intelligence/" target="_blank"&gt;Gemini intelligence &lt;/a&gt;already completes tasks on users’ behalf, and you can &lt;a href="https://developer.android.com/ai/appfunctions?_gl=1*1jms098*_up*MQ..*_ga*MjY0OTY0MDI3LjE3ODQzMzI1NDk.*_ga_6HH9YJMN9M*czE3ODQzMzI1NDkkbzEkZzAkdDE3ODQzMzI1NDkkajYwJGwwJGgxNjE0MTMzNjEz" target="_blank"&gt;experiment&lt;/a&gt; with the intelligence system by sharing your apps capabilities.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Samsung’s new foldable devices come with Gemini Nano 4, our latest on-device model. Nano 4 provides support for over 140 languages, better multimodal understanding, and &lt;a href="https://developers.google.com/ml-kit/release-notes#july_14_2026" target="_blank"&gt;much more&lt;/a&gt;. Use &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android" target="_blank"&gt;ML Kit’s Prompt API&lt;/a&gt; with advanced features like s&lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/structured-output" target="_blank"&gt;tructured output&lt;/a&gt; and &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/thinking-mode" target="_blank"&gt;thinking mode&lt;/a&gt; to build intelligent features on-device.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;h2 style="clear: both; text-align: left;"&gt;Start optimizing today&lt;/h2&gt;&lt;div class="separator" style="clear: both;"&gt;The tools and frameworks are ready to help you optimize your app for all screen sizes. Begin by exploring our guidance for &lt;a href="https://developer.android.com/develop/adaptive-apps" target="_blank"&gt;building adaptive apps &lt;/a&gt;to learn more about core adaptive design principles.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;To dive deeper, check out our comprehensive &lt;a href="https://www.youtube.com/playlist?list=PLD2U7gd1-ieo" target="_blank"&gt;YouTube playlist&lt;/a&gt;. Finally, ensure your app delivers a flawless, premium experience on the newest form factors by reviewing our dedicated quality guidelines for &lt;a href="https://developer.android.com/develop/adaptive-apps/guides/foldables/trifolds-and-landscape-foldables" target="_blank"&gt;trifolds and landscape foldables&lt;/a&gt; and &lt;a href="https://developer.android.com/design/ui/wear/guides/get-started?hl=en" target="_blank"&gt;WearOS&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Unfold the future today!&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/7230493561349571062/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/optimize-galaxy-screen-sizes.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/7230493561349571062" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/7230493561349571062" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/optimize-galaxy-screen-sizes.html" rel="alternate" title="Optimize your apps for the next generation of Samsung Galaxy devices" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV-c747avSj9Z8JO4DTK4kSfO3SjSpd5aTuVvR_TBeD3bXV6cc8lzNLGrWCngNXdyZBeiNjQqwQZCcU4QCrovwL99gu0t5bQrlTXa0PIBGIivwyS8y226MgeraphZr4VITWYe0x7ckFto0dsD8rBLM1J_P3dV0CBj5Ctlwm8jsgAPZA7W2XnKnRz59H9I/s72-c/MM_Adaptive_and_device_Meta%20(1).png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-1633372972504974395</id><published>2026-07-21T06:00:00.000-07:00</published><updated>2026-07-21T09:58:09.514-07:00</updated><title type="text">Build intelligent Android apps: Cloud and hybrid inference</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBHTpa22SxEltoebLZYO_34iRtahN8z5tA3tnIryIii0s4_conN5qFYfmNro6nmZBfsgiZeRLtru-gE4XO2mf-RBDyIo00kf3QunWwUO-SICHkVSv0exAQQ4qA0KzjMGRpA8qj1TSMP0Ffe0FzrEc_S1zBaakKzCZFpqYLXqds9Zqmqr8yyeSgyNl9U0s/s2469/features%20in%20Jetpacker%20Features%20with%20Firebase%20AI%20Logic%20_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBHTpa22SxEltoebLZYO_34iRtahN8z5tA3tnIryIii0s4_conN5qFYfmNro6nmZBfsgiZeRLtru-gE4XO2mf-RBDyIo00kf3QunWwUO-SICHkVSv0exAQQ4qA0KzjMGRpA8qj1TSMP0Ffe0FzrEc_S1zBaakKzCZFpqYLXqds9Zqmqr8yyeSgyNl9U0s/s2469/features%20in%20Jetpacker%20Features%20with%20Firebase%20AI%20Logic%20_Meta.png" style="display: none;" /&gt;&lt;div&gt;&lt;i&gt;Posted by Thomas Ezan, Jolanda Verhoef, Caren Chang, Senior Developer Relations Engineers, Android Developer Relations&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn2fO3T2xckksQ9pk3RUNPxZqqq2CyaifXnju0lCCpbfwJ4gZyq-df0kM_mK1TMV0F9YCMo19Ba9NvFAiUpzDH6Wlk_RyonRCK5Ono25CYyQ7xGC3q70mUhyphenhyphenOOYJ-5JX2KlFP1lIA3ULIhH86_hP2ptO0AllUIf6ZVh-SqoXVWcXrM8m3hHCkhGwZYfP4/s8583/AFD%20-%20%5BABL_101%5D%20Building%20AI%20features%20in%20Jetpacker%20Features%20with%20Firebase%20AI%20Logic%20_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn2fO3T2xckksQ9pk3RUNPxZqqq2CyaifXnju0lCCpbfwJ4gZyq-df0kM_mK1TMV0F9YCMo19Ba9NvFAiUpzDH6Wlk_RyonRCK5Ono25CYyQ7xGC3q70mUhyphenhyphenOOYJ-5JX2KlFP1lIA3ULIhH86_hP2ptO0AllUIf6ZVh-SqoXVWcXrM8m3hHCkhGwZYfP4/s1600/AFD%20-%20%5BABL_101%5D%20Building%20AI%20features%20in%20Jetpacker%20Features%20with%20Firebase%20AI%20Logic%20_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Welcome back to the blog post series "&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html" target="_blank"&gt;Build intelligent Android apps&lt;/a&gt;" where we take a basic Android app and transform it into a &lt;b&gt;personalized&lt;/b&gt;, &lt;b&gt;intelligent&lt;/b&gt;, and &lt;b&gt;agentic&lt;/b&gt; experience. In our &lt;a href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html"&gt;previous post&lt;/a&gt; we explored how to build intelligent on-device features using Gemini Nano through ML Kit's Prompt API.&lt;/p&gt;

&lt;p&gt;In this post, we will look at how you can leverage &lt;b&gt;&lt;a href="https://firebase.google.com/docs/ai-logic"&gt;Firebase AI Logic&lt;/a&gt; &lt;/b&gt;to build cloud-hosted and hybrid AI features:&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Grounding answers in real-world context&lt;/li&gt;
  &lt;li&gt;Routing requests dynamically between cloud and local execution using hybrid inference&lt;/li&gt;
  &lt;li&gt;Translating content with custom routing systems&lt;/li&gt;
&lt;/ul&gt;

&lt;div style="margin: 0px auto; width: 100%;"&gt;
  &lt;iframe allowfullscreen="" src="https://www.youtube.com/embed/_iuXykdlTkk" style="aspect-ratio: 16/9; border: 0; width: 100%;"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Sometimes a use case requires AI models with greater world knowledge, a much larger context window, or the ability to handle complex queries. In those scenarios, we can leverage cloud models.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Other times, you want the best of both worlds: using hybrid inference to run on-device when available to lower costs, while falling back to the cloud to ensure compatibility for all devices.&lt;/p&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwlTUF1Kzkbrf2w64KO3jZJZZ_wLEu34vq6Cb7PX2alVUhFVdbkiWuXCkzUS-bPJkHMbmuNJ_Ov0HYZzujr69jCU9gPvmKaKMZt2q4-TolSDFCLABBIY1IBRY9Zn7D5S10hFcJD2kuVCm3N2glpqDJoHiqAZat4z6oyXxxwH4ZCGVBgfPObMevoJrgNPg/s8000/features_upscaled.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="4744" data-original-width="8000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwlTUF1Kzkbrf2w64KO3jZJZZ_wLEu34vq6Cb7PX2alVUhFVdbkiWuXCkzUS-bPJkHMbmuNJ_Ov0HYZzujr69jCU9gPvmKaKMZt2q4-TolSDFCLABBIY1IBRY9Zn7D5S10hFcJD2kuVCm3N2glpqDJoHiqAZat4z6oyXxxwH4ZCGVBgfPObMevoJrgNPg/s1600/features_upscaled.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;em style="text-align: left;"&gt;Cloud and hybrid features in Jetpacker: Museum assistant with web grounding, hybrid restaurant review drafting, and&amp;nbsp;
  support chat featuring custom-routed live translation.&lt;/em&gt;&lt;/div&gt;

&lt;p&gt;Let’s look at how we implemented three cloud and hybrid features in &lt;a href="https://github.com/android/ai-samples/tree/main/jetpacker" target="_blank"&gt;Jetpacker&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;a museum assistant with web grounding&lt;/li&gt;
  &lt;li&gt;hybrid restaurant review drafting&lt;/li&gt;
  &lt;li&gt;hotel support chat featuring custom-routed live translation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Use LLM grounding for up-to-date informationMuseum assistant chatbot with LLM grounding&lt;/h2&gt;
&lt;p&gt;The &lt;b&gt;Museum assistant &lt;/b&gt;is an interactive chatbot designed to help users plan their museum visits. It provides visitors with up-to-date details regarding specific exhibits, current opening hours, ticket pricing, and more.&lt;/p&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em style="text-align: left;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pxeCVJfOo5G7McNB4RCIhoCUch8CHSAWI7gHijJJcE95b0gbu3lyAO1xIWc6mKllkpylSPBnVfU6RYnwfay4z6dH7TlufPuNw3Lw7s-bEuR4Ajx8IHK8k6zJcOHitqMRdDv8EVL-fCN6uuDo1QTnOgk_RW-AEM1_hZaJWbCGezMQF_D9Hia-Rm2T4-c/s4880/museum_assistant_upscaled.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="4880" data-original-width="2392" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3pxeCVJfOo5G7McNB4RCIhoCUch8CHSAWI7gHijJJcE95b0gbu3lyAO1xIWc6mKllkpylSPBnVfU6RYnwfay4z6dH7TlufPuNw3Lw7s-bEuR4Ajx8IHK8k6zJcOHitqMRdDv8EVL-fCN6uuDo1QTnOgk_RW-AEM1_hZaJWbCGezMQF_D9Hia-Rm2T4-c/w314-h640/museum_assistant_upscaled.png" width="314" /&gt;&lt;/a&gt;&lt;/div&gt;Museum assistant is a chatbot that answers questions, such as&amp;nbsp;&lt;/em&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em style="text-align: left;"&gt;‘How can I get a ticket discount for Le Louvre?’&lt;/em&gt;&lt;/div&gt;

&lt;p&gt;When building AI features, getting the model to answer with fresh, accurate, and specific real-world information is a common challenge. While cloud models possess massive amounts of world knowledge, they might not know about seasonal exhibits or the current day’s opening hours.&amp;nbsp;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8He5M2JC5EwXZwa-M52UAXHSO4dWy4gx3aZoY2ZXM-x25pV4kc6BsICe_fG4Zn6-R37_UgTQ8LBSsrNcP50e3aQLgxNbHOfWLBqzaSqQ78ZDmNEJadZNc-I5bduHr0UtWOxYMTFAHgffxcuzaETHPe3lvfRod2rkeOUXnRaLJ_vIiAfO_xRKpESbX3L8/s8000/grounding_upscaled.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="4452" data-original-width="8000" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8He5M2JC5EwXZwa-M52UAXHSO4dWy4gx3aZoY2ZXM-x25pV4kc6BsICe_fG4Zn6-R37_UgTQ8LBSsrNcP50e3aQLgxNbHOfWLBqzaSqQ78ZDmNEJadZNc-I5bduHr0UtWOxYMTFAHgffxcuzaETHPe3lvfRod2rkeOUXnRaLJ_vIiAfO_xRKpESbX3L8/s1600/grounding_upscaled.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;em style="text-align: left;"&gt;&lt;br /&gt;Grounding data is added to the context window to enable the model&lt;/em&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em style="text-align: left;"&gt;&amp;nbsp;to answer questions correctly and accurately.&lt;/em&gt;&lt;/div&gt;

&lt;p&gt;To bridge this gap, we can use grounding techniques to add extra context to the model’s context window. The &lt;a href="https://firebase.google.com/products/firebase-ai-logic" target="_blank"&gt;Firebase AI Logic SDK&lt;/a&gt; supports three types of grounding:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href="https://firebase.google.com/docs/ai-logic/url-context"&gt;URL grounding&lt;/a&gt;:&lt;/strong&gt; Grounding responses using content from a specific webpage (e.g. current ticket prices or museum rules).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href="https://firebase.google.com/docs/ai-logic/grounding-google-search"&gt;Google Search grounding&lt;/a&gt;:&lt;/strong&gt; Letting the model query the real-time Google search index for up-to-date details.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href="https://firebase.google.com/docs/ai-logic/grounding-google-maps"&gt;Maps grounding&lt;/a&gt;:&lt;/strong&gt; Using Google Maps location data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Jetpacker, we dynamically construct the available tools based on enabled feature flags and initialize the generative model using the Firebase AI SDK:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// implementation("com.google.firebase:firebase-ai-logic")

private var toolList = mutableListOf&amp;lt;Tool&amp;gt;()

init {
    if (ENABLE_SEARCH_GROUNDING) {
        toolList.add(Tool.googleSearch())
    }
    if (ENABLE_URL_GROUNDING) {
        toolList.add(Tool.urlContext())
    }
}

private val generativeModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3-flash",
        systemInstruction = content {
            text("You are a helpful museum assistant answering questions about a museum. Use plain text.")
        },
        tools = toolList
    )&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When the user queries the assistant, if URL grounding is enabled, we append the specific museum resource URLs directly into the prompt:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;val groundingText = if (FeatureFlags.ENABLE_URL_GROUNDING) {
    "\n If the following message above is about the rules and terms to visit Le Louvre, " +
    "if needed answer this urls ${urlList.joinToString()}"
} else {
    ""
}

val prompt = "$text $groundingText"

var response = chat.sendMessage(prompt)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Hybrid inference: On-device review generation with Maps deep link&lt;/h2&gt;
&lt;p&gt;Not every AI task requires a cloud-based model, and not every device is online. To help developers balance latency, cost, and offline availability, we recently introduced the &lt;a href="https://firebase.google.com/docs/ai-logic/hybrid/android/get-started?api=dev"&gt;Firebase API for Hybrid Inference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In Jetpacker, the &lt;b&gt;restaurant review&lt;/b&gt; feature lets users review select topics and automatically drafts a review. To enable this for all users, we prioritize local execution with Gemini Nano, and fall back to cloud models on devices that don’t support Gemini Nano.&amp;nbsp;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVa1o2Zh3v3Babi7gGmzOFYAKPEgS0HWmvisiKgK-QsSRh_ZhjTjuUYSS_QIH0JQw9NsqrkYe4Quud6cfCGwVc61_7HKcACj6c9yywWySn5xyHGgemBR5tYPP8q3bmLadaN6uLXspE9LqrcZkVdckEGHWDhdfYVa-xo8QomDaRn03mau2fHVyK0Fr1FaU/s4680/review_upscaled.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="4680" data-original-width="2392" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVa1o2Zh3v3Babi7gGmzOFYAKPEgS0HWmvisiKgK-QsSRh_ZhjTjuUYSS_QIH0JQw9NsqrkYe4Quud6cfCGwVc61_7HKcACj6c9yywWySn5xyHGgemBR5tYPP8q3bmLadaN6uLXspE9LqrcZkVdckEGHWDhdfYVa-xo8QomDaRn03mau2fHVyK0Fr1FaU/w327-h640/review_upscaled.png" width="327" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em&gt;The restaurant review feature uses hybrid inference to draft a review based on topics&lt;/em&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/div&gt;

&lt;pre&gt;&lt;code&gt;// implementation("com.google.firebase:firebase-ai-logic")
// implementation("com.google.firebase:firebase-ai-ondevice:16.0.0-beta03")


// Initialize the model with hybrid routing configuration
val reviewModel = Firebase.ai.generativeModel(
    modelName = "gemini-3.1-flash-lite",
    onDeviceConfig = OnDeviceConfig(
        inferenceMode = InferenceMode.PREFER_ON_DEVICE
    )
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Hybrid Inference API supports four distinct routing modes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;PREFER_ON_DEVICE:&lt;/strong&gt; Prioritizes local execution and falls back to cloud if Gemini Nano is unavailable.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PREFER_IN_CLOUD:&lt;/strong&gt; Prioritizes cloud execution and falls back to on-device if the device goes offline.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ONLY_ON_DEVICE:&lt;/strong&gt; Restricts execution strictly to the device.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ONLY_IN_CLOUD:&lt;/strong&gt; Restricts execution strictly to the cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the review is generated, we copy it to the clipboard and use an intent to open Google Maps directly to the restaurant's review page, providing a seamless user experience:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private fun copyAndOpenMapsReview(context: Context, reviewText: String, placeId: String) {
    val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clip = ClipData.newPlainText("User Review", reviewText)
    clipboard.setPrimaryClip(clip)

    val uri = Uri.parse("https://search.google.com/local/writereview/mobile?placeid=$placeId")
    val intent = Intent(Intent.ACTION_VIEW, uri).apply {
        setPackage("com.google.android.apps.maps")
    }
    context.startActivity(intent)
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Custom hybrid routing: Hotel support chat translation with simulated personas&lt;/h2&gt;
&lt;p&gt;The &lt;b&gt;hotel support chat&lt;/b&gt; was built to let users finalize logistics and check on hotel details. This feature uses system instructions to configure a localized receptionist assistant. By passing specific information—such as the preferred language and hotel information—in the instructions, we can set up a conversational persona representing a specific hotel.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private val generativeModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        systemInstruction = content {
            text("""
              You are a helpful hotel receptionist at $hotelName only speaking $language. 
              Answer politely in $language. The bar closes at 10pm and breakfast is from 7am to 10am.
              There's someone at the desk 24/7. You can retrieve your luggage from the storage room 
              at the back of the lobby at any time.
              """)
        },
        modelName = "gemini-3-flash-preview"
    )&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because receptionist responses are in the hotel's local language (for example, French for Hotel Le Meurice in Paris), we need to translate messages to the user’s preferred language.&amp;nbsp;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikIB_NnUYK8GnEpI3foNLO2_AQ2lNZhoc9gFB-CjERDjMwrdQ2T45y6jzrJAafi4Jz7eF_SBkXG7csDwpajKctp5yo1hsBjIacIfK3aHvvQjCUu22qZBj7dLl5Q4aGFJRD4hwTlMMNgZD8sIuYpCrRjMmpa5ybXDzi9nkTMZoiJOEn8jLmqBsgTXcVTDY/s4112/translation_upscaled.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2364" data-original-width="4112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikIB_NnUYK8GnEpI3foNLO2_AQ2lNZhoc9gFB-CjERDjMwrdQ2T45y6jzrJAafi4Jz7eF_SBkXG7csDwpajKctp5yo1hsBjIacIfK3aHvvQjCUu22qZBj7dLl5Q4aGFJRD4hwTlMMNgZD8sIuYpCrRjMmpa5ybXDzi9nkTMZoiJOEn8jLmqBsgTXcVTDY/s1600/translation_upscaled.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em&gt;Hotel support chat messages are automatically translated to the user’s preferred language&amp;nbsp;&lt;/em&gt;&lt;/div&gt;&lt;/em&gt;&lt;/div&gt;

&lt;p&gt;While hybrid models can configure simple routing preferences, complex scenarios require custom routing logic. In Jetpacker, we implement a custom routing stack that takes into account:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Language identification:&lt;/strong&gt; Using the on-device &lt;a href="https://developers.google.com/ml-kit/language/identification/android"&gt;ML Kit Language Identification API&lt;/a&gt;, we can detect the incoming message language.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;On-device translation (Gemini Nano):&lt;/strong&gt; &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android"&gt;ML Kit’s Prompt API&lt;/a&gt; lets us translate common language pairs directly on the device, saving bandwidth and cloud cost.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cloud translation (Gemini 3 Flash):&lt;/strong&gt; For more complex languages, we use Gemini Flash 3 to get a higher quality translation.&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code&gt;// implementation("com.google.android.gms:play-services-mlkit-language-id:17.0.0")&amp;nbsp;

// ML Kit for Language Identification (powered by Google Play Services)
private val languageIdentifier = LanguageIdentification.getClient()

// On-device translator model (prefer Gemini Nano) for translating common language pairs
private val hybridTranslationModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3-flash",
        onDeviceConfig = OnDeviceConfig(mode = InferenceMode.PREFER_ON_DEVICE)
    )

// Cloud translator model for more complex language pairs
private val cloudTranslationModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3-flash"
    )&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When a message needs to be translated, we identify the source language and apply our custom routing logic, executing either on-device or cloud translation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fun translateMessage(message: SupportChatMessage) {
    viewModelScope.launch {
        // 1. Detect language using ML Kit Language Identification
        val sourceLang = try {
            Tasks.await(languageIdentifier.identifyLanguage(message.text))
        } catch (e: Exception) {
            "Undefined"
        }

        // 2. Custom routing: we've verified the translation quality for English and Korean with Gemini Nano, and will translate message on-device for those two languages
        val routeToCloud = sourceLang != "en" &amp;amp;&amp;amp; sourceLang != "kr"

        val prompt = "Translate the following text to $selectedLanguage. Just return the translated sentence: ${message.text}."

        val (translatedText, routePrefix) = if (routeToCloud) {
            val result = cloudTranslationModel.generateContent(prompt)
            result.text to "[Cloud]"
        } else {
            val result = hybridTranslationModel.generateContent(prompt)
            result.text to "[On-Device]"
        }

        if (translatedText != null) {
            _translations.update { current -&amp;gt;
                current + (message.id to "$routePrefix: $translatedText")
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example, the custom routing logic only takes into consideration the translation’s source and target language. However, based on your app’s use case, you can expand the routing logic to include other factors such as the on-device model version, network connectivity, battery status, and more.&lt;/p&gt;

&lt;h2&gt;Securing the AI Pipelines: Firebase App Check&lt;/h2&gt;
&lt;p&gt;Lastly, using AI in the cloud opens up possibilities of API key abuse or unauthorized billing. To secure API calls, we integrated &lt;a href="https://firebase.google.com/docs/app-check"&gt;&lt;b&gt;Firebase App Check&lt;/b&gt;&lt;/a&gt; using both Play Integrity (production) and the local Debug Provider (for local development or emulators).&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://github.com/android/ai-samples/blob/main/jetpacker/android/app/src/main/kotlin/com/example/jetpacker/JetPackerApplication.kt"&gt;JetPackerApplication.kt&lt;/a&gt; file, we install the debug provider at startup and trigger anonymous authentication to establish a secure user session:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;//  implementation("com.google.firebase:firebase-appcheck-playintegrity")&amp;nbsp;
//  implementation("com.google.firebase:firebase-appcheck-debug")&amp;nbsp;&amp;nbsp;
//  implementation("com.google.firebase:firebase-auth")&amp;nbsp;

override fun onCreate() {
    super.onCreate()
    Firebase.initialize(context = this)
    Firebase.appCheck.installAppCheckProviderFactory(
        DebugAppCheckProviderFactory.getInstance()
    )
    Firebase.auth.signInAnonymously()
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When building locally on an emulator, App Check prints a local token secret to logcat:&lt;/p&gt;

&lt;p&gt;Enter this debug secret into the allow list in the Firebase Console: a8c2dd4c-xxxx-xxxx-xxxx-ef6c114ba27e&lt;/p&gt;

&lt;p&gt;Once registered in the Firebase console, local requests are fully verified and authenticated by App Check, protecting our backend while letting us test the app locally.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;By combining cloud model capabilities (grounding, system instructions) with on-device capabilities (hybrid routing, translation, security app checks), we created a travel app that is smart, secure, and available offline.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/android/ai-samples/tree/main/jetpacker" target="_blank"&gt;full source code for Jetpacker on GitHub&lt;/a&gt;, and explore the Firebase documentation to get started:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://firebase.google.com/docs/ai-logic/get-started"&gt;Firebase AI Logic Documentation&lt;/a&gt;&lt;br /&gt;&lt;a href="https://firebase.google.com/docs/ai-logic/hybrid/android/get-started"&gt;Firebase Hybrid Inference API&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out the other parts of this blog post series:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html"&gt;Part 1&lt;/a&gt;:&lt;/b&gt; Introduction of the app and a high-level overview.&lt;br /&gt;&lt;b&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html"&gt;Part 2&lt;/a&gt;: &lt;/b&gt;On-device intelligence. Deep-dive into ML Kit’s GenAI APIs and Gemini Nano to build privacy-first features like itinerary summarization, receipt parsing, and local audio processing.&lt;br /&gt;&lt;b&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html"&gt;Part 3 (this post!):&lt;/a&gt;&lt;/b&gt; Hybrid and cloud reasoning. Explore how to use Firebase AI Logic to ground LLM answers in real-world data like Google Maps and web context.&lt;br /&gt;&lt;b&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html"&gt;Part 4:&lt;/a&gt; &lt;/b&gt;System integration. Integrating with the Android intelligence system using AppFunctions.&amp;nbsp;&lt;br /&gt;&lt;b&gt;Part 5 (coming soon):&lt;/b&gt; In-app agentic workflows. Extend the app with an end-to-end booking assistant powered by A2UI and ADK.&lt;/p&gt;

&lt;p&gt;Interested in more on Android Development? Follow Android Developers on &lt;a href="https://www.youtube.com/@AndroidDevelopers"&gt;YouTube&lt;/a&gt; or &lt;a href="https://www.linkedin.com/showcase/androiddev/"&gt;LinkedIn&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;All code snippets in this blog post follow the following copyright notice:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0&lt;/code&gt;&lt;/pre&gt;</content><link href="http://android-developers.googleblog.com/feeds/1633372972504974395/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/1633372972504974395" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/1633372972504974395" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html" rel="alternate" title="Build intelligent Android apps: Cloud and hybrid inference" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBHTpa22SxEltoebLZYO_34iRtahN8z5tA3tnIryIii0s4_conN5qFYfmNro6nmZBfsgiZeRLtru-gE4XO2mf-RBDyIo00kf3QunWwUO-SICHkVSv0exAQQ4qA0KzjMGRpA8qj1TSMP0Ffe0FzrEc_S1zBaakKzCZFpqYLXqds9Zqmqr8yyeSgyNl9U0s/s72-c/features%20in%20Jetpacker%20Features%20with%20Firebase%20AI%20Logic%20_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-5691330950466150364</id><published>2026-07-21T06:00:00.000-07:00</published><updated>2026-07-23T11:47:25.264-07:00</updated><title type="text">Build intelligent Android apps: Integrate into Android's intelligence system using AppFunctions</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi961epgT3N_Za_k2-pCJ30tegn7DM-Umh1LWh7Q4NxhryR5H57JB00zKQcek56ccAvEM95i6wyXWWCZZ7486_Gq1ewxPHtsMY13UVsVTmndAvkOJtHPjUXuZ3XW_yBEFtlOr2ocBFIKr0PCRZhIRs67h6bX6zDKihwcxQs8bGbYTqIp5azuBKcX4PNMMY/s2469/AFD%20-%20%5BABL_104%5D%20JetPacker%20AppFunctions_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi961epgT3N_Za_k2-pCJ30tegn7DM-Umh1LWh7Q4NxhryR5H57JB00zKQcek56ccAvEM95i6wyXWWCZZ7486_Gq1ewxPHtsMY13UVsVTmndAvkOJtHPjUXuZ3XW_yBEFtlOr2ocBFIKr0PCRZhIRs67h6bX6zDKihwcxQs8bGbYTqIp5azuBKcX4PNMMY/s2469/AFD%20-%20%5BABL_104%5D%20JetPacker%20AppFunctions_Meta.png" style="display: none;" /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;Posted by Ben Weiss, Senior Developer Relations Engineer,&amp;nbsp;Android Developer Relations&lt;/i&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi92OFxAOxVMpResmBcBoUfxzgcMmVOMn3mXQabB9O-xkC7pjYxrvXS7YLTEWLIBstwuDLc0ePCC-Tf7AKq62mgAXjSYg9-VUIjKvokK6BhGHqPDSXCTQowbpj40plsP3V3Ju3ck4gzNdJmGQ6C1-twuob2UnPu7oY9B_oSwnYSkaif7lSEMwFnStzWknM/s8583/AFD%20-%20%5BABL_104%5D%20JetPacker%20AppFunctions_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi92OFxAOxVMpResmBcBoUfxzgcMmVOMn3mXQabB9O-xkC7pjYxrvXS7YLTEWLIBstwuDLc0ePCC-Tf7AKq62mgAXjSYg9-VUIjKvokK6BhGHqPDSXCTQowbpj40plsP3V3Ju3ck4gzNdJmGQ6C1-twuob2UnPu7oY9B_oSwnYSkaif7lSEMwFnStzWknM/s1600/AFD%20-%20%5BABL_104%5D%20JetPacker%20AppFunctions_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Welcome back to the blog post series "&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html" target="_blank"&gt;Build intelligent Android apps&lt;/a&gt;" where we take a basic Android app and transform it into a personalized, intelligent, and agentic experience. In our &lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html"&gt;previous post&lt;/a&gt;,&amp;nbsp;we explored how to leverage Firebase AI Logic to build cloud-hosted and hybrid AI features.&lt;/p&gt;Traditional mobile UIs excel at focused, hands-on tasks, and the Android intelligence system is introducing complementary features to make complex, multi-step actions even easier. By supplementing traditional user interfaces, AppFunctions provide a powerful new entry point: A privileged agent on the device can access app features in the background. This can be particularly helpful when users are driving, walking or otherwise multitasking. 

&lt;p&gt;In this article, we'll show you how we designed and integrated these capabilities into our travel planning app, &lt;a href="https://github.com/android/ai-samples/tree/main/jetpacker"&gt;JetPacker&lt;/a&gt;, using Android AppFunctions. We'll explore the rationale behind our feature choices, discuss the specialized tooling we used to accelerate development, and dive into the code that makes it all work.&lt;/p&gt;

&lt;h2&gt;Designing AI-ready features: making choices that matter for your users&lt;/h2&gt;

&lt;p&gt;To select which features to provide to the intelligence system, we looked for tasks where a voice or text command is objectively faster than tapping through screens. In this side-by-side screen recording you can see this contrast perfectly: on the left, a user tapping through multiple screens to log an expense; on the right, the same task completed instantly in the background via a privileged agent.&lt;/p&gt;

&lt;div class="vertical-video-grid"&gt;
  &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIr2ssY2GiOlBmFzcP-91j91VjH9QX_sOP8FcmtirYPyXZmYRzNJmfqI_GT6aXYXye8-ntylv-gTNu1Qlnbx5gHiFn9naHqt7tJOQBA3HpQ5uz8XRdavXh7b3IP3FzJb4SsbC4mClGLUHupDwIeE9Du3PNRQr0SGs2lgHZTdHXnv8TagNBRtoJsbpeE6c/s960/Comp%201.gif" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="540" data-original-width="960" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIr2ssY2GiOlBmFzcP-91j91VjH9QX_sOP8FcmtirYPyXZmYRzNJmfqI_GT6aXYXye8-ntylv-gTNu1Qlnbx5gHiFn9naHqt7tJOQBA3HpQ5uz8XRdavXh7b3IP3FzJb4SsbC4mClGLUHupDwIeE9Du3PNRQr0SGs2lgHZTdHXnv8TagNBRtoJsbpeE6c/s1600/Comp%201.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="vertical-video-wrapper"&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Our first choice was expense tracking. Logging a coffee expense during a trip usually takes quite a few taps—unlocking the phone, opening the app, finding the active trip, navigating to the expenses tab, tapping the add button, taking a picture of the receipt, and checking the result. By providing the &lt;code&gt;addExpense&lt;/code&gt; and &lt;code&gt;getExpenses&lt;/code&gt; features as AppFunctions, the system agent handles the heavy lifting. When the user says, "Add a five-dollar coffee expense to my Paris trip," the agent automatically searches for the correct trip ID in the background and inserts the expense, skipping the manual UI flow entirely.&lt;/p&gt;

&lt;p&gt;We also prioritized itinerary management. Finding what activity is next on a busy trip itinerary usually requires scrolling through a dense timeline view. By providing &lt;code&gt;getItinerary&lt;/code&gt; and &lt;code&gt;addItineraryEvent&lt;/code&gt; to the system, the user can simply ask, "What am I doing next in Paris?" and get an immediate answer.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRduisOXPFs0o2m-JwtESU1fUEanqH-A0eGt58MUuXs-vgN1af77M-j3ETdegzulBq-3TClrDvhO2K_8q4ep8xAlnW1y5T09ZxxHyZmTRtftA9DOmIk7ykfM_JihQ2c2fcUbEA-jCO1sgW2JnxN9qtB8IS58lbQoaIk4cPJPuPQavZNUoW2rNKo9r8g9M/s960/Comp%202.gif" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="540" data-original-width="960" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRduisOXPFs0o2m-JwtESU1fUEanqH-A0eGt58MUuXs-vgN1af77M-j3ETdegzulBq-3TClrDvhO2K_8q4ep8xAlnW1y5T09ZxxHyZmTRtftA9DOmIk7ykfM_JihQ2c2fcUbEA-jCO1sgW2JnxN9qtB8IS58lbQoaIk4cPJPuPQavZNUoW2rNKo9r8g9M/s1600/Comp%202.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
  

&lt;p&gt;Finally, we focused on hands-free note capturing. Typing out reminders or notes while walking down a busy street is difficult and unsafe. Exposing a voice note capability allows the user to say, "The flight was amazing, I saw a beautiful sunset and managed to sleep well," and the privileged agent automatically transcribes and saves it directly into the travel database&amp;nbsp;&lt;span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;&amp;nbsp;using the &lt;/span&gt;&lt;span style="color: #188038; font-family: &amp;quot;Roboto Mono&amp;quot;, monospace; font-size: 11pt; font-variant: normal; vertical-align: baseline; white-space: pre-wrap;"&gt;addVoiceNote&lt;/span&gt;&lt;span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant: normal; vertical-align: baseline; white-space: pre-wrap;"&gt; AppFunction.&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;Android MCP powered by AppFunctions&lt;/h2&gt;This entire experience is built on Android MCP. Under this design, the app acts as a local MCP server. Rather than remote APIs, you provide your app features directly to the on-device intelligence system.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://d.android.com/ai/appfunctions"&gt;Android AppFunctions&lt;/a&gt; is the API that brings this concept to life. It reads annotated Kotlin functions and compiles them into type-safe, sandboxed tool definitions that the privileged agent can discover and invoke locally on the device.&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjypEvh8lAK1myAWpnG4A0TtdIaTxP69t7g9croAJSUZ2Od6AEkhwMusN3CvdGohdvYzoh1UaCxCHb22oJzCD_4B2K8vfQzcyAIaTl8lk3TCR9T0SoMHjjaDk4GMxxPazeCfT0aF7rifm7-LAvcMhyphenhyphenryDJpOPYon7jiISKB2sMLzAwHDuKFxIv16sDXjrM/s2500/Android%20MCP%20diagram.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1406" data-original-width="2500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjypEvh8lAK1myAWpnG4A0TtdIaTxP69t7g9croAJSUZ2Od6AEkhwMusN3CvdGohdvYzoh1UaCxCHb22oJzCD_4B2K8vfQzcyAIaTl8lk3TCR9T0SoMHjjaDk4GMxxPazeCfT0aF7rifm7-LAvcMhyphenhyphenryDJpOPYon7jiISKB2sMLzAwHDuKFxIv16sDXjrM/s1600/Android%20MCP%20diagram.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;i&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;Diagram highlighting our apps, the android platform, and system agents coordinate AppFunctions.&lt;/i&gt;&lt;/div&gt;&lt;/i&gt;&lt;p&gt;Under the Android MCP model, your app acts as a local MCP server that exposes structured tools, while the Android platform serves as the central tool registry. On the MCP client side, agent apps are registered with the intelligence system after being granted system-privileged permissions to access the registry.&lt;/p&gt;

&lt;p&gt;When a user interacts with a registered agent, its LLM determines if the request can be handled by an AppFunction, queries the platform's metadata, and executes the appropriate registered functions in the background. This local MCP client-server design gives you full control: you choose exactly which features are accessible to the agent, keeping the rest of your app's data private.&lt;/p&gt;

&lt;h2&gt;How we accelerated development with Android skills&lt;/h2&gt;

To streamline the integration process, we leveraged the &lt;a href="https://github.com/android/skills/tree/main/device-ai/appfunctions"&gt;AppFunctions development skill&lt;/a&gt;. The AppFunctions development skill is a complete development companion. It guided us through the entire lifecycle: mapping Kotlin data classes to serialize parameters, generating the necessary &lt;code&gt;Service&lt;/code&gt; entry points, refining our &lt;code&gt;KDoc&lt;/code&gt; documentation to ensure the LLM understands parameter boundaries, and setting up automated testing using ADB.

&lt;h2&gt;Providing app features to the intelligence system&lt;/h2&gt;

&lt;p&gt;Enough with the theory, let's dive into the implementation.&lt;/p&gt;

&lt;h4&gt;Configuration and dependency setup&lt;/h4&gt;

&lt;p&gt;We begin by adding the AppFunctions dependencies. One for the API and one for the Kotlin Symbol Processing compiler.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;implementation("androidx.appfunctions:appfunctions:1.0.0-alpha10")
ksp("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha10")&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Modeling custom data types&lt;/h4&gt;

&lt;p&gt;Any custom object exchanged with the agent must be annotated with &lt;code&gt;@AppFunctionSerializable&lt;/code&gt;. In our &lt;a href="https://github.com/android/ai-samples/tree/main/jetpacker/android/feature/appfunctions/src/main/java/com/example/jetpacker/feature/appfunctions/TripSerializable.kt"&gt;TripSerializable.kt&lt;/a&gt; file, we define our trip data model:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@AppFunctionSerializable(isDescribedByKDoc = true)
data class TripSerializable(
    /** The trip's unique identifier. */
    val id: String,
    /** The trip's title. */
    val title: String,
    /** The trip's destination location. */
    val location: String,
    /** The trip's start date in milliseconds. */
    val startDate: Long,
    /** The trip's end date in milliseconds. */
    val endDate: Long,
    /** A list of participants. */
    val participants: List&amp;lt;String&amp;gt;,
)&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Providing features using the @AppFunction annotation&lt;/h4&gt;

&lt;p&gt;Next, the skill wrote the Kotlin functions that perform the database queries and annotate them with &lt;code&gt;@AppFunction&lt;/code&gt;. We can view this in searchTrip:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/**
 * Looks for trips based on optional filters like id, title (name), location, and dates.
 *
 * @param id The unique identifier of the trip.
 * @param title The title or name of the trip.
 * @param location The destination location.
 * @param startDate The minimum start date in milliseconds.
 * @param endDate The maximum end date in milliseconds.
 * @return A list of trips matching the filters.
 */
@AppFunction(isDescribedByKDoc = true)
suspend fun searchTrip(
    id: String? = null,
    title: String? = null,
    location: String? = null,
    startDate: Long? = null,
    endDate: Long? = null
): List&amp;lt;TripSerializable&amp;gt; {
    return withContext(Dispatchers.IO) {
    // implementation
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since AppFunctions run on the UI thread by default, we use &lt;code&gt;withContext(Dispatchers.IO)&lt;/code&gt; to switch to a background dispatcher. Additionally, we refine our KDoc to use clear, imperative verbs and specify parameter constraints. This documentation compiles directly into the tool's schema, which the privileged agent uses to resolve parameters and handle runtime errors.&lt;/p&gt;

&lt;h4&gt;The service entry point and Hilt integration&lt;/h4&gt;

&lt;p&gt;To register these features with the intelligence system, we create an abstract base class that extends &lt;code&gt;AppFunctionService&lt;/code&gt;. We annotate it with &lt;code&gt;@AppFunctionServiceEntryPoint&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@RequiresApi(36)
@AndroidEntryPoint
@AppFunctionServiceEntryPoint(
    serviceName = "JetPackerAppFunctionService",
    appFunctionXmlFileName = "jetpacker_app_function_service"
)
abstract class BaseJetPackerAppFunctionService : AppFunctionService() {
    @Inject internal lateinit var tripDao: TripDao
    // DAOs and database references are injected here...
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;During compilation, KSP generates the final concrete service subclass, &lt;code&gt;JetPackerAppFunctionService&lt;/code&gt;, as declared with the &lt;code&gt;serviceName&lt;/code&gt; parameter. We also register &lt;code&gt;app_metadata.xml&lt;/code&gt; in the app's manifest. This file provides global operational rules for JetPacker's declared AppFunctions.&lt;/p&gt;

&lt;h2&gt;Testing and verifying your AppFunctions&lt;/h2&gt;

&lt;p&gt;Once implemented, you should verify that your AppFunctions are registered and working correctly.&lt;/p&gt;

&lt;p&gt;Running devices or emulators with Android 17 or newer, you can use ADB commands from your terminal to list and invoke your functions. Running &lt;code&gt;adb shell cmd app_function list-app-functions&lt;/code&gt; displays all registered functions for your package. You can then execute a specific function and test its database integration by running &lt;code&gt;adb shell cmd app_function execute-app-function&lt;/code&gt; while passing a raw JSON parameters string.&lt;/p&gt;

&lt;p&gt;Instead of these ADB commands, you can also use the &lt;a href="https://github.com/android/appfunctions"&gt;AppFunctions Testing Agent&lt;/a&gt; to inspect your configuration, list and execute AppFunctions, and even see how your AppFunctions behave in a real conversational flow.&lt;/p&gt;

&lt;h2&gt;Wrapping it up&lt;/h2&gt;

&lt;p&gt;When thinking about app features that can be contributed to the intelligence system using AppFunctions requires a slight shift in how we think about code and documentation. AppFunctions enable you to use this new interaction model for apps, which allows using an agent to access app features..&lt;/p&gt;

&lt;p&gt;First, the &lt;a href="https://github.com/android/skills/tree/main/device-ai/appfunctions"&gt;AppFunctions development skill&lt;/a&gt; is an essential lifecycle tool, helping you discover features, implement and refine AppFunctions for your apps. Second, KDoc comments are a compiled API asset; clear parameter descriptions directly impact the execution accuracy of the system agent. Finally, Android MCP provides local-first execution allowing apps to safely collaborate with AI agents.&lt;/p&gt;

&lt;p&gt;Contributing app features through AppFunctions makes your application ready for the intelligence system. Let us know how you are adapting your apps for the agentic era!&lt;/p&gt;

&lt;h2&gt;Learn more&lt;/h2&gt;

&lt;p&gt;Check out the other parts of this blog post series:&lt;br /&gt;&lt;b&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html"&gt;Part 1:&lt;/a&gt;&lt;/b&gt; Introduction of the app and a high-level overview.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html"&gt;&lt;b&gt;Part 2:&lt;/b&gt;&lt;/a&gt; On-device intelligence. Deep-dive into ML Kit’s GenAI APIs and Gemini Nano to build privacy-first features like itinerary summarization, receipt parsing, and local audio processing.&lt;br /&gt;&lt;b&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html"&gt;Part 3:&lt;/a&gt;&lt;/b&gt; Hybrid and cloud reasoning. Explore how to use Firebase AI Logic to ground LLM answers in real-world data like Google Maps and web context.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html"&gt;&lt;b&gt;Part 4 (this post!):&lt;/b&gt;&lt;/a&gt; System integration. Integrating with the Android intelligence system using AppFunctions. &lt;br /&gt;Part 5 (coming soon):&amp;nbsp;In-app agentic workflows. Extend the app with an end-to-end booking assistant powered by A2UI and ADK.&lt;/p&gt;

&lt;p&gt;Interested in more on Android Development? Follow Android Developers on &lt;a href="https://www.youtube.com/@AndroidDevelopers"&gt;YouTube&lt;/a&gt; or &lt;a href="https://www.linkedin.com/showcase/androiddev/"&gt;LinkedIn&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;
  All code snippets in this blog post follow the following copyright notice:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/5691330950466150364/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/5691330950466150364" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/5691330950466150364" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html" rel="alternate" title="Build intelligent Android apps: Integrate into Android's intelligence system using AppFunctions" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi961epgT3N_Za_k2-pCJ30tegn7DM-Umh1LWh7Q4NxhryR5H57JB00zKQcek56ccAvEM95i6wyXWWCZZ7486_Gq1ewxPHtsMY13UVsVTmndAvkOJtHPjUXuZ3XW_yBEFtlOr2ocBFIKr0PCRZhIRs67h6bX6zDKihwcxQs8bGbYTqIp5azuBKcX4PNMMY/s72-c/AFD%20-%20%5BABL_104%5D%20JetPacker%20AppFunctions_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-6562467341747115358</id><published>2026-07-21T06:00:00.000-07:00</published><updated>2026-07-21T09:57:02.378-07:00</updated><title type="text">Build intelligent Android apps: Introduction to Jetpacker</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigBFwd7rJO49I_puODKBWFqPbpHaGyL3CTFuZBbr0HTQConFnc3JP0dL9Rr_i6wmyW0o4Ku2bvv3SEacwpC3Vc6b7cYy0aRbZKdUDudFcraYO8zcBVkrMfbrfMP9How0J1xSi91xLnR4s5Z3s-Lp6RF2SA0gU56B9nXD0NkD_CU8MT6wbgBw1tRaMWcMo/s2469/0713%20Jetpacker%20Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigBFwd7rJO49I_puODKBWFqPbpHaGyL3CTFuZBbr0HTQConFnc3JP0dL9Rr_i6wmyW0o4Ku2bvv3SEacwpC3Vc6b7cYy0aRbZKdUDudFcraYO8zcBVkrMfbrfMP9How0J1xSi91xLnR4s5Z3s-Lp6RF2SA0gU56B9nXD0NkD_CU8MT6wbgBw1tRaMWcMo/s2469/0713%20Jetpacker%20Meta.png" style="display: none;" /&gt;
&lt;div&gt;&lt;i&gt;Posted by Jolanda Verhoef, Senior Developer Relations Engineer,&amp;nbsp;&lt;/i&gt;&lt;i&gt;Android Developer Relations&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFlbIY8mjuSzlWuS8mnGJ3v8Je-yrtFFaBHNXumMqS0rbaS32wv5HUhI4mv5pHT8ro0Rfb-duyMhK8_OeKnMyocY9s6GmC9_pgTEv6sgZoiaZpD00sODTTctYV8I4RHddKWcXAMUyTASk97cS1ysx4A2PFYB6PEeiHeN93BFgDiOTKH62ZJMig3kGP66E/s8583/0713%20Jetpacker%20Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFlbIY8mjuSzlWuS8mnGJ3v8Je-yrtFFaBHNXumMqS0rbaS32wv5HUhI4mv5pHT8ro0Rfb-duyMhK8_OeKnMyocY9s6GmC9_pgTEv6sgZoiaZpD00sODTTctYV8I4RHddKWcXAMUyTASk97cS1ysx4A2PFYB6PEeiHeN93BFgDiOTKH62ZJMig3kGP66E/s1600/0713%20Jetpacker%20Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Building GenAI features in your app usually means navigating through various models, APIs and architecture choices:&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Execution location:&lt;/strong&gt; Where does your model run? On device, in the cloud, or both?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Complexity:&lt;/strong&gt; How complex is your setup? Are you doing a single inference call or do you need a more agentic flow?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;In-app or Android System:&lt;/strong&gt; Should your feature be built into your Android app or does it fit better as an Android system integration?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this blog post series we'll navigate these choices with you. We will take you along on a journey, starting with a basic mobile app and transforming it into a &lt;b&gt;personalized&lt;/b&gt;, &lt;b&gt;intelligent&lt;/b&gt;, and &lt;b&gt;agentic&lt;/b&gt; experience.&lt;/p&gt;

&lt;h2&gt;Jetpacker: a demo travel app&lt;/h2&gt;
&lt;p&gt;Jetpacker is a &lt;b&gt;technical showcase app&lt;/b&gt; that our team built from the ground up for this year's Google I/O (built using Antigravity). At its core, Jetpacker helps users plan, explore, and enjoy their next big adventure. It shows an overview of your trips, the itinerary of each trip, and details of each event on that trip. Of course following all best practices of Android development, including a beautifully expressive Material UI design.&lt;/p&gt;&lt;div style="height: 0px; max-width: 100%; overflow: hidden; padding-bottom: 56.25%; position: relative;"&gt;
  &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" src="https://www.youtube-nocookie.com/embed/_iuXykdlTkk" style="height: 100%; left: 0; position: absolute; top: 0; width: 100%;" title="YouTube video player"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;And best of all? It's fully &lt;a href="https://github.com/android/ai-samples/tree/main/jetpacker" target="_blank"&gt;open source&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Today we are publishing a series of&lt;b&gt; technical blog posts&lt;/b&gt; diving deep into each of these features. We’ll provide detailed implementation steps, code snippets, and architectural insights to help you build your own intelligent Android applications.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html"&gt;On-device intelligence&lt;/a&gt;&lt;/h2&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7d4EqOTEFypjsqmFoZ8h-zPw3QqQkNY1F_vdbJ98vv1QJCqIE8P-reC0fttcMfNk05g3kGSLhGXVaeiOQDqARK6ptNhFe43miZgTNSmdF7V5hh6u4PhjQleWXmxDqkAf5YKPPyBU14V9z_wFfkiwVDCHN0rkLDtbZCGnb6Jq8d7Iu3YRVgDd9fcMeTiA/s1848/on-device-features.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1256" data-original-width="1848" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7d4EqOTEFypjsqmFoZ8h-zPw3QqQkNY1F_vdbJ98vv1QJCqIE8P-reC0fttcMfNk05g3kGSLhGXVaeiOQDqARK6ptNhFe43miZgTNSmdF7V5hh6u4PhjQleWXmxDqkAf5YKPPyBU14V9z_wFfkiwVDCHN0rkLDtbZCGnb6Jq8d7Iu3YRVgDd9fcMeTiA/s1600/on-device-features.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;On-device features in Jetpacker: Summarizing trip itineraries, managing expenses, and voice notes&lt;/i&gt;&lt;/div&gt;&lt;p&gt;Using an on-device model comes with &lt;b&gt;no additional cloud inference&lt;/b&gt; costs, means you don't have to worry about &lt;b&gt;internet connectivity&lt;/b&gt;, and lets users be confident that private information will be &lt;b&gt;processed locally&lt;/b&gt;, on the device, without any of their data being sent to the cloud.&lt;/p&gt;

&lt;p&gt;In Jetpacker, we chose on-device inference for three of our features:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The &lt;b&gt;trip overview&lt;/b&gt; feature transforms a messy, multi-day itinerary into a concise, actionable summary. It leverages Gemini Nano through the &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android"&gt;ML Kit GenAI APIs&lt;/a&gt; to process data locally on the device. We consider this a nice-to-have feature where we don't want to incur extra cloud costs, making on-device inference the right choice.&lt;/li&gt;
  &lt;li&gt;The &lt;b&gt;expense tracker&lt;/b&gt; automatically extracts structured data from receipt images to help users track their travel spending. It uses the &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/get-started#provide-multimodal"&gt;multimodal capabilities&lt;/a&gt; of Gemini Nano 4 through the ML Kit GenAI APIs. We choose an on-device solution so that any privacy-sensitive information on the receipt images never leaves the user's device.&lt;/li&gt;
  &lt;li&gt;The &lt;b&gt;audio diary &lt;/b&gt;records, transcribes, and categorizes voice notes into relevant trip activities. It is powered by the &lt;a href="https://developers.google.com/ml-kit/genai/speech-recognition/android"&gt;ML Kit Speech Recognition&lt;/a&gt; and &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/get-started"&gt;GenAI Prompt APIs&lt;/a&gt;. We chose an on-device solution for privacy and connectivity reasons.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html" target="_blank"&gt;Cloud &amp;amp; hybrid inference&lt;/a&gt;&lt;/h2&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFPZiA1Obbj1gQKJ6S-U4UCR-jiUjasFY3jGQPeBRS27JJD5DzDIpGseazaNR3qcXR6xtYck8RYqKd0jgHGXVnfqQiPkW7jWVgTB_Hkds5EZcQDjosBZc7Ma9A-JaRaLeVxzEpTXYwSkalIyOIt-WQ_kqdlAvpDH1nB0Ajv7FdFJJ50aBOhP7a0p_RvN4/s2722/cloud-hybrid-features.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1632" data-original-width="2722" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFPZiA1Obbj1gQKJ6S-U4UCR-jiUjasFY3jGQPeBRS27JJD5DzDIpGseazaNR3qcXR6xtYck8RYqKd0jgHGXVnfqQiPkW7jWVgTB_Hkds5EZcQDjosBZc7Ma9A-JaRaLeVxzEpTXYwSkalIyOIt-WQ_kqdlAvpDH1nB0Ajv7FdFJJ50aBOhP7a0p_RvN4/s1600/cloud-hybrid-features.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;i&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;Cloud and hybrid features in Jetpacker: Museum assistant with web grounding, hybrid restaurant review drafting, and hotel support chat featuring custom-routed live translation.&lt;/i&gt;&lt;/div&gt;&lt;/i&gt;&lt;p&gt;Sometimes your use-case requires AI models with &lt;b&gt;greater world knowledge&lt;/b&gt; or a much &lt;b&gt;larger context window&lt;/b&gt; and with greater ability in &lt;b&gt;handling complex tasks&lt;/b&gt;. In that case, we can switch from running an on-device model to using a cloud model instead.&lt;/p&gt;

&lt;p&gt;Or, if you want to get the best of both worlds, you can use hybrid inference to &lt;b&gt;dynamically choose&lt;/b&gt; either a cloud or on-device model at runtime. This allows us to &lt;b&gt;lower costs&lt;/b&gt; by moving inference to the device when it is available, but at the same time &lt;b&gt;support all Android devices&lt;/b&gt; running the app.&lt;/p&gt;

&lt;p&gt;In Jetpacker, we implemented several features using cloud or hybrid inference:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The &lt;b&gt;place Q&amp;amp;A&lt;/b&gt; feature answers user questions about specific locations by grounding responses in real-world data. It uses &lt;a href="https://firebase.google.com/docs/ai-logic"&gt;Firebase AI Logic&lt;/a&gt; integrated with &lt;a href="https://firebase.google.com/docs/ai-logic/grounding-google-maps"&gt;Google Maps&lt;/a&gt; and &lt;a href="https://firebase.google.com/docs/ai-logic/grounding-google-search"&gt;web context&lt;/a&gt;. Using a cloud model is necessary here for its greater world knowledge.&lt;/li&gt;
  &lt;li&gt;The &lt;b&gt;review drafting&lt;/b&gt; feature helps users compose detailed reviews for the places they have visited. It leverages both on-device and cloud models through Firebase AI Logic's new &lt;a href="https://firebase.google.com/docs/ai-logic/hybrid/android/get-started"&gt;Hybrid inference API&lt;/a&gt;. This is a feature we wanted to make available to all app users, so we're using a cloud model as a fallback when an on-device model is unavailable.&lt;/li&gt;
  &lt;li&gt;The &lt;b&gt;automatic chat translation&lt;/b&gt; dynamically translates chat messages in real time to facilitate seamless communication, demonstrating custom hybrid inference logic. Again, we want this feature to be available to all app users, but at the same time have some specific considerations on when to choose on-device versus cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html"&gt;System integration&lt;/a&gt;&lt;/h2&gt;&lt;div style="height: 0px; max-width: 100%; overflow: hidden; padding-bottom: 56.25%; position: relative;"&gt;
  &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" src="https://www.youtube-nocookie.com/embed/qtQMH8RBYIo" style="height: 100%; left: 0; position: absolute; top: 0; width: 100%;" title="YouTube video player"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;While not a feature you see in the app itself, the Android system integration opens up the app's core capabilities directly to the Android operating system. It uses the &lt;a href="https://developer.android.com/ai/appfunctions"&gt;AppFunctions API&lt;/a&gt; to integrate with system-level intelligence.&lt;/p&gt;

&lt;h2&gt;In-app agentic workflows (coming soon!)&lt;/h2&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3YAW_TWepCinuAvHQ7i9JKfhWtf-GSggI6CtD0Qp7-nfPA7UTmmYHTAtsEybWlmiPgxZqo_fUlqc44dmF_5WWH4tlTRze8qdsm9Jc5ARwL5k_PJjU1VTcAHRE3EdxL4JHSnsCt4VCzwPaR41LM34048icLNZLE1kUhpLTeiGpDH87Bh7utPJmXS4kn_8/s1618/agentic-feature-booking-assistant%20(1).png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1618" data-original-width="844" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3YAW_TWepCinuAvHQ7i9JKfhWtf-GSggI6CtD0Qp7-nfPA7UTmmYHTAtsEybWlmiPgxZqo_fUlqc44dmF_5WWH4tlTRze8qdsm9Jc5ARwL5k_PJjU1VTcAHRE3EdxL4JHSnsCt4VCzwPaR41LM34048icLNZLE1kUhpLTeiGpDH87Bh7utPJmXS4kn_8/w209-h400/agentic-feature-booking-assistant%20(1).png" width="209" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;i&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;The booking assistant shows several in-progress flight bookings, asking the user for input before making a final booking.&lt;/i&gt;&lt;/div&gt;&lt;/i&gt;&lt;p&gt;Agenticness introduces a higher level of&lt;b&gt; autonomy&lt;/b&gt;, enabling models to act as agents. Instead of a single inference call, an agent works towards a specific goal via an orchestration loop that allows it to &lt;b&gt;reason&lt;/b&gt;, use &lt;b&gt;tools&lt;/b&gt;, and &lt;b&gt;adapt &lt;/b&gt;its path. Depending on your requirements, these intelligent agents can run either in the cloud, directly on-device, or in a hybrid setup.&lt;/p&gt;

&lt;p&gt;For Jetpacker we added a &lt;b&gt;booking assistant&lt;/b&gt; that automates end-to-end booking workflows directly within the application to streamline reservations. It is built using &lt;a href="https://a2ui.org/"&gt;A2UI&lt;/a&gt; and &lt;a href="https://adk.dev/"&gt;ADK&lt;/a&gt; running in the cloud. The Android app functions as a front-end to the multi-agentic system running in the cloud.&lt;/p&gt;

&lt;h2&gt;Learn more&lt;/h2&gt;
&lt;p&gt;Check out the other parts of this blog post series:&lt;/p&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html"&gt;&lt;b&gt;Part 1 (this post!):&lt;/b&gt;&lt;/a&gt; Introduction of the app and a high-level overview.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html"&gt;&lt;b&gt;Part 2:&lt;/b&gt;&lt;/a&gt; On-device intelligence. Deep-dive into ML Kit’s GenAI APIs and Gemini Nano to build privacy-first features like itinerary summarization, receipt parsing, and local audio processing.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html"&gt;&lt;b&gt;Part 3:&lt;/b&gt;&lt;/a&gt; Hybrid and cloud reasoning. Explore how to use Firebase AI Logic to ground LLM answers in real-world data like Google Maps and web context.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html"&gt;&lt;b&gt;Part 4:&lt;/b&gt;&lt;/a&gt; System integration. Integrating with the Android intelligence system using AppFunctions.&lt;br /&gt;Part 5 (coming soon): In-app agentic workflows. Extend the app with an end-to-end booking assistant powered by A2UI and ADK.&lt;p&gt;Interested in more on Android Development? Follow Android Developers on &lt;a href="https://www.youtube.com/@AndroidDevelopers"&gt;YouTube&lt;/a&gt; or &lt;a href="https://www.linkedin.com/showcase/androiddev/"&gt;LinkedIn&lt;/a&gt;!&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/6562467341747115358/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6562467341747115358" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6562467341747115358" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html" rel="alternate" title="Build intelligent Android apps: Introduction to Jetpacker" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigBFwd7rJO49I_puODKBWFqPbpHaGyL3CTFuZBbr0HTQConFnc3JP0dL9Rr_i6wmyW0o4Ku2bvv3SEacwpC3Vc6b7cYy0aRbZKdUDudFcraYO8zcBVkrMfbrfMP9How0J1xSi91xLnR4s5Z3s-Lp6RF2SA0gU56B9nXD0NkD_CU8MT6wbgBw1tRaMWcMo/s72-c/0713%20Jetpacker%20Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-6917221086083477701</id><published>2026-07-21T06:00:00.000-07:00</published><updated>2026-07-21T09:57:46.319-07:00</updated><title type="text">Build intelligent Android apps: On-device inference</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd7g4aJ0ZhzVcuPr3SzBJIVQ_MZT3hIXb1Ff8SVjjrvRjYzZwhgoE7IbHryS6Ds7u7if1_tmVmMdkFNAtPADXoeuRQ_64Pxfnp3oq2aHR8hbS3fDExGxE0nSiOvXPw7SonhNdjFNI2eDJfasEEMs0xjh2gZlyPq6ToimvFlaMv2-nVDz_XLnSXK1iCn4U/s2469/0625%20Building%20JetPacker%20with%20Intelligent%20On-Device%20features_Meta%20v02.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd7g4aJ0ZhzVcuPr3SzBJIVQ_MZT3hIXb1Ff8SVjjrvRjYzZwhgoE7IbHryS6Ds7u7if1_tmVmMdkFNAtPADXoeuRQ_64Pxfnp3oq2aHR8hbS3fDExGxE0nSiOvXPw7SonhNdjFNI2eDJfasEEMs0xjh2gZlyPq6ToimvFlaMv2-nVDz_XLnSXK1iCn4U/s2469/0625%20Building%20JetPacker%20with%20Intelligent%20On-Device%20features_Meta%20v02.png" style="display: none;" /&gt;&lt;div&gt;&lt;i&gt;Posted by Caren Chang, Developer Relations Engineer, Android Developer Relations&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIU-6haqWEXnugbhG5is8t1TU0tN3EkfSc7GwvHMRsMSU14k-P7q4il_nJlGk-qNP_PG3aKs1LDWNgWKqhFsG6Q16v2zeoHMvqY_PesC5ddxHRjTGgtiQ33uvOrUIPkSdUgFfBIYSkqBhcuZJTY8jbW0mOjKs8XF8DLxfyD7CjJ1Sd4FM7AUrufTnSEVw/s8582/0625%20Building%20JetPacker%20with%20Intelligent%20On-Device%20features_Blog%20v02.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8582" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIU-6haqWEXnugbhG5is8t1TU0tN3EkfSc7GwvHMRsMSU14k-P7q4il_nJlGk-qNP_PG3aKs1LDWNgWKqhFsG6Q16v2zeoHMvqY_PesC5ddxHRjTGgtiQ33uvOrUIPkSdUgFfBIYSkqBhcuZJTY8jbW0mOjKs8XF8DLxfyD7CjJ1Sd4FM7AUrufTnSEVw/s1600/0625%20Building%20JetPacker%20with%20Intelligent%20On-Device%20features_Blog%20v02.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Welcome back to the blog post series "&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html" target="_blank"&gt;Build intelligent Android apps&lt;/a&gt;" where we take a basic Android app and transform it into a &lt;b&gt;personalized, intelligent, &lt;/b&gt;and &lt;b&gt;agentic &lt;/b&gt;experience. In our &lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html" target="_blank"&gt;previous post we introduced Jetpacker&lt;/a&gt;, the demo app we'll use throughout this series.&lt;/p&gt;

&lt;p&gt;In this blog post, we will share how you can use Gemini Nano through &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android"&gt;ML Kit’s Prompt API&lt;/a&gt; to build intelligent on-device features.&lt;/p&gt;
&lt;div style="height: 0px; margin: 0px auto; max-width: 853px; overflow: hidden; padding-bottom: 56.25%; position: relative;"&gt;
  &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" src="https://www.youtube-nocookie.com/embed/_iuXykdlTkk" style="height: 100%; left: 0; position: absolute; top: 0; width: 100%;" title="YouTube video player"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Building intelligent on-device features refers to the ability to process prompts and data directly on a device without sending data to a server. This offers a few advantages:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;User data can be processed &lt;b&gt;locally&lt;/b&gt; on the device, preserving user privacy&lt;/li&gt;
  &lt;li&gt;Functionality of the model is &lt;b&gt;reliable&lt;/b&gt; even with spotty or no internet connection&lt;/li&gt;
  &lt;li&gt;No additional cloud inference &lt;b&gt;cost&lt;/b&gt;, since everything runs on the user’s hardware&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the benefits of on-device in mind, we identified three features to add in Jetpacker that can improve the user experience: summarizing trip itineraries, managing expenses, and capturing voice notes.&lt;/p&gt;

&lt;h2&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3FDrGSpGJqSapXXQ7052s1NR8rzvmmW-xbyOaAcg8bdTA6ZH7p6ZWE664FjlaoDLfREd-RlQil7gV-VjnCoq76o06haLoSxBzlIDAvM-dKvm_TCgPvqHU3ZlzBTXZ9XtAyMk26QWB8PvU5aUmzO0RBuMxqxJdC1wk7xl_1PXd1KHvuMCeHeAP9zhgSjg/s1848/Screenshot%202026-07-02%20at%2012.57.08%E2%80%AFPM.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1256" data-original-width="1848" height="434" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3FDrGSpGJqSapXXQ7052s1NR8rzvmmW-xbyOaAcg8bdTA6ZH7p6ZWE664FjlaoDLfREd-RlQil7gV-VjnCoq76o06haLoSxBzlIDAvM-dKvm_TCgPvqHU3ZlzBTXZ9XtAyMk26QWB8PvU5aUmzO0RBuMxqxJdC1wk7xl_1PXd1KHvuMCeHeAP9zhgSjg/w640-h434/Screenshot%202026-07-02%20at%2012.57.08%E2%80%AFPM.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;On-device features in Jetpacker: Summarizing trip itineraries, managing expenses, and voice notes&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;High quality tailored summarization of short texts&lt;/h2&gt;

&lt;p&gt;The itinerary screen gives users a quick overview of all activities for a given trip. Since this screen contains a lot of information, it can quickly become overwhelming. To help users prepare without feeling overwhelmed, we can add a ‘&lt;b&gt;Get ready for your trip&lt;/b&gt;’ section at the top.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtWrJplvxl7ymB4kMN_Tg4tYYkL7G1Ory0hSptzqsbw_xCu4I9l_4SQPQ9CUXs_Jc7qtT1KcpltBds0aYgIvXiK_-qp6fnoX3QmYnGyqGgr2d5f2uzQkyMK-_Iebwp9Ap0aJA4c8Pz4Zy01O5AM6kk_qZ4Blx_bY-_2xIxSA8DMva2LWBbCN_Hb_c37KE/s2499/Screenshot_20260702_111934.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2499" data-original-width="1183" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtWrJplvxl7ymB4kMN_Tg4tYYkL7G1Ory0hSptzqsbw_xCu4I9l_4SQPQ9CUXs_Jc7qtT1KcpltBds0aYgIvXiK_-qp6fnoX3QmYnGyqGgr2d5f2uzQkyMK-_Iebwp9Ap0aJA4c8Pz4Zy01O5AM6kk_qZ4Blx_bY-_2xIxSA8DMva2LWBbCN_Hb_c37KE/w189-h400/Screenshot_20260702_111934.png" width="189" /&gt;&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;The romantic Paris trip is summarized as a classic Parisian adventure blending art, sights, and delicious food. A tip and some useful phrases are also added.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;

&lt;p&gt;By inputting a trip itinerary and asking an LLM to summarize it, we can generate a quick summary of the trip along with packing tips and useful local phrases. This is a great use case for an on-device model for several reasons:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Performance and quality&lt;/b&gt;: Both the input and output text are relatively short. With that, we can expect the performance and quality of an on-device solution to be on par with more powerful cloud models.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Scalability&lt;/b&gt;: Shifting inference on-device allows us to scale this feature from a few users to millions without worrying about managing increasing cloud inference costs.&lt;/li&gt;
  &lt;li&gt;&lt;b&gt;Low latency and reliability&lt;/b&gt;: On-device inference guarantees low latency, providing a reliable experience even when users are offline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build with on-device, we use &lt;b&gt;Gemini Nano&lt;/b&gt;, Google’s most efficient model optimized for mobile devices. Gemini Nano was first introduced a few years ago, and is now running on over 140 million devices. The latest version of the model, &lt;a href="https://android-developers.googleblog.com/2026/04/AI-Core-Developer-Preview.html"&gt;Gemini Nano 4, is built on the architecture foundation of the recently released Gemma 4 model&lt;/a&gt;, and is further optimized for maximum battery and performance efficiency.&lt;/p&gt;

&lt;p&gt;Using ML Kit’s &lt;b&gt;Prompt API&lt;/b&gt;, we can take advantage of Gemini Nano 4’s new model capabilities to prototype our on-device features. We’ll create a prompt that includes the itinerary of a trip and ask the model to generate a summary along with any preparation tips.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// implementation("com.google.mlkit:genai-prompt:1.0.0-beta3") 

// Define the configuration for Gemini Nano 4 E2B preview model
val previewFastConfig = generationConfig {
    modelConfig = modelConfig {
        releaseStage = ModelReleaseStage.PREVIEW
        preference = ModelPreference.FAST
    }
}

val geminiNano2BPreviewModel = Generation.getClient(previewFastConfig)

val tripItinerary = ...

val getReadyForYourTripSummary = geminiNano2BPreviewModel
 .generateContent("Given this trip itinerary: $tripItinerary, 
     generate the following: overall vibe, tips on how to prepare for this
     trip, and common short phrases to learn for the trip.")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finding the optimal prompt usually requires some iteration, and the AICore app is perfect for this step in the process. After opting into the &lt;a href="https://developers.google.com/ml-kit/genai/aicore-dev-preview"&gt;developer preview option for AICore&lt;/a&gt;, we can download preview models such as Gemini Nano 4 to test prompts and see the model’s expected outputs. With a few iterations on the prompt, we were able to improve the speed of the response from 13 seconds to under 2 seconds! Check out the final code implementation and prompt &lt;a href="https://github.com/android/ai-samples/blob/40b999ef0e85693eac4de06e58335f0f5f125fa6/jetpacker/android/feature/trip/itinerary/enrichment/src/main/kotlin/com/example/jetpacker/feature/itinerary_enrichment/TripSummaryAndTipsProviderImpl.kt#L100" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaY2Q7rzlrAj2i410lc3qqtKwI3m6ufAi27R5S94LVFJKEJPnxmvShIcAWdD_Cx9lhTz9tmKW_DVcmNg0rZFBKpqYj0M9niFJwa-AurlyV2SHuErI7Z9H59Q9S936I4ErUQ_NFRNSJpUBXwDVmw6vKNVpIkBrYPJNUpCIyNXl5Z17x7jEl5Kn9BGgFuLg/s553/Screen%20Recording%202026-07-02%20at%2012.28.51%E2%80%AFPM.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="553" data-original-width="496" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaY2Q7rzlrAj2i410lc3qqtKwI3m6ufAi27R5S94LVFJKEJPnxmvShIcAWdD_Cx9lhTz9tmKW_DVcmNg0rZFBKpqYj0M9niFJwa-AurlyV2SHuErI7Z9H59Q9S936I4ErUQ_NFRNSJpUBXwDVmw6vKNVpIkBrYPJNUpCIyNXl5Z17x7jEl5Kn9BGgFuLg/w359-h400/Screen%20Recording%202026-07-02%20at%2012.28.51%E2%80%AFPM.gif" width="359" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;The first iteration of our prompt generated way too many tokens, and optimizing it helped keep responses quick and to the point.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;

&lt;h2&gt;Local processing for sensitive user input&lt;/h2&gt;

&lt;p&gt;Next, to help users enjoy their trip even more, we’ll build a simple expense manager that takes the manual work out of sorting through receipts and calculating budgets.&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsHCjYJhDefKk1_FHnyB8mXO6XGrVWPrWkkxUikHNrWly2YqLjD8GyN-qGXOBlZCJPug-VbVgBr8awg8I-TEl6d9udKhq_zKem9Xcdb7FzFlA4B77Iko2Rbf8R0XIPB30owcMoh-7KJ1paQnzDrNHSdvwYotNxt166QqJdNAf1d8wEwIFkL9qIEYUKmoQ/s1282/7.13_BlogGif_Transparent.gif" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1282" data-original-width="613" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsHCjYJhDefKk1_FHnyB8mXO6XGrVWPrWkkxUikHNrWly2YqLjD8GyN-qGXOBlZCJPug-VbVgBr8awg8I-TEl6d9udKhq_zKem9Xcdb7FzFlA4B77Iko2Rbf8R0XIPB30owcMoh-7KJ1paQnzDrNHSdvwYotNxt166QqJdNAf1d8wEwIFkL9qIEYUKmoQ/w191-h400/7.13_BlogGif_Transparent.gif" width="191" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
  
&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;Taking a photo of a restaurant bill, data is parsed and shown in the expense overview screen of the app.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;

&lt;p&gt;Since receipts might contain sensitive information like credit card number and addresses, this is another great use case for an on-device solution. With on-device, users can be confident that private information will be processed locally on the device without any of their data being sent to the cloud.&lt;/p&gt;

&lt;p&gt;In addition, Gemini Nano 4 has improved model capabilities for multimodality, especially for image understanding tasks like OCR and visual data extraction, making it a great solution for tasks like extracting information from receipts.&lt;/p&gt;

&lt;p&gt;For this use case, the prompt will analyze an image of the receipt, and output information such as: a generated title, amount spent and category of the expense. To ensure the model outputs the information in the preferred format, we can use &lt;a href="https://developers.google.com/ml-kit/genai/prompt/android/structured-output"&gt;ML Kit’s Structured Output API&lt;/a&gt; to seamlessly output a Kotlin data object that we define.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// implementation("com.google.mlkit:genai-prompt:1.0.0-beta3")
// ksp("com.google.mlkit:genai-schema-compiler:1.0.0-alpha1")

@Generable("Information extracted from an expense receipt")
data class ParsedReceipt(
  @Guide("Generated title for the expense less than 6 words. Based on restaurant or activity name.")
  val title: String,
  @Guide("Total amount of the expense. Look for values at the bottom and words like total or balance due.")
  val amount: Double,
  @Guide("Type of expense", enumValues = ["travel", "food", "shopping", "entertainment", "other"])
  val category: String,
)

val prompt = "Determine if the image is a receipt or expense. 
    If it is NOT a receipt or expense, output the text 'NOT_A_RECEIPT'.
    Otherwise, parse the receipt information."

val request = generateContentRequest(ImagePart(bitmap), TextPart(prompt)) {}
val requestWithStructuredOutput = generateTypedContentRequest(request, ParsedReceipt::class)

// Define the configuration for Gemini Nano 4 E4B preview model  
// When selecting models, you can specify which performance charactertists are most important
//  for your use case. Use ModelPreference.FULL when you want to prioritize reasoning power over speed. 
//  Use ModelPreference.FAST when complex logic is not required and latency is a priority.
val previewFullConfig = generationConfig {
    modelConfig = modelConfig {
        releaseStage = ModelReleaseStage.PREVIEW
        preference = ModelPreference.FULL
    }
}

val geminiNano4BPreviewModel = Generation.getClient(previewFullConfig)
val response = geminiNano4BPreviewModel.generateContent(requestWithStructuredOutput)
val parsedReceipt: ParsedReceipt? = response.candidates.firstOrNull()?.response&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Multimodal input&lt;/h2&gt;

&lt;p&gt;Lastly, to help users record audio memos during the trip, let’s build a fully on-device voice notes feature. Using &lt;a href="https://developers.google.com/ml-kit/genai/speech-recognition/android"&gt;ML Kit’s Speech Recognition API&lt;/a&gt;, we’ll enable users to record short voice notes that are automatically transcribed to text. With the transcribed text, we’ll use ML Kit’s Prompt API to identify which trip activity is associated with the recorded voice note, letting users easily recap their trip as they scroll through the trip’s itinerary.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnAm4XPVEJkfPmRFKJWh2sS-4rVz_eFollYxU5DWb7kAkSQdP4xhAEosziS_vpxv6yoAkvHiSp6SGYOp2_qp_cJWgfbJGnDOadaMP6Bc30a6rYnSP34sEubNAWXqsmd3cpYOoL8rCUhQn0_4GT3165aSFinlnHZjVnXYNYBAw8AdVtJpuRG2gDbi-uRII/s2499/Screenshot_20260702_115529.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2499" data-original-width="1183" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnAm4XPVEJkfPmRFKJWh2sS-4rVz_eFollYxU5DWb7kAkSQdP4xhAEosziS_vpxv6yoAkvHiSp6SGYOp2_qp_cJWgfbJGnDOadaMP6Bc30a6rYnSP34sEubNAWXqsmd3cpYOoL8rCUhQn0_4GT3165aSFinlnHZjVnXYNYBAw8AdVtJpuRG2gDbi-uRII/w189-h400/Screenshot_20260702_115529.png" width="189" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p style="text-align: center;"&gt;&lt;em&gt;The Roman holiday itinerary shows voice note extracts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://developers.google.com/ml-kit/genai/speech-recognition/android"&gt;ML Kit GenAI Speech Recognition API &lt;/a&gt;allows you to transcribe audio content to text fully on-device using two distinct modes. &lt;b&gt;Basic mode&lt;/b&gt; uses a traditional on-device speech recognition model and is available on most Android devices with API level 31 and higher. &lt;b&gt;Advanced mode&lt;/b&gt; uses Gemini Nano to offer broader language coverage and better quality, and is currently supported on Pixel 10 devices.&lt;/p&gt;

&lt;p&gt;For our feature we combine the Speech Recognition API with the ML Kit GenAI Prompt API:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// implementation("com.google.mlkit:genai-prompt:1.0.0-beta3")
// implementation("com.google.mlkit:genai-speech-recognition:1.0.0-alpha1")

val tripEvents = ... 

// Set up speech recognition
val speechRecognizerOptions =
    speechRecognizerOptions {
        locale = Locale.US
        preferredMode = SpeechRecognizerOptions.Mode.MODE_ADVANCED
    }
val speechRecognizer: SpeechRecognizer = SpeechRecognition.getClient(speechRecognizerOptions)

suspend fun transcribeVoiceNote(recognizer: SpeechRecognizer) {
    // Display partial text as the user is recording audio
    var partialTextResponse = ""

    // Display the full text once user is finished recording audio
    var transcription = ""

    val request: SpeechRecognizerRequest
        = speechRecognizerRequest { audioSource = AudioSource.fromMic() }
    recognizer.startRecognition(request).collect { response -&amp;gt;
        when (response) {
            is SpeechRecognizerResponse.PartialTextResponse -&amp;gt; {
                partialTextResponse = response.text
            }
            is SpeechRecognizerResponse.FinalTextResponse -&amp;gt; {
                transcription = response.text
                processAndCategorizeVoiceNote(transcription, tripEvents)
            }
        }
    }
}

fun processAndCategorizeVoiceNote(transcribedVoiceNote: String, events: List&lt;event&gt;) {
    val prompt = "Given the voice note $transcribedVoiceNote
     and the following events for this trip: $events, rewrite this transcription
     to remove filler words. Then, identify which events from the
     list this rewritten transcription matches to."

     // Utilize ML Kit's Prompt API to process voice note and tag it with the relevant trip activities
     Generation.getClient().generateContent(prompt)
}&lt;/event&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Using ML Kit’s GenAI APIs, we were able to take advantage of Gemini Nano to develop fully on-device intelligent features for the JetPacker app, and provide an improved user experience without any additional cloud costs.&lt;/p&gt;

&lt;p&gt;Check out the full source code for &lt;a href="https://github.com/android/ai-samples/tree/main/jetpacker" target="_blank"&gt;Jetpacker on Github&lt;/a&gt;, and watch the video &lt;a href="https://www.youtube.com/watch?v=_iuXykdlTkk"&gt;Build Intelligent Android apps with Google’s AI&lt;/a&gt; to learn more about how to integrate intelligent features directly into your app using on-device models, cloud-powered reasoning, and the latest agentic frameworks.&lt;/p&gt;&lt;h2&gt;Learn more&lt;/h2&gt;

&lt;p&gt;Check out the other parts of this blog post series:&lt;/p&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-introduction-jetpack.html"&gt;&lt;b&gt;Part 1:&lt;/b&gt;&lt;/a&gt; Introduction of the app and a high-level overview.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html"&gt;&lt;b&gt;Part 2 (this post!):&lt;/b&gt;&lt;/a&gt;&amp;nbsp;On-device intelligence. Deep-dive into ML Kit’s GenAI APIs and Gemini Nano to build privacy-first features like itinerary summarization, receipt parsing, and local audio processing.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-cloud-hybrid-inference.html"&gt;&lt;b&gt;Part 3:&lt;/b&gt; &lt;/a&gt;Hybrid and cloud reasoning. Explore how to use Firebase AI Logic to ground LLM answers in real-world data like Google Maps and web context.&lt;br /&gt;&lt;a href="http://android-developers.googleblog.com/2026/07/build-intelligent-android-apps-appfunctions.html"&gt;&lt;b&gt;Part 4:&lt;/b&gt;&lt;/a&gt; System integration. Integrating with the Android intelligence system using AppFunctions.&lt;br /&gt;Part 5 (coming soon): In-app agentic workflows. Extend the app with an end-to-end booking assistant powered by A2UI and ADK.

&lt;p&gt;Interested in more on Android Development? Follow Android Developers on &lt;a href="https://www.youtube.com/@AndroidDevelopers"&gt;YouTube&lt;/a&gt; or &lt;a href="https://www.linkedin.com/showcase/androiddev/"&gt;LinkedIn&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;All code snippets in this blog post follow the following copyright notice:&lt;br /&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/6917221086083477701/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6917221086083477701" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/6917221086083477701" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/android-on-device-inference.html" rel="alternate" title="Build intelligent Android apps: On-device inference" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd7g4aJ0ZhzVcuPr3SzBJIVQ_MZT3hIXb1Ff8SVjjrvRjYzZwhgoE7IbHryS6Ds7u7if1_tmVmMdkFNAtPADXoeuRQ_64Pxfnp3oq2aHR8hbS3fDExGxE0nSiOvXPw7SonhNdjFNI2eDJfasEEMs0xjh2gZlyPq6ToimvFlaMv2-nVDz_XLnSXK1iCn4U/s72-c/0625%20Building%20JetPacker%20with%20Intelligent%20On-Device%20features_Meta%20v02.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-494275494579598458</id><published>2026-07-20T06:00:00.000-07:00</published><updated>2026-07-20T09:00:55.199-07:00</updated><title type="text">Upcoming Changes to the Nearby Connections API</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBTEW5VPkXYGqZfx-TbWnVWxTk9AQIL8sALc8flpOeFh0cKmglsMQvlLpFfLk1Hk5dGxbj96UE_vLtNjxH91AIS583psy8RmP91l0TYuP2hXJPt5c-IZGmmU66d9FNlu9T-s9myFA9_uoQ60n-uy1DK96flaQSUkjh1nN2z3jMKOL4qMPg14XOlpH122Y/s2469/Upcoming%20Changes%20to%20the%20Nearby%20Connections%20API%20_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;&lt;i&gt;Posted by Wei Wang, Engineering Manager, Android BeTo&lt;/i&gt;

&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG84rk4vo20t7pFUGFUp6Cx38qbJTZWW5Q5ztSfPOaV474gZ4mnT7qpnC6o4hKJkwR6CiD4TwPWCS0aU-w0nr70WkKrcpR2yRM5PXnMDa9t3mjgQVahNBzLijD2v23LiDj_NaMWoyVXWTV3cKXHsForureZTA1_Q5M_03ZAve7PybnhpYpGG05IS2uCv0/s8583/Upcoming%20Changes%20to%20the%20Nearby%20Connections%20API%20_Blog.png" style="clear: left; float: left; margin-bottom: 0.3em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2600" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG84rk4vo20t7pFUGFUp6Cx38qbJTZWW5Q5ztSfPOaV474gZ4mnT7qpnC6o4hKJkwR6CiD4TwPWCS0aU-w0nr70WkKrcpR2yRM5PXnMDa9t3mjgQVahNBzLijD2v23LiDj_NaMWoyVXWTV3cKXHsForureZTA1_Q5M_03ZAve7PybnhpYpGG05IS2uCv0/s1600/Upcoming%20Changes%20to%20the%20Nearby%20Connections%20API%20_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p style="margin-bottom: 0.3em; margin-top: 0.3em;"&gt;User privacy and transparency are core to the Android experience. To better align with these principles, we are updating the default behavior of the Nearby Connections API regarding how it interacts with device radios.&lt;/p&gt;

&lt;h2 style="margin-bottom: 0.5em; margin-top: 1.5em;"&gt;What is changing?&lt;/h2&gt;
&lt;p style="margin-bottom: 0.3em; margin-top: 0.1em;"&gt;Previously, the Nearby Connections API could automatically toggle Wi-Fi and Bluetooth radios ON to facilitate connections without explicit user intervention. Moving forward, the API will no longer automatically enable these radios for 1P and 3P applications.&lt;/p&gt;

&lt;h2 style="margin-bottom: 0.5em; margin-top: 1.5em;"&gt;What this means for developers&lt;/h2&gt;
&lt;p style="margin-bottom: 0.3em; margin-top: 0.1em;"&gt;If your app relies on Nearby Connections, you will need to update your implementation to account for these changes:&lt;/p&gt;
&lt;ul style="margin-bottom: 0.3em; margin-top: 0.1em;"&gt;
  &lt;li style="margin-bottom: 0.2em;"&gt;&lt;strong&gt;Manual Radio Management:&lt;/strong&gt; You must ensure that the necessary radios (Wi-Fi or Bluetooth) are enabled before initiating Nearby Connections tasks.&lt;/li&gt;
  &lt;li style="margin-bottom: 0.2em;"&gt;&lt;strong&gt;User Notification:&lt;/strong&gt; If the required radios are disabled, your app must now inform the user and request that they enable them manually. The API will no longer programmatically turn them on for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 style="margin-bottom: 0.5em; margin-top: 1.5em;"&gt;Timing&lt;/h2&gt;
&lt;p style="margin-bottom: 0em; margin-top: 0.1em;"&gt;These changes are scheduled to take effect in late 2026. We recommend reviewing your connection workflows now to ensure a seamless transition for your users.&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/494275494579598458/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/upcoming-changes-nearby-connections-api.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/494275494579598458" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/494275494579598458" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/upcoming-changes-nearby-connections-api.html" rel="alternate" title="Upcoming Changes to the Nearby Connections API" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG84rk4vo20t7pFUGFUp6Cx38qbJTZWW5Q5ztSfPOaV474gZ4mnT7qpnC6o4hKJkwR6CiD4TwPWCS0aU-w0nr70WkKrcpR2yRM5PXnMDa9t3mjgQVahNBzLijD2v23LiDj_NaMWoyVXWTV3cKXHsForureZTA1_Q5M_03ZAve7PybnhpYpGG05IS2uCv0/s72-c/Upcoming%20Changes%20to%20the%20Nearby%20Connections%20API%20_Blog.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-992564715214116931</id><published>2026-07-14T04:00:00.000-07:00</published><updated>2026-07-14T06:44:50.199-07:00</updated><title type="text">Android Studio Quail 2 is Stable: Multi-task with the Android Studio AI agent </title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitwUFdkGaqVNsaJ2iCtprD4WZuFjvI1rR6WX35ewxin0wbtVadUtkRb3qYG-KGEKepmtC4WFv2mSAmUBRmZ-oR5ey_-codg1_MhbagflhqgWk2MdNX6-yL8SaADve6mn3v0aJ_uh-qLizIgdImHaQ_KdJfVYqvCga_v_fyJYPHKDyhuhVklAfo145xays/s2461/QuailBlog_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitwUFdkGaqVNsaJ2iCtprD4WZuFjvI1rR6WX35ewxin0wbtVadUtkRb3qYG-KGEKepmtC4WFv2mSAmUBRmZ-oR5ey_-codg1_MhbagflhqgWk2MdNX6-yL8SaADve6mn3v0aJ_uh-qLizIgdImHaQ_KdJfVYqvCga_v_fyJYPHKDyhuhVklAfo145xays/s2461/QuailBlog_Meta.png" style="display: none;" /&gt;&lt;p&gt;Posted by Amman Asfaw, Product Manager, Android Studio&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-nTZM4cgutSVcLIdjSDqJoeiaES_FELwFC84O01Roy0P81-mAyqz3X2w4pwzAZwdhiMeUuhRSyT4euWZkWtGderw6LRu-fK6k-w8lB-9k7GMXOFBy0IzgtGmUk6QkRriFX24lchlTD0SQhbywxli4p4iZ7JzMAN80YoCdruEeruJ58bwhmuo0cj9Y_yg/s2152/QuailMovement_V1_a.gif" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="608" data-original-width="2152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-nTZM4cgutSVcLIdjSDqJoeiaES_FELwFC84O01Roy0P81-mAyqz3X2w4pwzAZwdhiMeUuhRSyT4euWZkWtGderw6LRu-fK6k-w8lB-9k7GMXOFBy0IzgtGmUk6QkRriFX24lchlTD0SQhbywxli4p4iZ7JzMAN80YoCdruEeruJ58bwhmuo0cj9Y_yg/s1600/QuailMovement_V1_a.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Android Studio Quail 2 is now stable and ready for you to use in production, bringing a shift to your IDE with concurrent agentic workflows, natively integrated memory leak profiling, and context-aware crash remediation. Whether you are performing a sweeping architectural overhaul, tracing a memory leak, or resolving a critical production crash, Android Studio keeps you anchored in your workspace by reducing manual friction.&lt;/p&gt;
&lt;p style="margin-bottom: 12px;"&gt;Here’s a deep dive into what’s new:&lt;/p&gt;
&lt;h2 style="margin-top: 0px;"&gt;Multi-tasking with parallel chats&lt;/h2&gt;

&lt;p&gt;In Android Studio Quail 2, we've been hard at work redesigning Agent Mode from the ground up. This new architecture provides better performance, offers more flexibility for decomposing complex tasks, and improves the suite of internal tools the agent uses to do its work.&lt;/p&gt;In addition to these behind-the-scenes improvements, these changes also allow you to converse across multiple agent chats simultaneously. Waiting for the Android Studio agent to finish a task before you can ask another question or initiate a separate task in Agent Mode is a bottleneck of the past. You can multi-task seamlessly: kick off a UI refactor in one tab, fix a ProGuard rule in a second, and generate documentation in a third.&lt;br /&gt;&lt;br /&gt; You can also change which models the agent uses from chat to chat based on the requests you have. Take a look at &lt;a href="http://d.android.com/bench"&gt;Android Bench&lt;/a&gt; for an analysis of how LLMs perform Android development tasks. 

&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;strong&gt;How to use:&lt;/strong&gt; Click the "+" icon to start a new parallel conversation, and use the &lt;b&gt;History&lt;/b&gt; icon to navigate between active tasks. Alternatively, select File &amp;gt; New &amp;gt; New Agent Tab to open a conversation in a dedicated tab.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt; Worktree support is currently unavailable. Exercise caution when running concurrent chats that modify the same project files, which can potentially lead to editor conflicts.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
  &lt;iframe allowfullscreen="" class="BLOG_video_class" height="450" src="https://www.youtube.com/embed/U6T67Lbar-w" style="border: 0; height: 450px; width: 100%;" width="100%" youtube-src-id="U6T67Lbar-w"&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p style="text-align: center;"&gt;&lt;i&gt;Run multiple agent tasks in parallel with different models of your choice.&lt;/i&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwUDucsd939pAvvfRC8VvmNkDp-1nDBMaP3TGFwdjspFgPz7_CVS-7NVzNhP278oKO3MNJL0RZy3k9aCZgmVtuqsahIZh79bGXhB026yKqPPiMYVMFkkSUgTBSLLajNObkMkke_iF6i_cIMRRQ_5Zl8zLgXWKYItToSiyLaZfok-pd-KVkAkRfup_yCsI/s3456/Screenshot%202026-06-17%20at%2012.56.57%E2%80%AFAM.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2044" data-original-width="3456" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwUDucsd939pAvvfRC8VvmNkDp-1nDBMaP3TGFwdjspFgPz7_CVS-7NVzNhP278oKO3MNJL0RZy3k9aCZgmVtuqsahIZh79bGXhB026yKqPPiMYVMFkkSUgTBSLLajNObkMkke_iF6i_cIMRRQ_5Zl8zLgXWKYItToSiyLaZfok-pd-KVkAkRfup_yCsI/s1600/Screenshot%202026-06-17%20at%2012.56.57%E2%80%AFAM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="text-align: left;"&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;Use the History icon to navigate between active tasks.&lt;/i&gt;&lt;/div&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;

&lt;h2 style="margin-top: 12px;"&gt;Memory leak detection with LeakCanary&lt;/h2&gt;

&lt;p&gt;Memory leaks in Android occur when your code holds onto an object's reference long after its life cycle has ended. This prevents the Garbage Collector from reclaiming that memory, eventually leading to sluggish performance or &lt;code&gt;OutOfMemoryError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hunting down memory leaks can be a tedious, manual task. Starting with Android Studio Quail 2, the popular open-source leak detector &lt;a href="https://square.github.io/leakcanary/"&gt;LeakCanary&lt;/a&gt; is natively integrated directly into the Profiler as a dedicated, first-class task.&lt;/p&gt;

&lt;p&gt;This integration transforms your debugging performance by lifting and shifting the heap analysis off your resource-constrained testing phone, and onto your powerful development computer. By running the analysis on your computer, leak tracing is up to five times faster and jank-free, leaving your test app running smoothly on the device.&lt;/p&gt;

&lt;p&gt;Once a leak is detected during a profiling session:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The Profiler renders an interactive, color-coded leak trace, grouping occurrences and estimating lost memory.&lt;/li&gt;
  &lt;li&gt;You can click &lt;b&gt;Go to declaration&lt;/b&gt; on any leaking object in the trace to instantly jump to that exact line of code in your editor.&lt;/li&gt;
  &lt;li&gt;You can click &lt;b&gt;Fix with Agent&lt;/b&gt; to have the Gemini agent ingest the trace, explain the root cause of the retained reference, and write the exact code change (such as unbinding a listener or clearing a static reference) to plug the leak.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwBONeahZYC_5KBtkgQkc5vTjzmN5D-ypyOOScCRcp6Cy8CZeNHVWeNViBS6D_we7HaRy_AjIg1tptZAVEqNTeQ4IVVjoQp4_XJp45648fhiD0H5qvNmiPphikYGDNbEyus-QTVkSU9imwJm4QN0CKnWFs6JZsVkC21SXl9LXAnSndereOvE6iDWOmsEo/s1250/Leak_Canary_4e3675ccb2_ZXI2sE.webp" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="640" data-original-width="1250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwBONeahZYC_5KBtkgQkc5vTjzmN5D-ypyOOScCRcp6Cy8CZeNHVWeNViBS6D_we7HaRy_AjIg1tptZAVEqNTeQ4IVVjoQp4_XJp45648fhiD0H5qvNmiPphikYGDNbEyus-QTVkSU9imwJm4QN0CKnWFs6JZsVkC21SXl9LXAnSndereOvE6iDWOmsEo/s1600/Leak_Canary_4e3675ccb2_ZXI2sE.webp" /&gt;&lt;/a&gt;&lt;span style="text-align: left;"&gt;&lt;i&gt;Review memory leaks identified via LeakCanary through the Fix with Agent button.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;

&lt;h2 style="margin-top: 12px;"&gt;App Quality Insights agent integration&lt;/h2&gt;

&lt;p&gt;Tracking down the root cause of an app crash can require manually synthesizing stack traces, device data, and source code. However Android Studio’s App Quality Insights (AQI) is now fully integrated with Agent Mode to do the heavy lifting for you.&lt;/p&gt;

&lt;p&gt;When you click on a crash in the AQI panel, you immediately get a concise, high-level summary of the issue. If you need to dig deeper, simply click &lt;b&gt;See more&lt;/b&gt;. This opens a dedicated chat where the agent uses your selected model and pulls in local source code and the full stack trace to deliver a comprehensive explanation of the failure.&lt;/p&gt;

&lt;p&gt;With the new agent integration, you move directly from issue identification to resolution. By clicking &lt;b&gt;Fix with AI&lt;/b&gt;, the agent will analyze the issue, propose a step-by-step fix plan, and—upon your approval—apply the necessary code changes directly to your project and verify the resulting fix&lt;/p&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
  &lt;iframe allowfullscreen="" class="BLOG_video_class" height="450" src="https://www.youtube.com/embed/JjgEePciHHg" style="border: 0; height: 450px; width: 100%;" width="100%" youtube-src-id="JjgEePciHHg"&gt;&lt;/iframe&gt;
&lt;/div&gt;&lt;p style="text-align: center;"&gt;&lt;i&gt;The &lt;b&gt;Fix with AI&lt;/b&gt; button triggering the agent to analyze the issue, then propose the fix&lt;/i&gt;&lt;/p&gt;

&lt;h2 style="margin-top: 12px;"&gt;Quality &amp;amp; stability improvements&lt;/h2&gt;

&lt;p&gt;Beyond new features, we’ve continued our focus on quality by addressing numerous bugs and incorporating the latest stability and performance improvements from the IntelliJ platform, making this a significant enhancement for your daily development.&lt;/p&gt;

&lt;h2 style="margin-top: 12px;"&gt;Get Started&lt;/h2&gt;

&lt;p&gt;Ready to dive in and accelerate your development? &lt;a href="https://developer.android.com/studio"&gt;Download&lt;/a&gt; Android Studio Quail 2 and start exploring these new features today! As always, your feedback is crucial to us. &lt;a href="https://developer.android.com/studio/known-issues"&gt;Check known issues&lt;/a&gt;, &lt;a href="https://developer.android.com/studio/report-bugs"&gt;report bugs&lt;/a&gt;, and be part of our vibrant community on &lt;a href="https://www.linkedin.com/showcase/androiddev/posts/?feedView=all"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/androiddevelopers"&gt;Medium&lt;/a&gt;, &lt;a href="https://www.youtube.com/c/AndroidDevelopers/videos"&gt;YouTube&lt;/a&gt;, or &lt;a href="https://twitter.com/androidstudio"&gt;X&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;</content><link href="http://android-developers.googleblog.com/feeds/992564715214116931/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/06/android-studio-quail-2-stable-features.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/992564715214116931" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/992564715214116931" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/06/android-studio-quail-2-stable-features.html" rel="alternate" title="Android Studio Quail 2 is Stable: Multi-task with the Android Studio AI agent " type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitwUFdkGaqVNsaJ2iCtprD4WZuFjvI1rR6WX35ewxin0wbtVadUtkRb3qYG-KGEKepmtC4WFv2mSAmUBRmZ-oR5ey_-codg1_MhbagflhqgWk2MdNX6-yL8SaADve6mn3v0aJ_uh-qLizIgdImHaQ_KdJfVYqvCga_v_fyJYPHKDyhuhVklAfo145xays/s72-c/QuailBlog_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-8846032960796184778</id><published>2026-07-08T06:00:00.000-07:00</published><updated>2026-08-28T17:14:18.224-07:00</updated><title type="text">Evolving how LLMs are measured for Android: the next era of Android Bench</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCAy4lIbOAOrygTMaHZB8q4NarDrLRsqALfsmer5urQX7G_MaRDTw51uMh77Ks2knIuWM-zaEel63Dk2IlCVGD9IxLFy0B68KxwxsvDZzVDaEWaM4Bg8xJYinunaXS_fonxBw7-R4_qSplI4MJU7RDDaYlbq7nRXZoht5lFZVC7ErLEWHdWA6B2KgJvrk/s2469/Bench%20July%20releas%20V01_Meta.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCAy4lIbOAOrygTMaHZB8q4NarDrLRsqALfsmer5urQX7G_MaRDTw51uMh77Ks2knIuWM-zaEel63Dk2IlCVGD9IxLFy0B68KxwxsvDZzVDaEWaM4Bg8xJYinunaXS_fonxBw7-R4_qSplI4MJU7RDDaYlbq7nRXZoht5lFZVC7ErLEWHdWA6B2KgJvrk/s2469/Bench%20July%20releas%20V01_Meta.png" style="display: none;" /&gt;
&lt;div&gt;&lt;i&gt;Posted by Zoe Lopez-Latorre, Senior Developer Relations Engineer, Android&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi49z_u9zPMjp-zyQ1yIpzLgDumtzUwZoprtIgPXv_kpF05e87KklDEguaKSJVhvV8dZJ7aVr98p-MG3FR4Sk37rcYTS91J3ADUQot-c-xnOuyIZ411VO4Hp43Yp7V_TwF6zO6RmAJpw51ZHPGbHfOwZxWgQ62SQeXblULcSc0RjMcZbLHGUZGgHzU6pEo/s8583/Bench%20July%20releas%20V01_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="2601" data-original-width="8583" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi49z_u9zPMjp-zyQ1yIpzLgDumtzUwZoprtIgPXv_kpF05e87KklDEguaKSJVhvV8dZJ7aVr98p-MG3FR4Sk37rcYTS91J3ADUQot-c-xnOuyIZ411VO4Hp43Yp7V_TwF6zO6RmAJpw51ZHPGbHfOwZxWgQ62SQeXblULcSc0RjMcZbLHGUZGgHzU6pEo/s1600/Bench%20July%20releas%20V01_Blog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;p&gt;Back in March, we introduced &lt;a href="http://d.android.com/bench"&gt;Android Bench&lt;/a&gt;—our LLM leaderboard for real-world Android development tasks. Our goal was to provide transparency around model capabilities in Android development and to encourage model improvements, to give you more helpful AI options for your everyday workflow. Since then, we have enhanced the benchmark based on your feedback, including evaluating &lt;a href="https://x.com/AndroidDev/status/2064482677500080549"&gt;open-weight models&lt;/a&gt; and adding cost and efficiency dimensions to the leaderboard.&lt;/p&gt;

&lt;p&gt;But AI capabilities are ever-evolving, and measurement needs to follow suit. As part of our July release, we have adopted the &lt;a href="https://www.harborframework.com/"&gt;Harbor framework&lt;/a&gt;, which includes an updated version of the benchmarking agent used to evaluate models.&lt;/p&gt;

Along with this change to our evaluation, in this July release we’re adding 8 new models (&lt;b&gt;Claude Fable 5, Claude Sonnet 5, Claude Opus 4.8, GLM 5.2, Kimi K2.7 Code, MiniMax M3, Qwen 3.7 Plus and Qwen 3.7 Max&lt;/b&gt;) to the leaderboard. We’re also sharing opportunities for you, the Android developer community, to contribute to the benchmark. 

&lt;h2 style="margin-top: 10px;"&gt;Upgrading our methodology with the Harbor framework&lt;/h2&gt;

&lt;p&gt;When we designed Android Bench, we anchored our methodology on leading industry standards available at the time. We used mini-swe-agent v1, a general-purpose benchmarking agent, and adapted it to the nuances of Android development to provide a baseline measurement for the capabilities of models for common Android development tasks.&lt;/p&gt;

&lt;p&gt;To continue providing you with state-of-the-art evaluations that accurately measure the latest model capabilities on Android development, we are standardizing our benchmark to the &lt;a href="https://www.harborframework.com/"&gt;Harbor framework&lt;/a&gt;. Harbor defines standards and integrations that make it easy for anyone to run the benchmark, evaluate their preferred set-up, or share results – providing you with additional transparency and visibility.&lt;/p&gt;

&lt;p&gt;This upgrade enables us to more rigorously evaluate models and their capabilities, and we re-ran the benchmark on all models to establish an updated baseline. This means there is a minor shift in scoring, but you will still be able to view historical scores within &lt;a href="http://d.android.com/bench/archive"&gt;the archive&lt;/a&gt; on our website.&lt;/p&gt;

&lt;p&gt;We want to ensure Android Bench is helpful for you, so we will continuously update it as our evaluations and the industry mature.&lt;/p&gt;

&lt;h2 style="margin-top: 10px;"&gt;Expanding the leaderboard with 8 new models&lt;/h2&gt;

&lt;p&gt;As part of our commitment to keeping the leaderboard fresh, we have added Claude Fable 5, Claude Sonnet 5, Claude Opus 4.8, GLM 5.2, Kimi K2.7 Code, MiniMax M3, Qwen 3.7 Plus and Qwen 3.7 Max to the Android Bench leaderboard.&lt;/p&gt;

&lt;p&gt;You will see that &lt;b&gt;Claude Fable 5&lt;/b&gt; is at the top of the leaderboard with a score of 84.5, followed by &lt;b&gt;GPT 5.5&lt;/b&gt; with 80.2, with &lt;b&gt;Claude Sonnet 5&lt;/b&gt; in 3rd with a score of 76.2.&lt;/p&gt;

&lt;p&gt;When just comparing Open-weight models,&lt;b&gt; GLM 5.2&lt;/b&gt; is at the top with 72.2, followed by &lt;b&gt;Kimi K2.7 Code&lt;/b&gt; with a score of 70.4.&lt;/p&gt;

&lt;p&gt;You can check out model performance and efficiency metrics on the updated leaderboard to see how these new and previous models navigate Android-specific challenges like Jetpack Compose migrations, wearable networking, and platform API updates.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQCbY3Td_I5gR8bC4uFSBTe4Sl-XuArNNdFU-27JP6-kwHycXt9AMpWfkLqjUIK37Zw18Tel6a7yOS9x0L_NabxBgYd9KIJKZ6dTLl6VxxJI4M7Zstqj12wvOFtF8LjnYrCIWnhCDdeGsgpQvFpFX8VOoSO0dFJcOW_gRc6eX7mXDq80sOwQAlQWNhlQg/s1999/image1.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="890" data-original-width="1999" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQCbY3Td_I5gR8bC4uFSBTe4Sl-XuArNNdFU-27JP6-kwHycXt9AMpWfkLqjUIK37Zw18Tel6a7yOS9x0L_NabxBgYd9KIJKZ6dTLl6VxxJI4M7Zstqj12wvOFtF8LjnYrCIWnhCDdeGsgpQvFpFX8VOoSO0dFJcOW_gRc6eX7mXDq80sOwQAlQWNhlQg/s1600/image1.png" /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h2 id="community-contributions"&gt;Opening Android Bench to community contributions&lt;/h2&gt;

&lt;p&gt;From the beginning, we’ve valued an open and transparent approach, which is why we made our original methodology and test harness publicly available on GitHub. You’ve asked for a way to provide feedback on our dataset, so now we’re taking collaboration a step further by giving you, the Android developer community, a chance to shape Android Bench.&lt;/p&gt;

&lt;p&gt;Starting today, you can contribute to Android Bench in two ways:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Design and &lt;a href="https://github.com/android-bench/community-dataset"&gt;submit your own Android development tasks&lt;/a&gt; to evaluate how models handle the scenarios that matter to you.&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/android-bench/community-results"&gt;Run and share benchmark evaluations&lt;/a&gt; firsthand, testing your preferred models against our dataset or your own custom tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will be reviewing the submitted tasks and will be assessing if they get added to the benchmark. We hope to build a benchmark that truly reflects the diverse, day-to-day realities of the global Android developer community.&lt;/p&gt;

&lt;h2 style="margin-top: 10px;"&gt;Looking ahead&lt;/h2&gt;

&lt;p&gt;With more and more options for agentic development, maintaining a cutting-edge benchmark ensures that the AI assistance you rely on keeps getting smarter, more helpful, and more effective. Head over to our &lt;a href="https://github.com/android-bench/android-bench"&gt;GitHub repository&lt;/a&gt; to check out the tasks. We invite you to submit a task to our team for review, and you can check out &lt;a href="https://hub.harborframework.com/datasets/android-bench/android-bench/latest"&gt;Harbor Hub&lt;/a&gt; to explore the dataset or submit evaluations.&lt;/p&gt;

&lt;p&gt;As always, you can find the &lt;a href="http://d.android.com/bench"&gt;updated leaderboard&lt;/a&gt;, or read the &lt;a href="http://d.android.com/bench/methodology"&gt;methodology&lt;/a&gt; on our website.&lt;/p&gt;
  &lt;span style="display: none !important; visibility: hidden;"&gt;
    Android Bench, LLM leaderboard, Harbor framework, Android development, Claude Fable 5, GPT 5.5, Claude Sonnet 5, GLM 5.2, Kimi K2.7 Code, MiniMax M3, Qwen 3.7 Plus, Qwen 3.7 Max, AI benchmarking, Jetpack Compose migration, wearable networking, mobile AI agent, Zoe Lopez-Latorre, model evaluation, open-weight models, developer community contributions.
&lt;/span&gt;
  &lt;/div&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/8846032960796184778/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/android-bench-llm-measurement.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8846032960796184778" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8846032960796184778" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/android-bench-llm-measurement.html" rel="alternate" title="Evolving how LLMs are measured for Android: the next era of Android Bench" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCAy4lIbOAOrygTMaHZB8q4NarDrLRsqALfsmer5urQX7G_MaRDTw51uMh77Ks2knIuWM-zaEel63Dk2IlCVGD9IxLFy0B68KxwxsvDZzVDaEWaM4Bg8xJYinunaXS_fonxBw7-R4_qSplI4MJU7RDDaYlbq7nRXZoht5lFZVC7ErLEWHdWA6B2KgJvrk/s72-c/Bench%20July%20releas%20V01_Meta.png" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6755709643044947179.post-8962875207066256340</id><published>2026-07-06T06:00:00.000-07:00</published><updated>2026-07-06T09:05:49.653-07:00</updated><title type="text">Google Play launches the first Indie Games Fund in Africa</title><content type="html">&lt;meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVaj2uWBON3o1zwwUkgNlLg-ZaLaCDp6myrMrmYMlLIl2zA6438CvmUIPQ8We2FfLSrdwTpcKA_JTGs8gnSibQ2k8b8fb6f-h61WRd8v0WLyyrFCV0YqpVix-1HsVj5g2uuofXmDmjqyWh5IzkmcqfqXthM8dGhQhw06U34XRB5xon72Fq0SEndEifDN8/s2048/IGFund26_Metadata%20Card.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;/meta&gt;
&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVaj2uWBON3o1zwwUkgNlLg-ZaLaCDp6myrMrmYMlLIl2zA6438CvmUIPQ8We2FfLSrdwTpcKA_JTGs8gnSibQ2k8b8fb6f-h61WRd8v0WLyyrFCV0YqpVix-1HsVj5g2uuofXmDmjqyWh5IzkmcqfqXthM8dGhQhw06U34XRB5xon72Fq0SEndEifDN8/s2048/IGFund26_Metadata%20Card.png" style="display: none;" /&gt;&lt;div&gt;&lt;name content="IMG" twitter:image=""&gt;&lt;i&gt;Posted by Steph Pio, Strategic Partnerships Manager, Google Play EMEA&lt;/i&gt;&lt;/name&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;name content="IMG" twitter:image=""&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;em&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj86YrBhsnBplvegJfEidJDWTSlkZ8i8WT_TpXfsiaamFA3ILGZKZgz9AkX3-JJTvYTO3qcyJdDnn0GakXbA3GvrKvqucP5n67-XtPAigihdacSOJ1D448iiIyF7gjY68vBmXAAAvtZRISJbhZWhxjx4_mPD92R4KqgEg3xk46WO0qJtm-xQkGMShiHbKs/s4209/IGFund26_Blogger%20Header.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj86YrBhsnBplvegJfEidJDWTSlkZ8i8WT_TpXfsiaamFA3ILGZKZgz9AkX3-JJTvYTO3qcyJdDnn0GakXbA3GvrKvqucP5n67-XtPAigihdacSOJ1D448iiIyF7gjY68vBmXAAAvtZRISJbhZWhxjx4_mPD92R4KqgEg3xk46WO0qJtm-xQkGMShiHbKs/s16000/IGFund26_Blogger%20Header.png" /&gt;&lt;/a&gt;&lt;/em&gt;&lt;/div&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/name&gt;
&lt;p&gt;Sub-Saharan Africa is home to some of the world’s most creative storytelling. To help bring those stories to a global audience, today, we’re proud to announce the debut of Google Play’s Indie Games Fund in Africa.&lt;/p&gt;

&lt;p&gt;The region’s unique creativity has fueled a vibrant game development scene, helping drive what is quickly becoming one of the most exciting, resilient, and fast-growing gaming markets. It’s a space defined by immense talent. However, access to capital is a persistent hurdle, and a significant investment gap often holds back incredibly promising local studios.&lt;/p&gt;

&lt;p&gt;With this inaugural fund, we’re committing $1 million USD to help address that gap. This fund will empower 10 indie game studios across Sub-Saharan Africa to scale their businesses and realize their full potential.&lt;/p&gt;

&lt;h3&gt;Funding and support for selected studios&lt;/h3&gt;

&lt;p&gt;This program is designed to drive long-term growth, where it can make the biggest impact. Selected studios will receive a share of the $1 million fund, with individual investments ranging from $50,000 to $200,000 to help elevate their games. Alongside this financial backing, recipients will benefit from dedicated mentorship and hands-on technical support. Together, these awards are designed to help them scale their businesses and reach a global audience.&lt;/p&gt;

&lt;h3&gt;Who can apply?&lt;/h3&gt;

&lt;p&gt;The program is open to indie game developers based in Sub-Saharan Africa (see the &lt;a href="https://rsvp.withgoogle.com/events/africa-indie-games-fund-2026/terms"&gt;list of eligible countries&lt;/a&gt;) who have launched a game—whether it’s on Google Play, another mobile platform, PC, or console.&lt;/p&gt;

&lt;p&gt;Review the &lt;a href="https://rsvp.withgoogle.com/events/africa-indie-games-fund-2026/terms"&gt;eligibility criteria&lt;/a&gt; and &lt;a href="https://rsvp.withgoogle.com/events/africa-indie-games-fund-2026/home"&gt;apply now&lt;/a&gt;. Applications close at 12 noon UTC on July 31, 2026.&lt;/p&gt;&lt;/div&gt;</content><link href="http://android-developers.googleblog.com/feeds/8962875207066256340/comments/default" rel="replies" title="Post Comments" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/Indie-Games-Fund-Africa.html#comment-form" rel="replies" title="0 Comments" type="text/html"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8962875207066256340" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6755709643044947179/posts/default/8962875207066256340" rel="self" type="application/atom+xml"/><link href="http://android-developers.googleblog.com/2026/07/Indie-Games-Fund-Africa.html" rel="alternate" title="Google Play launches the first Indie Games Fund in Africa" type="text/html"/><author><name>Android Developers</name><uri>http://www.blogger.com/profile/08588467489110681140</uri><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVaj2uWBON3o1zwwUkgNlLg-ZaLaCDp6myrMrmYMlLIl2zA6438CvmUIPQ8We2FfLSrdwTpcKA_JTGs8gnSibQ2k8b8fb6f-h61WRd8v0WLyyrFCV0YqpVix-1HsVj5g2uuofXmDmjqyWh5IzkmcqfqXthM8dGhQhw06U34XRB5xon72Fq0SEndEifDN8/s72-c/IGFund26_Metadata%20Card.png" width="72"/><thr:total>0</thr:total></entry></feed>