### Original NavHost setup Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md Example of a typical NavHost setup using composable and navigation functions before migration. ```kotlin NavHost(navController = navController, startDestination = BaseRouteA){ composable{ val id = entry.toRoute().id ScreenA(title = "Screen has ID: $id") } featureBSection() dialog{ ScreenD() } } ``` -------------------------------- ### Refactored entryProvider setup Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md The refactored setup using entryProvider and updated destination definitions. ```kotlin val entryProvider = entryProvider { entry{ key -> ScreenA(title = "Screen has ID: ${key.id}") } featureBSection() entry(metadata = DialogSceneStrategy.dialog()){ ScreenD() } } ``` -------------------------------- ### Install All Android Skills Source: https://github.com/android/skills/blob/main/README.md Use the Android CLI to install all available Android skills. If no specific agents or projects are defined, skills will be installed in the default location for Gemini and Antigravity. ```bash android skills add --all ``` -------------------------------- ### Setup NavDisplay with ListDetailSceneStrategy Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-listdetail.md Configure the `NavDisplay` in your activity to use the `ListDetailSceneStrategy`. This setup involves remembering the navigation back stack, creating the strategy, and passing it to the `NavDisplay` along with other necessary parameters like the entry provider and shared transition scope. ```kotlin /* * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.nav3recipes.scenes.listdetail import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionLayout import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.ui.Modifier import androidx.navigation3.runtime.NavBackStack import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.ui.NavDisplay import com.example.nav3recipes.ui.setEdgeToEdgeConfig import kotlinx.serialization.Serializable /** * This example shows how to create a list-detail layout using the Scenes API. * * A `ListDetailScene` will render content in two panes if: * * - the window width is over 600dp * - A `Detail` entry is the last item in the back stack * - A `List` entry is in the back stack * * @see `ListDetailScene` */ @Serializable data object ConversationList : NavKey @Serializable data class ConversationDetail( val id: Int, val colorId: Int ) : NavKey @Serializable data object Profile : NavKey class ListDetailActivity : ComponentActivity() { @OptIn(ExperimentalSharedTransitionApi::class) override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { Scaffold { val backStack = rememberNavBackStack(ConversationList) val listDetailStrategy = rememberListDetailSceneStrategy() SharedTransitionLayout { NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, sceneStrategies = listOf(listDetailStrategy), sharedTransitionScope = this, modifier = Modifier.padding(paddingValues), entryProvider = entryProvider { entry( metadata = ListDetailScene.listPane() ) { ConversationListScreen( onConversationClicked = { detailRoute -> ``` -------------------------------- ### Install a Specific Android Skill Source: https://github.com/android/skills/blob/main/README.md Use the Android CLI to install a specific skill into the current project directory. Ensure the skill name and project path are correctly specified. ```bash android skills add --skill=r8-analyzer --project=. ``` -------------------------------- ### Global App Description for Task Management Source: https://github.com/android/skills/blob/main/device-ai/appfunctions/references/kdoc-refinement-optimization.md This example demonstrates how to structure a global app description for server instructions, including operational patterns and constraints. ```text This app provides functions for task management and team collaboration. Operational Patterns: - Always use 'searchUsers' to resolve user handles to internal IDs before calling 'assignTask'. - Prefer 'batchUpdateStatus' when modifying more than 3 tasks simultaneously to reduce latency. Constraints: - Task titles are limited to 100 characters. - Attachment uploads are limited to 5MB. ``` -------------------------------- ### Manage Android SDK Packages Source: https://github.com/android/skills/blob/main/devtools/android-cli/SKILL.md Commands for installing, updating, removing, and listing Android SDK components. ```bash android sdk install platforms/android-30@2 platforms/android-34 ``` ```bash android sdk update [] ``` ```bash android sdk remove ``` ```bash android sdk list --all ``` -------------------------------- ### Box with windowInsetsPadding and imePadding Source: https://github.com/android/skills/blob/main/system/edge-to-edge/SKILL.md This example demonstrates consuming IME insets using `windowInsetsPadding` on the parent Box and `imePadding` on the child Column, ensuring correct padding. ```kotlin // RIGHT Box( // Insets consumed modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing) // or WindowInsets.ime, WindowInsets.safeContent, WindowInsets.safeGestures ) { Column( modifier = Modifier.imePadding() ) { /* Content */ } } ``` -------------------------------- ### Query SKU Details and Start Purchase in Java Source: https://github.com/android/skills/blob/main/play/play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md Retrieves SKU details asynchronously and configures BillingFlowParams using setSkuDetails. ```java private BillingClient mBillingClient; private Map mSkuDetailsMap = new HashMap<>(); private void querySkuDetails() { SkuDetailsParams.Builder skuDetailsParamsBuilder = SkuDetailsParams.newBuilder(); mBillingClient.querySkuDetailsAsync(skuDetailsParamsBuilder.build(), new SkuDetailsResponseListener() { @Override public void onSkuDetailsResponse(int responseCode, List skuDetailsList) { if (responseCode == 0) { for (SkuDetails skuDetails : skuDetailsList) { mSkuDetailsMap.put(skuDetails.getSku(), skuDetails); } } } }); } private void startPurchase(String skuId) { BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setSkuDetails(mSkuDetailsMap.get(skuId)) .build(); } ``` -------------------------------- ### Implement Dynamic Color Theming Source: https://github.com/android/skills/blob/main/wear/wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md Example of using dynamicColorScheme with a fallback for M3 applications. ```kotlin @Composable fun myApp() { val dynamicColorScheme = dynamicColorScheme(LocalContext.current) MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {} } internal val myBrandColors: ColorScheme = ColorScheme( /* Specify colors here */) ``` -------------------------------- ### ListDetailSceneStrategy Setup Source: https://github.com/android/skills/blob/main/jetpack-compose/adaptive/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md Sets up the `ListDetailSceneStrategy` for adaptive layouts. It overrides default horizontal spacing and configures pane roles for list and detail content. ```kotlin package com.example.nav3recipes.material.listdetail /* * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2 import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective import androidx.compose.material3.adaptive.navigation3.ListDetailSceneStrategy import androidx.compose.material3.adaptive.navigation3.rememberListDetailSceneStrategy import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.dropUnlessResumed import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.ui.NavDisplay import com.example.nav3recipes.content.ContentBlue import com.example.nav3recipes.content.ContentGreen import com.example.nav3recipes.content.ContentRed import com.example.nav3recipes.content.ContentYellow import com.example.nav3recipes.ui.setEdgeToEdgeConfig import kotlinx.serialization.Serializable @Serializable private object ConversationList : NavKey @Serializable private data class ConversationDetail(val id: String) : NavKey @Serializable private object Profile : NavKey class MaterialListDetailActivity : ComponentActivity() { @OptIn(ExperimentalMaterial3AdaptiveApi::class) override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { val backStack = rememberNavBackStack(ConversationList) // Override the defaults so that there isn't a horizontal space between the panes. // See b/418201867 val windowAdaptiveInfo = currentWindowAdaptiveInfoV2() val directive = remember(windowAdaptiveInfo) { calculatePaneScaffoldDirective(windowAdaptiveInfo) .copy(horizontalPartitionSpacerSize = 0.dp) } val listDetailStrategy = rememberListDetailSceneStrategy(directive = directive) NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, sceneStrategies = listOf(listDetailStrategy), entryProvider = entryProvider { entry( metadata = ListDetailSceneStrategy.listPane( detailPlaceholder = { ContentYellow("Choose a conversation from the list") } ) ) { ContentRed("Welcome to Nav3") { Button(onClick = dropUnlessResumed { ``` -------------------------------- ### Query SKU Details and Start Purchase in Kotlin Source: https://github.com/android/skills/blob/main/play/play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md Retrieves SKU details asynchronously and configures BillingFlowParams using setSkuDetails. ```kotlin private lateinit var mBillingClient: BillingClient private val mSkuDetailsMap = HashMap() private fun querySkuDetails() { val skuDetailsParamsBuilder = SkuDetailsParams.newBuilder() mBillingClient.querySkuDetailsAsync(skuDetailsParamsBuilder.build() ) { responseCode, skuDetailsList -> if (responseCode == 0) { for (skuDetails in skuDetailsList) { mSkuDetailsMap[skuDetails.sku] = skuDetails } } } } private fun startPurchase(skuId: String) { val billingFlowParams = BillingFlowParams.newBuilder() .setSkuDetails(mSkuDetailsMap[skuId]) .build() } ``` -------------------------------- ### M2.5 Button Implementation Source: https://github.com/android/skills/blob/main/wear/wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md Example of using M2.5 components like Chip and Button before migrating to Material 3. ```kotlin import androidx.wear.compose.material.Chip //M2.5 Buttons Chip(...) CompactChip(...) Button(...) ``` -------------------------------- ### Verification Action Example Source: https://github.com/android/skills/blob/main/devtools/android-cli/references/journeys.md An action that checks for the visibility of a specific UI element on the screen. ```xml Check if "Switch 2" is visible on the screen ``` -------------------------------- ### Initialize NavigationState and Navigator Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md Create instances of NavigationState and Navigator, typically with the same scope as your NavController. Remember to provide your starting route and top-level routes. ```kotlin val navigationState = rememberNavigationState( startRoute = , topLevelRoutes = ) val navigator = remember { Navigator(navigationState) } ``` -------------------------------- ### Retrieve arguments in destination Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/passingarguments.md Retrieve arguments passed to a destination using Safe Args. This Kotlin example shows how to get the 'id' argument in a Fragment. ```kotlin val id = DetailFragmentArgs.fromBundle(arguments).id ``` -------------------------------- ### Get Projected Device ID Source: https://github.com/android/skills/blob/main/xr/display-glasses-with-jetpack-compose-glimmer/references/projectedcontext-source.md Retrieves the device ID of a virtual device whose name starts with a specific prefix. Requires API level 34 (UPSIDE_DOWN_CAKE). ```kotlin @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) private fun getProjectedDeviceId(context: Context) = context .getSystemService(VirtualDeviceManager::class.java) .virtualDevices // TODO: b/424824481 - Replace the name matching with a better method. .find { it.name?.startsWith(PROJECTED_DEVICE_NAME) ?: false } ?.deviceId ``` -------------------------------- ### Run Android Startup Metrics Source: https://github.com/android/skills/blob/main/profilers/perfetto-trace-analysis/SKILL.md Use this command to gather high-level performance metrics related to Android startup. This is a starting point before diving into custom SQL queries. ```bash ./trace_processor --run-metrics android_startup ``` -------------------------------- ### Using the uiAutomator Test Scope Source: https://github.com/android/skills/blob/main/performance/r8-analyzer/references/android/training/testing/other-components/ui-automator.md Access UI Automator APIs within the `uiAutomator { ... }` block for a type-safe testing environment. This example starts an app and clicks an element with specific text. ```kotlin uiAutomator { // All your UI Automator actions go here startApp("com.example.targetapp") onElement { textAsString() == "Hello, World!" }.click() } ``` -------------------------------- ### Define Custom NavType for Complex Types (Kotlin) Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/type-safe-destinations.md Create a custom NavType to handle complex data classes by defining how to get, parse, and put the data into a Bundle. This example uses kotlinx.serialization for encoding and decoding. ```kotlin val SearchFilterType = object : NavType(isNullableAllowed = false) { override fun get(bundle: Bundle, key: String): SearchFilter? = Json.decodeFromString(bundle.getString(key) ?: return null) override fun parseValue(value: String): SearchFilter = Json.decodeFromString(Uri.decode(value)) override fun put(bundle: Bundle, key: String, value: SearchFilter) { bundle.putString(key, Json.encodeToString(value)) } } ``` -------------------------------- ### Create an entryProvider Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md Initialize an entryProvider using the DSL. This should be at the same scope as the NavigationState. ```kotlin val entryProvider = entryProvider { } ``` -------------------------------- ### OpenId4Vp Request Example Source: https://github.com/android/skills/blob/main/identity/verified-email/references/android/identity/digital-credentials/credential-verifier.md An example of an OpenId4Vp request structure conforming to the Verifier API. ```json { "requests": [ { "protocol": "openid4vp-v1-unsigned", "data": { "response_type": "vp_token", "response_mode": "dc_api", "nonce": "OD8eP8BYfr0zyhgq4QCVEGN3m7C1Ht_No9H5fG5KJFk", "dcql_query": { "credentials": [ { "id": "cred1", "format": "mso_mdoc", "meta": { "doctype_value": "org.iso.18013.5.1.mDL" }, "claims": [ { "path": [ "org.iso.18013.5.1", "family_name" ] }, { "path": [ "org.iso.18013.5.1", "given_name" ] }, { "path": [ "org.iso.18013.5.1", "age_over_21" ] } ] } ] } } } ] } ``` -------------------------------- ### Activity Setup for Multiple Back Stacks Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/multiple-backstacks.md Sets up the main activity with a `Scaffold` and `NavigationBar` to manage top-level routes. It uses `rememberNavigationState` and `Navigator` to handle navigation logic and `NavDisplay` to render the content for each route's back stack. ```kotlin class MultipleStacksActivity : ComponentActivity() { @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { val navigationState = rememberNavigationState( startRoute = RouteA, topLevelRoutes = TOP_LEVEL_ROUTES.keys ) val navigator = remember { Navigator(navigationState) } val entryProvider = entryProvider { featureASection(onSubRouteClick = { navigator.navigate(RouteA1) }) featureBSection(onSubRouteClick = { navigator.navigate(RouteB1) }) featureCSection(onSubRouteClick = { navigator.navigate(RouteC1) }) } Scaffold(bottomBar = { NavigationBar { TOP_LEVEL_ROUTES.forEach { (key, value) -> val isSelected = key == navigationState.topLevelRoute NavigationBarItem( selected = isSelected, onClick = { navigator.navigate(key) }, icon = { Icon( imageVector = value.icon, contentDescription = value.description ) }, label = { Text(value.description) } ) } } }) { NavDisplay( entries = navigationState.toDecoratedEntries(entryProvider), onBack = { navigator.goBack() } ) } } } } ``` -------------------------------- ### CreateDeepLinkActivity UI Setup Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-basic.md Sets up the UI for a deeplink sandbox, allowing users to construct and test deeplinks. It manages state for path and query arguments and displays the final constructed URL. ```kotlin class CreateDeepLinkActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { /** * UI for deeplink sandbox */ EntryScreen("Sandbox - Build Your Deeplink") { TextContent("Base url:\n${PATH_BASE}/\n") var showFilterOptions by remember { mutableStateOf(false) } val selectedPath = remember { mutableStateOf(MENU_OPTIONS_PATH[KEY_PATH]?.first()) var showQueryOptions by remember { mutableStateOf(false) } var selectedFilter by remember { mutableStateOf("") } val selectedSearchQuery = remember { mutableStateMapOf() } // manage path options MenuDropDown( menuOptions = MENU_OPTIONS_PATH, ) { _, selection -> selectedPath.value = selection when (selection) { PATH_SEARCH -> { showQueryOptions = true showFilterOptions = false } PATH_INCLUDE -> { showQueryOptions = false showFilterOptions = true } else -> { showQueryOptions = false showFilterOptions = false } } } // manage path filter options, reset state if menu is closed LaunchedEffect(showFilterOptions) { selectedFilter = if (showFilterOptions) { MENU_OPTIONS_FILTER.values.first().first() } else { "" } } if (showFilterOptions) { MenuDropDown( menuOptions = MENU_OPTIONS_FILTER, ) { _, selected -> selectedFilter = selected } } // manage query options, reset state if menu is closed LaunchedEffect(showQueryOptions) { if (showQueryOptions) { val initEntry = MENU_OPTIONS_SEARCH.entries.first() selectedSearchQuery[initEntry.key] = initEntry.value.first() } else { selectedSearchQuery.clear() } } if (showQueryOptions) { MenuTextInput( menuLabels = MENU_LABELS_SEARCH, ) { label, selected -> selectedSearchQuery[label] = selected } MenuDropDown( menuOptions = MENU_OPTIONS_SEARCH, ) { label, selected -> selectedSearchQuery[label] = selected } } // form final deeplink url val arguments = when (selectedPath.value) { PATH_INCLUDE -> "/${selectedFilter}" PATH_SEARCH -> { buildString { selectedSearchQuery.forEach { entry -> if (entry.value.isNotEmpty()) { val prefix = if (isEmpty()) "?" else "&" append("$prefix${entry.key}=${entry.value}") } } } } else -> "" } val finalUrl = "${PATH_BASE}/${selectedPath.value}$arguments" TextContent("Final url:\n$finalUrl") // deeplink to target PaddedButton("Deeplink Away!", onClick = dropUnlessResumed { val intent = Intent( this@CreateDeepLinkActivity, MainActivity::class.java ) ``` -------------------------------- ### Install Android CLI Source: https://github.com/android/skills/blob/main/devtools/android-cli/SKILL.md Commands to install the Android CLI tool based on the operating system architecture. ```bash curl -fsSL https://dl.google.com/android/cli/latest/linux_x86_64/install.sh | bash ``` ```bash curl -fsSL https://dl.google.com/android/cli/latest/darwin_arm64/install.sh | bash ``` ```bash curl -fsSL https://dl.google.com/android/cli/latest/darwin_x86_64/install.sh | bash ``` ```cmd curl -fsSL https://dl.google.com/android/cli/latest/windows_x86_64/install.cmd -o "%TEMP%\i.cmd" && "%TEMP%\i.cmd" ``` -------------------------------- ### Start Focus Animation Source: https://github.com/android/skills/blob/main/xr/display-glasses-with-jetpack-compose-glimmer/references/surface-source.md Initializes and starts the animations for the focused highlight progress and rotation. It snaps to the initial state before animating. ```kotlin _focusedHighlightProgress = _focusedHighlightProgress ?: Animatable(0f) _focusedHighlightRotationProgress = _focusedHighlightRotationProgress ?: Animatable(0f) coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) { _focusedHighlightProgress?.snapTo(0f) _focusedHighlightProgress?.animateTo( targetValue = 1f, animationSpec = FocusedEnterAnimationSpec, ) } coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) { _focusedHighlightRotationProgress?.snapTo(0f) _focusedHighlightRotationProgress?.animateTo( targetValue = 1f, animationSpec = FocusedHighlightRotationAnimationSpec, ) } ``` -------------------------------- ### Initialize AudioRecord with projected device context Source: https://github.com/android/skills/blob/main/xr/display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/access-hardware-projected-context.md Use the AudioRecord.Builder to associate the audio recording session with the projected device context. ```kotlin // Initialize AudioRecord with projected device context val audioRecord = AudioRecord.Builder() .setAudioSource(MediaRecorder.AudioSource.CAMCORDER) .setAudioFormat(audioFormat) .setBufferSizeInBytes(bufferSize) // pass in the projected device context .setContext(projectedDeviceContext) .build() audioRecord.startRecording() ``` -------------------------------- ### Koin Module Setup for Navigation Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-koin.md Define a Koin module to provide navigation-related dependencies, such as the navigator. Ensure this module is included in your Koin setup. ```kotlin val navigationModule = module { single { NavigatorImpl() } // Add other navigation-related dependencies here } ``` -------------------------------- ### Launch Price Change Confirmation Flow in Java Source: https://github.com/android/skills/blob/main/play/play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md Displays a dialog for users to accept new subscription pricing. ```java PriceChangeFlowParams priceChangeFlowParams = PriceChangeFlowParams.newBuilder() .setSkuDetails(skuDetailsOfThePriceChangedSubscription) .build(); billingClient.launchPriceChangeConfirmationFlow(activity, priceChangeFlowParams, new PriceChangeConfirmationListener() { @Override public void onPriceChangeConfirmationResult(int responseCode) { // Handle the result. } }); ``` -------------------------------- ### trace_start Source: https://github.com/android/skills/blob/main/profilers/perfetto-trace-analysis/references/perfetto-stdlib.md Retrieves the start timestamp of the trace. ```APIDOC ## trace_start ### Description Fetch start of the trace. ### Signature trace_start() -> LONG ### Returns - **LONG** - Start of the trace in nanoseconds. ``` -------------------------------- ### Initialize Night Mode Extension Source: https://github.com/android/skills/blob/main/camera/camerax/references/low-light.md Sets up the extension manager and binds a camera with Night mode enabled if supported. ```kotlin // Use ListenableFuture.await() extension function for coroutine support val extensionsManager = ExtensionsManager.getInstanceAsync(context, cameraProvider).await() if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.NIGHT)) { val nightSelector = extensionsManager.getExtensionEnabledCameraSelector( cameraSelector, ExtensionMode.NIGHT ) cameraProvider.bindToLifecycle(lifecycleOwner, nightSelector, imageCapture, preview) } ``` -------------------------------- ### trace_start Source: https://github.com/android/skills/blob/main/profilers/perfetto-sql/references/perfetto-stdlib.md Retrieves the start time of the trace. ```APIDOC ## trace_start ### Description Fetch start of the trace. ### Returns LONG: Start of the trace in nanoseconds. ``` -------------------------------- ### Implement a basic Grid Source: https://github.com/android/skills/blob/main/jetpack-compose/adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/get-started.md Create a 2x3 grid with fixed row and column sizes using the Grid composable. ```kotlin Grid( config = { repeat(2) { column(100.dp) } repeat(3) { row(100.dp) } } ) { Card1(containerColor = PastelRed) Card2(containerColor = PastelGreen) Card3(containerColor = PastelBlue) Card4(containerColor = PastelPink) Card5(containerColor = PastelOrange) Card6(containerColor = PastelYellow) } ``` -------------------------------- ### Define Typography Source: https://github.com/android/skills/blob/main/wear/wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md Example of defining typography in M2.5. ```kotlin import androidx.wear.compose.material.Typography val Typography = Typography( // M2.5 TextStyle parameters ) ``` -------------------------------- ### linux_get_devfreq_counters Source: https://github.com/android/skills/blob/main/profilers/perfetto-sql/references/perfetto-stdlib.md Gets devfreq frequency counter based on device queried. ```APIDOC ## Function: linux_get_devfreq_counters ### Description Gets devfreq frequency counter based on device queried. These counters will only be available if the "devfreq/devfreq_frequency" ftrace event is enabled. ### Arguments | Argument | Type | Description | |---|---|---| | device_name | STRING | Devfreq name to query for. | ### Returns | Column | Type | Description | |---|---|---| | id | INT | Unique identifier for this counter. | | ts | LONG | Starting timestamp of the counter. | | dur | INT | Duration in which counter is constant and frequency doesn't chamge. | | freq | INT | Frequency in kHz of the device that corresponds to the counter. | ``` -------------------------------- ### Constructing Recommendation Reasons Source: https://github.com/android/skills/blob/main/play/engage-sdk-integration/references/android/guide/playcore/engage/tv/recommendations.md Use these builders to provide context for why a specific title is recommended to the user. ```kotlin //Allows us to construct reason: "Because it is top 10 on your Channel" val topOnPartner = RecommendationReasonTopOnPartner .Builder() .setNum(10) //any valid integer value .build() //Allows us to construct reason: "Because it is popular on your Channel" val popularOnPartner = RecommendationReasonPopularOnPartner .Builder() .build() //Allows us to construct reason: "New to your channel, or Just added" val newOnPartner = RecommendationReasonNewOnPartner .Builder() .build() //Allows us to construct reason: "Because you watched Star Wars" val watchedSimilarTitles = RecommendationReasonWatchedSimilarTitles .addSimilarWatchedTitleName("Movie or TV Show Title") .addSimilarWatchedTitleName("Movie or TV Show Title") .Builder() .build() //Allows us to construct reason: "Recommended for you by ChannelName" val recommendedForUser = RecommendationReasonRecommendedForUser .Builder() .build() val watchAgain = RecommendationReasonWatchAgain .Builder() .build() val fromUserWatchList = RecommendationReasonFromUserWatchlist .Builder() .build() val userLikedOnPartner = RecommendationReasonUserLikedOnPartner .Builder() .setTitleName("Movie or TV Show Title") .build() val generic = RecommendationReasonGeneric.Builder().build() ``` -------------------------------- ### Description Setter and Getter Source: https://github.com/android/skills/blob/main/play/engage-sdk-integration/references/common.md Methods to set and get the description of an item. ```APIDOC ## setDescription(String) ### Description Sets the description for the item. This is an optional field. ### Method setter ### Parameters - **description** (String) - Optional - The description to set. ``` ```APIDOC ## getDescription() ### Description Retrieves the current description of the item. ### Method getter ### Returns - **String** - The current description. ``` -------------------------------- ### Basic DSL Navigation with Persistent Back Stack Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/basicdsl.md Sets up a persistent back stack using `rememberNavBackStack` and defines navigation entries with the `entryProvider` DSL. Routes must be serializable and implement `NavKey`. Use this for scenarios requiring state preservation across configuration changes. ```kotlin /* * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.nav3recipes.basicdsl import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.lifecycle.compose.dropUnlessResumed import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.ui.NavDisplay import com.example.nav3recipes.content.ContentBlue import com.example.nav3recipes.content.ContentGreen import com.example.nav3recipes.ui.setEdgeToEdgeConfig import kotlinx.serialization.Serializable @Serializable private data object RouteA : NavKey @Serializable private data class RouteB(val id: String) : NavKey class BasicDslActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { val backStack = rememberNavBackStack(RouteA) NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = entryProvider { entry { ContentGreen("Welcome to Nav3") { Button(onClick = dropUnlessResumed { backStack.add(RouteB("123")) }) { Text("Click to navigate") } } } entry { key -> ContentBlue("Route id: ${key.id} ") } } ) } } } ``` -------------------------------- ### Title Setter and Getter Source: https://github.com/android/skills/blob/main/play/engage-sdk-integration/references/common.md Methods to set and get the title of an item. ```APIDOC ## setTitle(String) ### Description Sets the title for the item. This is an optional field. ### Method setter ### Parameters - **title** (String) - Optional - The title to set. ``` ```APIDOC ## getTitle() ### Description Retrieves the current title of the item. ### Method getter ### Returns - **String** - The current title. ``` -------------------------------- ### Compute Dominator Tree for Heap Graph Source: https://github.com/android/skills/blob/main/profilers/perfetto-sql/references/perfetto-stdlib.md This example demonstrates how to prepare a heap graph for dominator tree computation by creating a compatible view and then applying the graph_dominator_tree macro. Ensure the graph is a single connected component with a defined root node. ```sql CREATE PERFETTO VIEW dominator_compatible_heap_graph AS -- Extract the edges from the heap graph which correspond to references -- between objects. SELECT owner_id AS source_node_id, owned_id as dest_node_id FROM heap_graph_reference JOIN heap_graph_object owner on heap_graph_reference.owner_id = owner.id WHERE owned_id IS NOT NULL AND owner.reachable UNION ALL -- Since a Java heap graph is a "forest" structure, we need to add a dummy -- "root" node which connects all the roots of the forest into a single -- connected component. SELECT (SELECT max(id) + 1 FROM heap_graph_object) as source_node_id, id FROM heap_graph_object WHERE root_type IS NOT NULL; SELECT * FROM graph_dominator_tree!( dominator_compatible_heap_graph, (SELECT max(id) + 1 FROM heap_graph_object) ); ``` -------------------------------- ### Source Setter and Getter Source: https://github.com/android/skills/blob/main/play/engage-sdk-integration/references/common.md Methods to set and get the source badge of an item. ```APIDOC ## setSource(Badge) ### Description Sets the source badge for the item. This is an optional field. ### Method setter ### Parameters - **source** (Badge) - Optional - The source badge to set. ``` ```APIDOC ## getSource() ### Description Retrieves the current source badge of the item. ### Method getter ### Returns - **Badge** - The current source badge. ``` -------------------------------- ### Implement M3 AppScaffold and ScreenScaffold Source: https://github.com/android/skills/blob/main/wear/wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md Structure navigation with AppScaffold and define screen-level content using ScreenScaffold. ```kotlin AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list" ) { composable("message_list") { MessageList(onMessageClick = { id -> navController.navigate("message_detail/$id") }) } composable("message_detail/{id}") { MessageDetail(id = it.arguments?.getString("id")!!) } } } } // Implementation of one of the screens in the navigation @Composable fun MessageDetail(id: String) { // .. Screen level content goes here val scrollState = rememberTransformingLazyColumnState() val padding = rememberResponsiveColumnPadding( first = ColumnItemType.BodyText ) ScreenScaffold( scrollState = scrollState, contentPadding = padding ) { scaffoldPaddingValues -> // Screen content goes here // ... ``` -------------------------------- ### Create analysis directory Source: https://github.com/android/skills/blob/main/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md Prepare the required directory structure for storing R8 analysis files. ```bash mkdir -p "$PWD/tmp/r8analysis" ``` -------------------------------- ### Action Element Example Source: https://github.com/android/skills/blob/main/devtools/android-cli/references/journeys.md Illustrates a basic UI interaction action within a journey. ```xml Click the red button ``` -------------------------------- ### Progress Percentage Setter and Getter Source: https://github.com/android/skills/blob/main/play/engage-sdk-integration/references/common.md Methods to set and get the progress percentage of an item. ```APIDOC ## setProgressPercentage(int) ### Description Sets the progress percentage for the item. This is a required field for 'ContinuationCluster'. ### Method setter ### Parameters - **progressPercentage** (int) - Required - The progress percentage to set. ``` ```APIDOC ## getProgressPercentage() ### Description Retrieves the current progress percentage of the item. ### Method getter ### Returns - **Integer** - The current progress percentage. ``` -------------------------------- ### Basic Navigation with Two Screens Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/basic.md Sets up a basic navigation flow between two screens, RouteA and RouteB. RouteA displays a welcome message and a button to navigate to RouteB, passing an ID. RouteB displays the provided ID. Requires `mutableStateListOf` for back stack management and `NavDisplay` for rendering. ```kotlin /* * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.nav3recipes.basic import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.remember import androidx.lifecycle.compose.dropUnlessResumed import androidx.navigation3.runtime.NavEntry import androidx.navigation3.ui.NavDisplay import com.example.nav3recipes.content.ContentBlue import com.example.nav3recipes.content.ContentGreen import com.example.nav3recipes.ui.setEdgeToEdgeConfig private data object RouteA private data class RouteB(val id: String) class BasicActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { val backStack = remember { mutableStateListOf(RouteA) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is RouteA -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = dropUnlessResumed { backStack.add(RouteB("123")) }) { Text("Click to navigate") } } } is RouteB -> NavEntry(key) { ContentBlue("Route id: ${key.id} ") } else -> { error("Unknown route: $key") } } } ) } } } ``` -------------------------------- ### BottomSheetSceneStrategy Imports Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/bottomsheet.md These are the necessary imports for implementing `BottomSheetSceneStrategy` and related components in your Navigation 3 setup. ```kotlin package com.example.nav3recipes.bottomsheet import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.ModalBottomSheetProperties import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.rememberLifecycleOwner import androidx3.navigation.runtime.NavEntry import androidx3.navigation.runtime.NavMetadataKey import androidx3.navigation.runtime.get import androidx3.navigation.runtime.metadata ``` -------------------------------- ### Create Android Project Source: https://github.com/android/skills/blob/main/devtools/android-cli/SKILL.md Generate a new Android project from a template. ```bash android create empty-activity --name="My App" --output=./my-app ``` -------------------------------- ### android_startup_threads View Source: https://github.com/android/skills/blob/main/profilers/perfetto-trace-analysis/references/perfetto-stdlib.md Maps a startup to the set of threads within processes that handled the activity start. ```APIDOC VIEW android_startup_threads -- Maps a startup to the set of threads on processes that handled the activity start. ( startup_id INT, ts INT, dur INT, upid INT, utid INT, thread_name STRING, is_main_thread BOOL ) ``` -------------------------------- ### Get Last Scrolled Backward Source: https://github.com/android/skills/blob/main/xr/display-glasses-with-jetpack-compose-glimmer/references/stackstate-source.md Indicates whether the last scroll action was in the backward direction. ```kotlin @get:Suppress("GetterSetterNames") override val lastScrolledBackward: Boolean get() = pagerState.lastScrolledBackward ``` -------------------------------- ### Set Content with NavBackStack and EntryProvider Source: https://github.com/android/skills/blob/main/navigation/navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-basic.md Configures the main content of the activity using NavBackStack and EntryProvider. This setup allows for different screens to be rendered based on the NavKey, including handling specific arguments for users and search queries. ```kotlin setContent { val backStack: NavBackStack = rememberNavBackStack(key) NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = entryProvider { entry { key -> EntryScreen(key.name) { TextContent("") } } entry { key -> EntryScreen("${key.name} : ${key.filter}") { TextContent("") val list = when { key.filter.isEmpty() -> LIST_USERS key.filter == UsersKey.FILTER_OPTION_ALL -> LIST_USERS else -> LIST_USERS.take(5) } FriendsList(list) } } entry { SearchKey -> EntryScreen(SearchKey.name) { TextContent("") val matchingUsers = LIST_USERS.filter { (SearchKey.firstName == null || it.firstName == SearchKey.firstName) && (SearchKey.location == null || it.location == SearchKey.location) && (SearchKey.ageMin == null || it.age >= SearchKey.ageMin) && (SearchKey.ageMax == null || it.age <= SearchKey.ageMax) } FriendsList(matchingUsers) } } } ) } ``` -------------------------------- ### Get Last Scrolled Forward Source: https://github.com/android/skills/blob/main/xr/display-glasses-with-jetpack-compose-glimmer/references/stackstate-source.md Indicates whether the last scroll action was in the forward direction. ```kotlin @get:Suppress("GetterSetterNames") override val lastScrolledForward: Boolean get() = pagerState.lastScrolledForward ``` -------------------------------- ### Font Family Creation Source: https://github.com/android/skills/blob/main/xr/display-glasses-with-jetpack-compose-glimmer/references/glimmersansflextypography-source.md A utility function to create a `FontFamily` from a `GoogleFont` and its `FontVariation.Settings`. This simplifies font setup. ```kotlin private fun FontFamily(font: GoogleFont, variationSettings: FontVariation.Settings): FontFamily = FontFamily(Font(googleFont = font, variationSettings = variationSettings)) ``` -------------------------------- ### Initialize the AppEngagePublishClient Source: https://github.com/android/skills/blob/main/play/engage-sdk-integration/references/android/guide/playcore/engage/tv/getting-started.md Initialize the client and verify service availability before attempting to publish data. ```kotlin val client = AppEngagePublishClient(context) client.isServiceAvailable().addOnCompleteListener { task -> if (task.isSuccessful && task.result) { // Service is available, proceed with publishing } else { // Service is not available or call failed } } ```