reis-mobile 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +24 -0
- package/README.md +175 -168
- package/THIRD_PARTY_NOTICES.md +224 -4
- package/agents/android-architect.md +89 -0
- package/agents/android-performance-engineer.md +92 -0
- package/agents/android-test-engineer.md +97 -0
- package/agents/flutter-test-engineer.md +2 -0
- package/agents/ios-architect.md +93 -0
- package/agents/ios-performance-engineer.md +92 -0
- package/agents/ios-test-engineer.md +95 -0
- package/agents/lead-mobile.md +10 -1
- package/agents/mobile-staff-engineer.md +1 -1
- package/agents/rn-architect.md +94 -0
- package/agents/rn-performance-engineer.md +92 -0
- package/agents/rn-test-engineer.md +98 -0
- package/bin/reis-mobile.mjs +59 -17
- package/commands/debate.md +10 -1
- package/commands/debug.md +60 -0
- package/commands/reis-mobile.md +7 -2
- package/core/config/project.mjs +59 -0
- package/core/registry/frontmatter.mjs +15 -4
- package/core/registry/registry.mjs +21 -1
- package/core/router/intents.mjs +2 -0
- package/core/router/router.mjs +10 -5
- package/package.json +1 -1
- package/skills/android-adaptive/SKILL.md +304 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/container-behavior.md +112 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/get-started.md +69 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/index.md +81 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/item-behavior.md +170 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/container-properties.md +415 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/get-started.md +51 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/index.md +73 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/item-properties.md +170 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/mediaquery/index.md +333 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/tooling/debug.md +114 -0
- package/skills/android-adaptive/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
- package/skills/android-agp-9-upgrade/SKILL.md +106 -0
- package/skills/android-agp-9-upgrade/references/android/build/migrate-to-built-in-kotlin.md +416 -0
- package/skills/android-agp-9-upgrade/references/android/build/releases/agp-9-0-0-release-notes.md +554 -0
- package/skills/android-agp-9-upgrade/references/buildconfig.md +54 -0
- package/skills/android-agp-9-upgrade/references/ksp-kapt.md +39 -0
- package/skills/android-agp-9-upgrade/references/paparazzi-gradle-9.md +30 -0
- package/skills/android-agp-9-upgrade/references/recipes.md +62 -0
- package/skills/android-appfunctions/SKILL.md +74 -0
- package/skills/android-appfunctions/references/adb-interaction-testing.md +95 -0
- package/skills/android-appfunctions/references/context.md +26 -0
- package/skills/android-appfunctions/references/feature-discovery-analysis.md +71 -0
- package/skills/android-appfunctions/references/implementation-configuration.md +282 -0
- package/skills/android-appfunctions/references/kdoc-refinement-optimization.md +75 -0
- package/skills/android-appfunctions/references/migrate-to-service-entry-point.md +226 -0
- package/skills/android-camerax/SKILL.md +135 -0
- package/skills/android-camerax/references/camera1-to-camerax.md +198 -0
- package/skills/android-camerax/references/camera2-to-camerax.md +193 -0
- package/skills/android-camerax/references/expert-blueprints.md +58 -0
- package/skills/android-camerax/references/foldables.md +83 -0
- package/skills/android-camerax/references/immutability.md +60 -0
- package/skills/android-camerax/references/low-light.md +124 -0
- package/skills/android-camerax/references/mlkit-spatial.md +75 -0
- package/skills/android-camerax/references/modern-apis.md +42 -0
- package/skills/android-camerax/references/testing.md +69 -0
- package/skills/android-camerax/references/thermals.md +85 -0
- package/skills/android-camerax/references/wear-os.md +76 -0
- package/skills/android-camerax/references/xr.md +54 -0
- package/skills/android-cli/SKILL.md +474 -0
- package/skills/android-cli/references/interact.md +113 -0
- package/skills/android-cli/references/journeys.md +120 -0
- package/skills/android-code-review/SKILL.md +58 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/SKILL.md +340 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/design/ui/ai-glasses/guides/interaction/inputs.md +67 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/access-hardware-projected-context.md +388 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/buttons.md +139 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/cards.md +148 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/focus.md +107 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/icons.md +90 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/text.md +69 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/title-chips.md +82 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/request-hardware-permissions.md +213 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-samples-source.md +176 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-source.md +203 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-samples-source.md +296 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-source.md +515 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffect-source.md +224 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffectlevels-source.md +105 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmersansflextypography-source.md +270 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmertheme-source.md +182 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/icon-source.md +388 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconbutton-source.md +126 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconsizes-source.md +78 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/list-source.md +27 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/listitem-source.md +272 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/liststate-source.md +427 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/material-hct-source.md +217 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/projectedcontext-source.md +265 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stack-source.md +368 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackitemscope-source.md +440 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackstate-source.md +325 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/surface-source.md +1211 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-samples-source.md +101 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-source.md +131 -0
- package/skills/android-edge-to-edge/SKILL.md +429 -0
- package/skills/android-engage-sdk-integration/SKILL.md +130 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/faq.md +439 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/food.md +1149 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/healthandfitness.md +1055 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/listen.md +1050 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/otherverticals.md +1301 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/read.md +910 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/shopping.md +1224 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/social.md +719 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/travel.md +1413 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/continue-watching/index.md +19 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/entitlements.md +353 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/getting-started.md +202 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/recommendations.md +471 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/watch.md +1081 -0
- package/skills/android-engage-sdk-integration/references/clusters.md +154 -0
- package/skills/android-engage-sdk-integration/references/common.md +519 -0
- package/skills/android-engage-sdk-integration/references/patterns.md +527 -0
- package/skills/android-engage-sdk-integration/references/requests.md +260 -0
- package/skills/android-engage-sdk-integration/references/schemas/food.md +509 -0
- package/skills/android-engage-sdk-integration/references/schemas/listen.md +842 -0
- package/skills/android-engage-sdk-integration/references/schemas/other.md +220 -0
- package/skills/android-engage-sdk-integration/references/schemas/read.md +412 -0
- package/skills/android-engage-sdk-integration/references/schemas/shopping.md +357 -0
- package/skills/android-engage-sdk-integration/references/schemas/social.md +228 -0
- package/skills/android-engage-sdk-integration/references/schemas/travel.md +923 -0
- package/skills/android-engage-sdk-integration/references/schemas/tv.md +1226 -0
- package/skills/android-engage-sdk-integration/references/schemas/watch.md +1137 -0
- package/skills/android-engage-sdk-integration/references/troubleshooting.md +39 -0
- package/skills/android-gradle-build-debug/SKILL.md +71 -0
- package/skills/android-intent-security/SKILL.md +550 -0
- package/skills/android-leanback-to-compose-tv-migration/SKILL.md +743 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/get-started/navigation.md +372 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/browse.md +243 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/index.md +153 -0
- package/skills/android-media3-cast-integration/SKILL.md +236 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/create-castplayer.md +390 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/customize-castoptions.md +93 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/index.md +21 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/SKILL.md +127 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/analysis-of-the-project-and-layout.md +42 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/designsystems/migrate-xml-theme-to-compose.md +171 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/compose-in-views.md +299 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/views-in-compose.md +286 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/setup-compose-dependencies-and-compiler.md +197 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/identify-optimal-xml-candidate.md +31 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/xml-layout-migration.md +86 -0
- package/skills/android-ml-kit-genai-prompt-api/SKILL.md +124 -0
- package/skills/android-ml-kit-genai-prompt-api/references/get-started.md +272 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prefix-caching.md +146 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prompt-design.md +55 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prompt-optimization.md +74 -0
- package/skills/android-ml-kit-genai-prompt-api/references/structured-output.md +219 -0
- package/skills/android-ml-kit-genai-prompt-api/references/system-instructions.md +71 -0
- package/skills/android-navigation-3/SKILL.md +122 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/index.md +51 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md +670 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/animations.md +147 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basic.md +89 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicdsl.md +85 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicsaveable.md +90 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/bottomsheet.md +195 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/common-ui.md +200 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional-transitions.md +182 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional.md +230 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-custommatcher.md +176 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-staticuri.md +140 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-syntheticbackstack.md +184 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/dialog.md +107 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/lifecycle-owner.md +185 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-supportingpane.md +145 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-hilt.md +283 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-koin.md +287 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/multiple-backstacks.md +468 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/passingarguments.md +371 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-event.md +273 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-state.md +266 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-listdetail.md +435 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-twopane.md +244 -0
- package/skills/android-navigation-3/references/android/guide/navigation/type-safe-destinations.md +129 -0
- package/skills/android-navigation-event/SKILL.md +312 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/dispatcher.md +134 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/handle-back.md +217 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/index.md +83 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/setup.md +32 -0
- package/skills/android-play-billing-library-version-upgrade/SKILL.md +96 -0
- package/skills/android-play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md +1240 -0
- package/skills/android-play-billing-library-version-upgrade/references/migration-logic.md +78 -0
- package/skills/android-play-billing-library-version-upgrade/references/version-checklist.md +54 -0
- package/skills/android-play-policy-insights/SKILL.md +172 -0
- package/skills/android-play-policy-insights/resources/common_mandates.md +100 -0
- package/skills/android-play-policy-insights/resources/compliance_report_template.md +59 -0
- package/skills/android-play-policy-insights/resources/critic.md +86 -0
- package/skills/android-play-policy-insights/resources/goal_data_safety.md +212 -0
- package/skills/android-play-policy-insights/resources/goal_permissions_and_apis.md +459 -0
- package/skills/android-play-policy-insights/resources/goal_user_account.md +106 -0
- package/skills/android-play-policy-insights/resources/policies.json +321 -0
- package/skills/android-play-policy-insights/resources/scanner_config.json +843 -0
- package/skills/android-play-policy-insights/scripts/generate_report.py +860 -0
- package/skills/android-play-policy-insights/scripts/orchestrator.py +1313 -0
- package/skills/android-play-policy-insights/scripts/play_store_scraper.py +410 -0
- package/skills/android-play-policy-insights/scripts/scanner.py +261 -0
- package/skills/android-play-policy-insights/scripts/template_engine.py +243 -0
- package/skills/android-profiler/SKILL.md +60 -0
- package/skills/android-profiler/analysis/analysis_orchestrator.md +32 -0
- package/skills/android-profiler/analysis/workflows/perfetto-sql/perfetto_sql.md +28 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/perfetto_trace_analysis.md +121 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/guiding_principles.md +51 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/domain_hints_template.md +7 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_cpu.md +56 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_graphics.md +51 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_io.md +46 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_ipc.md +41 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_memory.md +55 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_power.md +33 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/per_candidate_analysis.md +172 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/triage.md +94 -0
- package/skills/android-profiler/recording/recording_orchestrator.md +36 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/perfetto_trace_recording.md +148 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/app_jank.pftxt +43 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/cpu_profile.pftxt +35 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/java_heap_dump.pftxt +21 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/long_background.pftxt +37 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/memory_counters.pftxt +45 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/native_heap.pftxt +21 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/sched_cpu.pftxt +33 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/trace_config_reference.md +102 -0
- package/skills/android-profiler/references/env_setup.md +15 -0
- package/skills/android-profiler/references/perfetto/setup.md +29 -0
- package/skills/android-profiler/references/perfetto/sql.md +327 -0
- package/skills/android-r8-analyzer/SKILL.md +72 -0
- package/skills/android-r8-analyzer/references/CONFIGURATION-ANALYZER.md +287 -0
- package/skills/android-r8-analyzer/references/CONFIGURATION.md +44 -0
- package/skills/android-r8-analyzer/references/KEEP-RULES-IMPACT-HIERARCHY.md +83 -0
- package/skills/android-r8-analyzer/references/REDUNDANT-RULES.md +222 -0
- package/skills/android-r8-analyzer/references/REFLECTION-GUIDE.md +139 -0
- package/skills/android-r8-analyzer/references/REPORT_FORMAT.md +51 -0
- package/skills/android-r8-analyzer/references/android/topic/performance/app-optimization/enable-app-optimization.md +252 -0
- package/skills/android-r8-analyzer/references/android/training/testing/other-components/ui-automator.md +312 -0
- package/skills/android-restore-credentials/SKILL.md +359 -0
- package/skills/android-restore-credentials/references/android/guide/topics/manifest/application-element.md +832 -0
- package/skills/android-restore-credentials/references/android/identity/passkeys/create-passkeys.md +327 -0
- package/skills/android-restore-credentials/references/android/identity/passkeys/sign-in-with-passkeys.md +219 -0
- package/skills/android-styles/SKILL.md +229 -0
- package/skills/android-styles/references/android/develop/ui/compose/designsystems/custom.md +459 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/fundamentals.md +421 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/state-animations.md +461 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/styles-vs-modifiers.md +48 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/theming.md +269 -0
- package/skills/android-verified-email/SKILL.md +432 -0
- package/skills/android-verified-email/references/android/identity/credential-manager/index.md +67 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/credential-verifier.md +166 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification-implementation.md +313 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification.md +158 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/index.md +112 -0
- package/skills/android-verified-email/references/android/identity/passkeys/create-passkeys.md +327 -0
- package/skills/android-verified-email/references/android/identity/sign-in/credential-manager-webview.md +84 -0
- package/skills/android-wear-compose-m3/SKILL.md +365 -0
- package/skills/android-wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md +677 -0
- package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md +123 -0
- package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md.txt +123 -0
- package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md +430 -0
- package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md.txt +430 -0
- package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md +99 -0
- package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md.txt +99 -0
- package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md +141 -0
- package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md.txt +141 -0
- package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md +56 -0
- package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md.txt +56 -0
- package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md +153 -0
- package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md.txt +153 -0
- package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md +131 -0
- package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md.txt +131 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md +169 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md.txt +169 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md +282 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md.txt +282 -0
- package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md +335 -0
- package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md.txt +335 -0
- package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md +377 -0
- package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md.txt +377 -0
- package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md +165 -0
- package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md.txt +165 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md +91 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md.txt +91 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md +496 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md.txt +496 -0
- package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md +470 -0
- package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md.txt +470 -0
- package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md +67 -0
- package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md.txt +67 -0
- package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md +162 -0
- package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md.txt +162 -0
- package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md +78 -0
- package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md.txt +78 -0
- package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md +131 -0
- package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md.txt +131 -0
- package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md +74 -0
- package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md.txt +74 -0
- package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md +63 -0
- package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md.txt +63 -0
- package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md +60 -0
- package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md.txt +60 -0
- package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md +125 -0
- package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md.txt +125 -0
- package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md +116 -0
- package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md.txt +116 -0
- package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md +68 -0
- package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md.txt +68 -0
- package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md +50 -0
- package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md.txt +50 -0
- package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md +177 -0
- package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md.txt +177 -0
- package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md +651 -0
- package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md.txt +651 -0
- package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md +57 -0
- package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md.txt +57 -0
- package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md +110 -0
- package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md.txt +110 -0
- package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md +204 -0
- package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md.txt +204 -0
- package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md +139 -0
- package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md.txt +139 -0
- package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md +111 -0
- package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md.txt +111 -0
- package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md +184 -0
- package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md.txt +184 -0
- package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md +263 -0
- package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md.txt +263 -0
- package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md +105 -0
- package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md.txt +105 -0
- package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md +146 -0
- package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md.txt +146 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md +97 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md.txt +97 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md +66 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md.txt +66 -0
- package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md +86 -0
- package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md.txt +86 -0
- package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md +148 -0
- package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md.txt +148 -0
- package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md +166 -0
- package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md.txt +166 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md +172 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md.txt +172 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md +367 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md.txt +367 -0
- package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md +66 -0
- package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md.txt +66 -0
- package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md +115 -0
- package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md.txt +115 -0
- package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md +71 -0
- package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md.txt +71 -0
- package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md +151 -0
- package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md.txt +151 -0
- package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md +65 -0
- package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md.txt +65 -0
- package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md +246 -0
- package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md.txt +246 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md +89 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md.txt +89 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md +309 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md.txt +309 -0
- package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md +205 -0
- package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md.txt +205 -0
- package/skills/{architecture-feature-first → flutter-architecture-feature-first}/SKILL.md +1 -1
- package/skills/{bloc → flutter-bloc}/SKILL.md +1 -1
- package/skills/flutter-build-debug/SKILL.md +66 -0
- package/skills/{code-review → flutter-code-review}/SKILL.md +1 -1
- package/skills/{dart-3-updates → flutter-dart-3-updates}/SKILL.md +1 -1
- package/skills/{dart-fix-runtime-errors → flutter-dart-fix-runtime-errors}/SKILL.md +1 -1
- package/skills/{dart-resolve-package-conflicts → flutter-dart-resolve-package-conflicts}/SKILL.md +1 -1
- package/skills/{dart-run-static-analysis → flutter-dart-run-static-analysis}/SKILL.md +1 -1
- package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/SKILL.md +1 -1
- package/skills/{effective-dart → flutter-effective-dart}/SKILL.md +1 -1
- package/skills/{provider → flutter-provider}/SKILL.md +1 -1
- package/skills/{riverpod → flutter-riverpod}/SKILL.md +1 -1
- package/skills/ios-cocoapods-debug/SKILL.md +65 -0
- package/skills/ios-code-review/SKILL.md +56 -0
- package/skills/ios-xcode-build-debug/SKILL.md +66 -0
- package/skills/{detect-mobile-stack → mobile-detect-stack}/SKILL.md +1 -1
- package/skills/mobile-firebase/SKILL.md +54 -0
- package/skills/mobile-firebase/references/android/ai-logic.md +31 -0
- package/skills/mobile-firebase/references/android/analytics.md +33 -0
- package/skills/mobile-firebase/references/android/app-check.md +36 -0
- package/skills/mobile-firebase/references/android/auth.md +44 -0
- package/skills/mobile-firebase/references/android/crashlytics.md +31 -0
- package/skills/mobile-firebase/references/android/firestore.md +44 -0
- package/skills/mobile-firebase/references/android/functions.md +33 -0
- package/skills/mobile-firebase/references/android/in-app-messaging.md +28 -0
- package/skills/mobile-firebase/references/android/messaging.md +41 -0
- package/skills/mobile-firebase/references/android/realtime-database.md +50 -0
- package/skills/mobile-firebase/references/android/remote-config.md +43 -0
- package/skills/mobile-firebase/references/android/sql-connect.md +31 -0
- package/skills/mobile-firebase/references/android/storage.md +39 -0
- package/skills/mobile-firebase/references/android.md +30 -0
- package/skills/{firebase-ai/SKILL.md → mobile-firebase/references/flutter/ai-logic.md} +2 -8
- package/skills/{firebase-analytics/SKILL.md → mobile-firebase/references/flutter/analytics.md} +2 -8
- package/skills/{firebase-app-check/SKILL.md → mobile-firebase/references/flutter/app-check.md} +2 -8
- package/skills/{firebase-auth/SKILL.md → mobile-firebase/references/flutter/auth.md} +2 -8
- package/skills/{firebase-crashlytics/SKILL.md → mobile-firebase/references/flutter/crashlytics.md} +2 -8
- package/skills/{firebase-cloud-firestore/SKILL.md → mobile-firebase/references/flutter/firestore.md} +2 -8
- package/skills/{firebase-cloud-functions/SKILL.md → mobile-firebase/references/flutter/functions.md} +2 -8
- package/skills/{firebase-in-app-messaging/SKILL.md → mobile-firebase/references/flutter/in-app-messaging.md} +2 -8
- package/skills/{firebase-messaging/SKILL.md → mobile-firebase/references/flutter/messaging.md} +2 -8
- package/skills/{firebase-database/SKILL.md → mobile-firebase/references/flutter/realtime-database.md} +2 -8
- package/skills/{firebase-remote-config/SKILL.md → mobile-firebase/references/flutter/remote-config.md} +2 -8
- package/skills/{flutterfire-configure/SKILL.md → mobile-firebase/references/flutter/setup-flutterfire.md} +1 -8
- package/skills/{firebase-data-connect/SKILL.md → mobile-firebase/references/flutter/sql-connect.md} +2 -8
- package/skills/{firebase-storage/SKILL.md → mobile-firebase/references/flutter/storage.md} +2 -8
- package/skills/mobile-firebase/references/flutter.md +36 -0
- package/skills/mobile-firebase/references/ios/ai-logic.md +30 -0
- package/skills/mobile-firebase/references/ios/analytics.md +33 -0
- package/skills/mobile-firebase/references/ios/app-check.md +36 -0
- package/skills/mobile-firebase/references/ios/auth.md +48 -0
- package/skills/mobile-firebase/references/ios/crashlytics.md +34 -0
- package/skills/mobile-firebase/references/ios/firestore.md +53 -0
- package/skills/mobile-firebase/references/ios/functions.md +35 -0
- package/skills/mobile-firebase/references/ios/in-app-messaging.md +26 -0
- package/skills/mobile-firebase/references/ios/messaging.md +45 -0
- package/skills/mobile-firebase/references/ios/realtime-database.md +49 -0
- package/skills/mobile-firebase/references/ios/remote-config.md +44 -0
- package/skills/mobile-firebase/references/ios/sql-connect.md +33 -0
- package/skills/mobile-firebase/references/ios/storage.md +36 -0
- package/skills/mobile-firebase/references/ios.md +28 -0
- package/skills/mobile-firebase/references/react-native/ai-logic.md +32 -0
- package/skills/mobile-firebase/references/react-native/analytics.md +43 -0
- package/skills/mobile-firebase/references/react-native/app-check.md +35 -0
- package/skills/mobile-firebase/references/react-native/auth.md +50 -0
- package/skills/mobile-firebase/references/react-native/crashlytics.md +36 -0
- package/skills/mobile-firebase/references/react-native/firestore.md +45 -0
- package/skills/mobile-firebase/references/react-native/functions.md +28 -0
- package/skills/mobile-firebase/references/react-native/in-app-messaging.md +27 -0
- package/skills/mobile-firebase/references/react-native/messaging.md +46 -0
- package/skills/mobile-firebase/references/react-native/realtime-database.md +46 -0
- package/skills/mobile-firebase/references/react-native/remote-config.md +32 -0
- package/skills/mobile-firebase/references/react-native/sql-connect.md +11 -0
- package/skills/mobile-firebase/references/react-native/storage.md +30 -0
- package/skills/mobile-firebase/references/react-native.md +29 -0
- package/skills/mobile-test/SKILL.md +63 -0
- package/skills/mobile-test/references/android/setup/GUIDE.md +183 -0
- package/skills/mobile-test/references/android/setup/references/android/develop/ui/compose/testing/common-patterns.md +181 -0
- package/skills/mobile-test/references/android/setup/references/android/studio/preview/compose-screenshot-testing.md +255 -0
- package/skills/mobile-test/references/android/setup/references/android/training/dependency-injection/hilt-testing.md +447 -0
- package/skills/mobile-test/references/android.md +83 -0
- package/skills/{dart-collect-coverage/SKILL.md → mobile-test/references/flutter/coverage.md} +2 -11
- package/skills/{dart-generate-test-mocks/SKILL.md → mobile-test/references/flutter/generate-mocks.md} +2 -11
- package/skills/{flutter-add-integration-test/SKILL.md → mobile-test/references/flutter/integration-tests.md} +2 -11
- package/skills/{dart-migrate-to-checks-package/SKILL.md → mobile-test/references/flutter/migrate-to-checks.md} +2 -13
- package/skills/{mockito/SKILL.md → mobile-test/references/flutter/mockito.md} +1 -8
- package/skills/{mocktail/SKILL.md → mobile-test/references/flutter/mocktail.md} +1 -8
- package/skills/{patrol-e2e-testing/SKILL.md → mobile-test/references/flutter/patrol.md} +1 -8
- package/skills/{testing/SKILL.md → mobile-test/references/flutter/testing-guidelines.md} +1 -8
- package/skills/{dart-add-unit-test/SKILL.md → mobile-test/references/flutter/unit-tests.md} +2 -11
- package/skills/{flutter-add-widget-test/SKILL.md → mobile-test/references/flutter/widget-tests.md} +2 -11
- package/skills/mobile-test/references/flutter.md +44 -0
- package/skills/mobile-test/references/ios.md +79 -0
- package/skills/mobile-test/references/react-native.md +62 -0
- /package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/examples/json_patterns.dart +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android-camerax
|
|
3
|
+
description: Provide technical guidance for Android camera development with CameraX.
|
|
4
|
+
Use when implementing camera features, handling asynchronous recording lifecycles,
|
|
5
|
+
wiring low-level hardware interop using CameraX, or integrating ML Kit or Media3
|
|
6
|
+
effects.
|
|
7
|
+
license: Apache-2.0
|
|
8
|
+
source: https://github.com/android/skills
|
|
9
|
+
routing: manual
|
|
10
|
+
stacks: [android]
|
|
11
|
+
metadata:
|
|
12
|
+
author: Google LLC
|
|
13
|
+
last-updated: '2026-08-14'
|
|
14
|
+
keywords:
|
|
15
|
+
- recipe
|
|
16
|
+
- Android
|
|
17
|
+
- Camera
|
|
18
|
+
- Camera1
|
|
19
|
+
- Camera2
|
|
20
|
+
- CameraX
|
|
21
|
+
- migration
|
|
22
|
+
- Compose
|
|
23
|
+
- guide
|
|
24
|
+
- dependencies
|
|
25
|
+
- PreviewView
|
|
26
|
+
- CameraXViewfinder
|
|
27
|
+
- ImageCapture
|
|
28
|
+
- VideoCapture
|
|
29
|
+
- ImageAnalysis.
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
This skill provides procedural guidance and standard patterns for building
|
|
33
|
+
camera applications on Android, with a focus on CameraX, including its
|
|
34
|
+
`Camera2Interop` utilities, and Media3 integrations.
|
|
35
|
+
|
|
36
|
+
## Core workflows
|
|
37
|
+
|
|
38
|
+
### Handling immutable API patterns
|
|
39
|
+
|
|
40
|
+
Various Android camera and media APIs, especially CameraX `VideoCapture`, use a
|
|
41
|
+
**fluent, immutable builder-like pattern** where methods return a new instance.
|
|
42
|
+
Failing to reassign these results in settings, such as audio, being ignored.
|
|
43
|
+
|
|
44
|
+
**Pattern: Reassignment is required**
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
```kotlin
|
|
48
|
+
// WRONG
|
|
49
|
+
run {
|
|
50
|
+
val pending = recorder.prepareRecording(context, opts)
|
|
51
|
+
pending.withAudioEnabled() // This returns a new instance which is ignored
|
|
52
|
+
val active = pending.start(exec, listener)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// CORRECT
|
|
56
|
+
run {
|
|
57
|
+
val pending = recorder.prepareRecording(context, opts)
|
|
58
|
+
.withAudioEnabled() // Chaining works
|
|
59
|
+
val active = pending.start(exec, listener)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ALSO CORRECT
|
|
63
|
+
run {
|
|
64
|
+
var pending = recorder.prepareRecording(context, opts)
|
|
65
|
+
pending = pending.withAudioEnabled() // Reassignment
|
|
66
|
+
val active = pending.start(exec, listener)
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
<br />
|
|
71
|
+
|
|
72
|
+
See [immutability](references/immutability.md) for a list of affected classes.
|
|
73
|
+
|
|
74
|
+
### Migrating to CameraX
|
|
75
|
+
|
|
76
|
+
When migrating legacy camera codebases to the CameraX Jetpack library:
|
|
77
|
+
|
|
78
|
+
- **Camera1 to CameraX** : For migrating legacy `android.hardware.Camera` implementations, surface handling, and manual lifecycles, see the [Camera1 migration guide](references/camera1-to-camerax.md).
|
|
79
|
+
- **Camera2 to CameraX** : For migrating more recent but verbose `android.hardware.camera2` implementations, session state callbacks, and interop patterns, see the [Camera2 migration guide](references/camera2-to-camerax.md).
|
|
80
|
+
|
|
81
|
+
### Comprehensive feature blueprinting
|
|
82
|
+
|
|
83
|
+
For multi-step features that involve multiple files and hardware-level wiring,
|
|
84
|
+
follow the [Structural Blueprinting](references/expert-blueprints.md) approach to avoid
|
|
85
|
+
system timeouts. Such complex features include:
|
|
86
|
+
|
|
87
|
+
- **Manual controls** : Break down into the `ViewModel` state, the controller layer, and the `Camera2Interop` wiring in the session.
|
|
88
|
+
- **RAW capture**: Separate JPEG and RAW output configurations into discrete build steps.
|
|
89
|
+
- **Custom effects** : Prefer `Media3Effect` or `SurfaceProcessor` over manual OpenGL pipelines unless absolute performance is required.
|
|
90
|
+
- **Low-light** : See [low-light](references/low-light.md) for Night Mode and LLB guidance.
|
|
91
|
+
- **Foldables** : See [foldables](references/foldables.md) for handling dynamic postures and hinge states.
|
|
92
|
+
- **XR, AR, and VR** : See [xr](references/xr.md) for spatial tracking, passthrough synchronization, and latency guardrails.
|
|
93
|
+
- **Thermals and power** : See [thermals](references/thermals.md) for managing `StreamUseCase` optimizations and `PowerManager` thermal states.
|
|
94
|
+
- **Testing and mocking** : See [testing](references/testing.md) for using `FakeCameraConfig`, handling asynchronous lifecycles, and validating analysis pipelines.
|
|
95
|
+
- **ML Kit spatial analysis** : See [mlkit-spatial](references/mlkit-spatial.md) for coordinate mapping, rotation logic, and mirrored lens handling.
|
|
96
|
+
- **Wear OS camera remote** : See [wear-os](references/wear-os.md) for circular UI constraints, Data Layer API syncing, and remote trigger logic.
|
|
97
|
+
|
|
98
|
+
See [expert-blueprints](references/expert-blueprints.md) for step-by-step guides.
|
|
99
|
+
|
|
100
|
+
### API discovery
|
|
101
|
+
|
|
102
|
+
Always use higher-level abstractions instead of low-level manual wiring:
|
|
103
|
+
|
|
104
|
+
- **Analysis** : Use `MlKitAnalyzer` instead of manual `ImageAnalysis.Analyzer`.
|
|
105
|
+
- **Filters and effects** : Use `Media3Effect` for standard post-processing.
|
|
106
|
+
- **Multi-camera** : Use `ConcurrentCamera` APIs for dual-stream setups.
|
|
107
|
+
|
|
108
|
+
See [modern-apis](references/modern-apis.md) for current recommendations.
|
|
109
|
+
|
|
110
|
+
### Code quality and architectural rules
|
|
111
|
+
|
|
112
|
+
Adhere to the following Android ecosystem standard patterns when building your
|
|
113
|
+
camera implementations:
|
|
114
|
+
|
|
115
|
+
- **Testing, fakes over mocks** : Avoid mocking libraries like `Mockito`, especially for multi-step CameraX interfaces like `ImageProxy`. Build "Fakes" to verify state rather than unreliable implementation details.
|
|
116
|
+
- **Google Truth assertions** : Use `assertThat` over standard `JUnit` assertions like `assertEquals` for improved readability.
|
|
117
|
+
- **Explicit test runners** : Always define an explicit `@RunWith` for test classes to ensure the CI environment executes them correctly.
|
|
118
|
+
- **Semantic UI merging** : When building custom camera controls in Compose, such as a button with an `Icon` and `Text`, use `semantics {
|
|
119
|
+
mergeDescendants = true }` to ensure screen readers announce them as a single, coherent unit.
|
|
120
|
+
|
|
121
|
+
## Hardware and device diversity
|
|
122
|
+
|
|
123
|
+
Camera apps run on a wide variety of hardware, from mobile phones and
|
|
124
|
+
foldables to tablets, laptops, and even smart appliances. Have consideration
|
|
125
|
+
for the specific hardware the app is running on.
|
|
126
|
+
|
|
127
|
+
- **Form factors**: Account for screen size and orientation changes on foldables and tablets.
|
|
128
|
+
- **Multi-camera arrays**: Some devices have a rear-facing camera and a front-facing camera. Other devices have multiple rear-facing cameras, such as wide-angle and telephoto lenses.
|
|
129
|
+
- **Feature parity**: Features like flash or auto-focus behave differently across hardware. For example, CameraX handles both physical flash, back, and screen-based flash, front, and both must be considered when implementing flash functionality.
|
|
130
|
+
|
|
131
|
+
## Common pitfalls
|
|
132
|
+
|
|
133
|
+
- **Asynchronous lifecycles** : Check `isRecording` state before attempting to stop or pause. Handle `VideoRecordEvent.Start` for UI state updates, not just the initial call.
|
|
134
|
+
- **Thread safety**: Camera callbacks often run on background executors. Dispatch UI updates on the main thread.
|
|
135
|
+
- **Permission handling** : Check `CAMERA` permission; check for `RECORD_AUDIO` specifically when enabling audio in `VideoCapture`.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
## Remove `Camera1` implementation
|
|
2
|
+
|
|
3
|
+
1. Delete all `android.hardware.Camera` instances.
|
|
4
|
+
2. Delete `SurfaceView` and `SurfaceHolder.Callback` implementations `surfaceCreated`, `surfaceChanged`, and `surfaceDestroyed`.
|
|
5
|
+
3. Remove custom lifecycle handling that opens or releases the camera in `onResume` or `onPause`.
|
|
6
|
+
4. Remove manual matrix calculations for orientation.
|
|
7
|
+
|
|
8
|
+
## Initialize `ProcessCameraProvider`
|
|
9
|
+
|
|
10
|
+
Request the `ProcessCameraProvider` and bind use cases to the Activity or
|
|
11
|
+
Fragment lifecycle.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
val context = LocalContext.current
|
|
16
|
+
val lifecycleOwner = LocalLifecycleOwner.current
|
|
17
|
+
LaunchedEffect(context, lifecycleOwner) {
|
|
18
|
+
val cameraProvider = ProcessCameraProvider.getInstance(context).await()
|
|
19
|
+
|
|
20
|
+
val cameraSelector = CameraSelector.Builder()
|
|
21
|
+
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
|
22
|
+
.build()
|
|
23
|
+
|
|
24
|
+
val preview = Preview.Builder().build()
|
|
25
|
+
val imageCapture = ImageCapture.Builder()
|
|
26
|
+
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
|
|
27
|
+
.build()
|
|
28
|
+
|
|
29
|
+
cameraProvider.unbindAll() // Unbind before rebinding
|
|
30
|
+
|
|
31
|
+
val camera = cameraProvider.bindToLifecycle(
|
|
32
|
+
lifecycleOwner,
|
|
33
|
+
cameraSelector,
|
|
34
|
+
preview,
|
|
35
|
+
imageCapture
|
|
36
|
+
)
|
|
37
|
+
val cameraControl = camera.cameraControl
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
<br />
|
|
42
|
+
|
|
43
|
+
## Implement the preview and tap-to-focus
|
|
44
|
+
|
|
45
|
+
Choose exactly one of the following patterns based on the app's UI toolkit:
|
|
46
|
+
|
|
47
|
+
### Option A: For Android Views
|
|
48
|
+
|
|
49
|
+
Use `androidx.camera.view.PreviewView`.
|
|
50
|
+
|
|
51
|
+
1. **Set up preview**:
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
```kotlin
|
|
55
|
+
preview.setSurfaceProvider(previewView.surfaceProvider)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
<br />
|
|
59
|
+
|
|
60
|
+
2. **Handle tap-to-focus**:
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
```kotlin
|
|
64
|
+
val factory = previewView.meteringPointFactory
|
|
65
|
+
val point = factory.createPoint(x, y) // x, y from touch event
|
|
66
|
+
val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF).build()
|
|
67
|
+
cameraControl?.startFocusAndMetering(action)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
<br />
|
|
71
|
+
|
|
72
|
+
### Option B: For Jetpack Compose
|
|
73
|
+
|
|
74
|
+
Use `androidx.camera.compose.CameraXViewfinder`.
|
|
75
|
+
|
|
76
|
+
1. **Set up preview and SurfaceRequest**:
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
```kotlin
|
|
80
|
+
var surfaceRequest by remember { mutableStateOf<SurfaceRequest?>(null) }
|
|
81
|
+
val preview = remember {
|
|
82
|
+
Preview.Builder().build().apply {
|
|
83
|
+
setSurfaceProvider { request -> surfaceRequest = request }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
<br />
|
|
89
|
+
|
|
90
|
+
2. **Render viewfinder**:
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
```kotlin
|
|
94
|
+
surfaceRequest?.let { request ->
|
|
95
|
+
CameraXViewfinder(
|
|
96
|
+
surfaceRequest = request,
|
|
97
|
+
coordinateTransformer = coordinateTransformer,
|
|
98
|
+
modifier = Modifier
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
<br />
|
|
104
|
+
|
|
105
|
+
3. **Handle tap-to-focus in Compose**:
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
```kotlin
|
|
109
|
+
// Inside your tap gesture handler...
|
|
110
|
+
val surfaceCoords = with(coordinateTransformer) { offset.transform() }
|
|
111
|
+
val factory = SurfaceOrientedMeteringPointFactory(
|
|
112
|
+
request.resolution.width.toFloat(),
|
|
113
|
+
request.resolution.height.toFloat()
|
|
114
|
+
)
|
|
115
|
+
val point = factory.createPoint(surfaceCoords.x, surfaceCoords.y)
|
|
116
|
+
val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF).build()
|
|
117
|
+
cameraControl?.startFocusAndMetering(action)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
<br />
|
|
121
|
+
|
|
122
|
+
4. **Update target rotation for Compose**:
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
```kotlin
|
|
126
|
+
LaunchedEffect(configuration) {
|
|
127
|
+
if (!view.isInEditMode) {
|
|
128
|
+
val rotation = view.display?.rotation ?: Surface.ROTATION_0
|
|
129
|
+
imageCapture.targetRotation = rotation
|
|
130
|
+
preview.targetRotation = rotation
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
<br />
|
|
136
|
+
|
|
137
|
+
## Capture a photo
|
|
138
|
+
|
|
139
|
+
Use the `ImageCapture` use case to take the picture. The `ImageProxy` handles
|
|
140
|
+
rotation directly.
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
```kotlin
|
|
144
|
+
imageCapture.takePicture(
|
|
145
|
+
cameraExecutor,
|
|
146
|
+
object : ImageCapture.OnImageCapturedCallback() {
|
|
147
|
+
override fun onCaptureSuccess(image: ImageProxy) {
|
|
148
|
+
val buffer = image.planes[0].buffer
|
|
149
|
+
val bytes = ByteArray(buffer.remaining())
|
|
150
|
+
buffer.get(bytes)
|
|
151
|
+
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
|
|
152
|
+
|
|
153
|
+
// Adjust rotation natively via ImageProxy
|
|
154
|
+
val matrix = Matrix()
|
|
155
|
+
matrix.postRotate(image.imageInfo.rotationDegrees.toFloat())
|
|
156
|
+
if (lensFacing == CameraSelector.LENS_FACING_FRONT) {
|
|
157
|
+
matrix.postScale(-1f, 1f) // Mirror for front camera
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
val rotatedBitmap = Bitmap.createBitmap(
|
|
161
|
+
bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
// MUST close proxy
|
|
165
|
+
image.close()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
override fun onError(exception: ImageCaptureException) {
|
|
169
|
+
Log.e("CameraX", "Capture failed: ${exception.message}", exception)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
<br />
|
|
176
|
+
|
|
177
|
+
## Switch cameras
|
|
178
|
+
|
|
179
|
+
To flip between front and rear cameras, change the `CameraSelector` and
|
|
180
|
+
retrigger the `ProcessCameraProvider` logic.
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
```kotlin
|
|
184
|
+
lensFacing = if (lensFacing == CameraSelector.LENS_FACING_BACK) {
|
|
185
|
+
CameraSelector.LENS_FACING_FRONT
|
|
186
|
+
} else {
|
|
187
|
+
CameraSelector.LENS_FACING_BACK
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
<br />
|
|
192
|
+
|
|
193
|
+
## Follow constraints
|
|
194
|
+
|
|
195
|
+
- **Don't manage the camera lifecycle manually** : Bind the camera to a `LifecycleOwner` through the `ProcessCameraProvider`. Avoid manual camera open or close logic in `onResume` or `onPause`.
|
|
196
|
+
- **Don't calculate focus matrices manually** : `MeteringPointFactory` handles coordinate transformations, including device rotation offsets. Avoid custom matrix implementations.
|
|
197
|
+
- **Don't forget to close the `ImageProxy`** : Remember to invoke `image.close()` in the capture callback. Skipping this call locks the capture pipeline and interrupts subsequent photos.
|
|
198
|
+
- **Don't wrap `PreviewView` in `AndroidView` for Compose code** : For Compose UI layouts, use `CameraXViewfinder`. Compiling `PreviewView` in an `AndroidView` is an earlier fallback option that introduces resizing issues.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Camera2 offers granular control but introduces boilerplate: managing
|
|
2
|
+
`CameraDevice` states, `CameraCaptureSession` lifecycles, background threads,
|
|
3
|
+
`HandlerThread`, and manual orientation calculations.
|
|
4
|
+
|
|
5
|
+
CameraX simplifies this by binding high-level `UseCase`s such as `Preview`,
|
|
6
|
+
`ImageCapture`, and `ImageAnalysis` directly to Android lifecycles, handling
|
|
7
|
+
thread management and device-specific workarounds automatically.
|
|
8
|
+
|
|
9
|
+
*** ** * ** ***
|
|
10
|
+
|
|
11
|
+
## Remove Camera2 boilerplate
|
|
12
|
+
|
|
13
|
+
Migrating to CameraX removes manual setup code:
|
|
14
|
+
|
|
15
|
+
1. **Delete manual thread handling** : Remove `HandlerThread`, `Handler`, and executors dedicated to camera background tasks. CameraX manages its own threads.
|
|
16
|
+
2. **Remove session and device callbacks** : Delete `CameraDevice.StateCallback` and `CameraCaptureSession.StateCallback` implementations.
|
|
17
|
+
3. **Remove surface management** : Remove manual routing of `Surface` objects from `TextureView` or `SurfaceView` to the camera device.
|
|
18
|
+
4. **Remove manual orientation logic** : Delete calculations involving `CameraCharacteristics.SENSOR_ORIENTATION` and display rotation for adjusting preview and capture orientation.
|
|
19
|
+
|
|
20
|
+
*** ** * ** ***
|
|
21
|
+
|
|
22
|
+
## Initialize `ProcessCameraProvider`
|
|
23
|
+
|
|
24
|
+
Request the `ProcessCameraProvider` and bind your use cases to the
|
|
25
|
+
`LifecycleOwner` activity or fragment. This replaces the
|
|
26
|
+
`CameraManager.openCamera` flow.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
val context = LocalContext.current
|
|
31
|
+
val lifecycleOwner = LocalLifecycleOwner.current
|
|
32
|
+
LaunchedEffect(context, lifecycleOwner) {
|
|
33
|
+
val cameraProvider = ProcessCameraProvider.getInstance(context).await()
|
|
34
|
+
|
|
35
|
+
val cameraSelector = CameraSelector.Builder()
|
|
36
|
+
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
|
|
37
|
+
.build()
|
|
38
|
+
|
|
39
|
+
val preview = Preview.Builder().build()
|
|
40
|
+
val imageCapture = ImageCapture.Builder()
|
|
41
|
+
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
|
|
42
|
+
.build()
|
|
43
|
+
|
|
44
|
+
// ImageAnalysis is common when migrating from Camera2 ImageReader
|
|
45
|
+
val imageAnalysis = ImageAnalysis.Builder()
|
|
46
|
+
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
|
|
47
|
+
.build()
|
|
48
|
+
|
|
49
|
+
cameraProvider.unbindAll()
|
|
50
|
+
|
|
51
|
+
val camera = cameraProvider.bindToLifecycle(
|
|
52
|
+
lifecycleOwner,
|
|
53
|
+
cameraSelector,
|
|
54
|
+
preview,
|
|
55
|
+
imageCapture,
|
|
56
|
+
imageAnalysis
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
<br />
|
|
62
|
+
|
|
63
|
+
*** ** * ** ***
|
|
64
|
+
|
|
65
|
+
## Implement the preview and tap-to-focus
|
|
66
|
+
|
|
67
|
+
CameraX handles surface configuration automatically. Choose based on your UI
|
|
68
|
+
toolkit:
|
|
69
|
+
|
|
70
|
+
### Option A: For Android Views
|
|
71
|
+
|
|
72
|
+
Use `androidx.camera.view.PreviewView` in your layout, and bind it to the
|
|
73
|
+
`Preview` use case.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
```kotlin
|
|
77
|
+
preview.setSurfaceProvider(previewView.surfaceProvider)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
<br />
|
|
81
|
+
|
|
82
|
+
### Option B: For Jetpack Compose
|
|
83
|
+
|
|
84
|
+
Use `androidx.camera.compose.CameraXViewfinder`.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
```kotlin
|
|
88
|
+
var surfaceRequest by remember { mutableStateOf<SurfaceRequest?>(null) }
|
|
89
|
+
val preview = remember {
|
|
90
|
+
Preview.Builder().build().apply {
|
|
91
|
+
setSurfaceProvider { request -> surfaceRequest = request }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
<br />
|
|
97
|
+
|
|
98
|
+
*** ** * ** ***
|
|
99
|
+
|
|
100
|
+
## Capture a photo
|
|
101
|
+
|
|
102
|
+
Replace `ImageReader` capture flows and
|
|
103
|
+
`CaptureRequest.Builder.TEMPLATE_STILL_CAPTURE` with the `ImageCapture` use
|
|
104
|
+
case. CameraX handles the rotation natively using the returned `ImageProxy`.
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
```kotlin
|
|
108
|
+
imageCapture.takePicture(
|
|
109
|
+
cameraExecutor,
|
|
110
|
+
object : ImageCapture.OnImageCapturedCallback() {
|
|
111
|
+
override fun onCaptureSuccess(image: ImageProxy) {
|
|
112
|
+
val buffer = image.planes[0].buffer
|
|
113
|
+
val bytes = ByteArray(buffer.remaining())
|
|
114
|
+
buffer.get(bytes)
|
|
115
|
+
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
|
|
116
|
+
if (bitmap != null) {
|
|
117
|
+
val matrix = Matrix()
|
|
118
|
+
matrix.postRotate(image.imageInfo.rotationDegrees.toFloat())
|
|
119
|
+
if (lensFacing == CameraSelector.LENS_FACING_FRONT) {
|
|
120
|
+
matrix.postScale(-1f, 1f)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
val rotatedBitmap = Bitmap.createBitmap(
|
|
124
|
+
bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// MUST close proxy
|
|
129
|
+
image.close()
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
override fun onError(exception: ImageCaptureException) {
|
|
133
|
+
Log.e("CameraX", "Capture failed: ${exception.message}", exception)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
<br />
|
|
140
|
+
|
|
141
|
+
*** ** * ** ***
|
|
142
|
+
|
|
143
|
+
## Implement image analysis
|
|
144
|
+
|
|
145
|
+
If you were using `ImageReader` in Camera2 to access raw frames, e.g., for QR
|
|
146
|
+
scanning or ML,, replace it with the CameraX `ImageAnalysis` use case.
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
```kotlin
|
|
150
|
+
imageAnalysis.setAnalyzer(cameraExecutor) { imageProxy ->
|
|
151
|
+
try {
|
|
152
|
+
val rotationDegrees = imageProxy.imageInfo.rotationDegrees
|
|
153
|
+
// Process image here (e.g., run object detection)
|
|
154
|
+
// ...
|
|
155
|
+
} finally {
|
|
156
|
+
// MUST close the imageProxy to avoid blocking the pipeline
|
|
157
|
+
imageProxy.close()
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
<br />
|
|
163
|
+
|
|
164
|
+
*** ** * ** ***
|
|
165
|
+
|
|
166
|
+
## Use Camera2 interop
|
|
167
|
+
|
|
168
|
+
If your app requires specific Camera2 configuration options, such as custom
|
|
169
|
+
exposure modes or flash settings, that aren't exposed directly in CameraX,
|
|
170
|
+
use `Camera2Interop` to apply them to your CameraX use cases.
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
```kotlin
|
|
174
|
+
// Use Camera2Interop to set Camera2-specific capture options
|
|
175
|
+
val extender = Camera2Interop.Extender(imageCaptureBuilder)
|
|
176
|
+
extender.setCaptureRequestOption(
|
|
177
|
+
CaptureRequest.CONTROL_AE_MODE,
|
|
178
|
+
CaptureRequest.CONTROL_AE_MODE_OFF
|
|
179
|
+
).setCaptureRequestOption(
|
|
180
|
+
CaptureRequest.FLASH_MODE,
|
|
181
|
+
CaptureRequest.FLASH_MODE_TORCH
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
<br />
|
|
186
|
+
|
|
187
|
+
*** ** * ** ***
|
|
188
|
+
|
|
189
|
+
## Follow constraints
|
|
190
|
+
|
|
191
|
+
- **Don't open the CameraDevice manually** : Let CameraX manage device opening and closing using `bindToLifecycle`.
|
|
192
|
+
- **Don't forget to close `ImageProxy`** : In both `ImageCapture` and `ImageAnalysis` callbacks, you **must** call `image.close()`. Failure to do so will block the camera pipeline.
|
|
193
|
+
- **Don't block the ImageAnalysis thread** : The analyzer runs frame-by-frame. If you need to perform heavy computations, offload them to a background worker and close the `ImageProxy` as soon as possible.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Complex camera features often fail due to "Agent Stall" or timeouts when
|
|
2
|
+
attempted in a single turn. Use these blueprints to break tasks into manageable
|
|
3
|
+
phases.
|
|
4
|
+
|
|
5
|
+
## Manual controls
|
|
6
|
+
|
|
7
|
+
### Phase one: ViewModel and state
|
|
8
|
+
|
|
9
|
+
1. Define a `ManualSettings` data class.
|
|
10
|
+
2. Add a `MutableStateFlow<ManualSettings>` to your `CameraViewModel`.
|
|
11
|
+
3. Implement the Jetpack Compose UI with sliders and switches to update this flow.
|
|
12
|
+
|
|
13
|
+
### Phase two: Controller wiring
|
|
14
|
+
|
|
15
|
+
1. In `CameraController.kt`, create a new function `updateManualSettings(settings: ManualSettings)`.
|
|
16
|
+
2. Map these settings into the `CameraSystem` layer.
|
|
17
|
+
|
|
18
|
+
### Phase three: CameraX `Camera2Interop` wiring
|
|
19
|
+
|
|
20
|
+
1. In `CameraSession.kt`, use the `Camera2Interop.Extender` utility to access Camera2 capture request keys.
|
|
21
|
+
2. Apply the hardware keys:
|
|
22
|
+
- `CaptureRequest.SENSOR_SENSITIVITY` to set ISO sensitivity.
|
|
23
|
+
- `CaptureRequest.SENSOR_EXPOSURE_TIME` to set exposure time.
|
|
24
|
+
- `CaptureRequest.LENS_FOCUS_DISTANCE` to set focus distance.
|
|
25
|
+
3. **Critical** : If manual exposure is active, set `CaptureRequest.CONTROL_AE_MODE` to `CameraMetadata.CONTROL_AE_MODE_OFF`. ---
|
|
26
|
+
|
|
27
|
+
## RAW and JPEG capture
|
|
28
|
+
|
|
29
|
+
### Phase one: Output configuration
|
|
30
|
+
|
|
31
|
+
1. Verify device support for RAW capture using `CameraInfo`.
|
|
32
|
+
2. Configure `ImageCapture.Builder` with `OUTPUT_FORMAT_RAW_JPEG` or `OUTPUT_FORMAT_RAW`.
|
|
33
|
+
|
|
34
|
+
### Phase two: Implementation
|
|
35
|
+
|
|
36
|
+
1. Provide `ImageCapture.OutputFileOptions` for the target storage locations.
|
|
37
|
+
2. Invoke `takePicture`. CameraX internally manages `DngCreator` to wrap RAW data with the required `CameraCharacteristics` and `CaptureResult` metadata.
|
|
38
|
+
|
|
39
|
+
*** ** * ** ***
|
|
40
|
+
|
|
41
|
+
## Apply image effects
|
|
42
|
+
|
|
43
|
+
### Phase one: Effects selection
|
|
44
|
+
|
|
45
|
+
1. Use the `androidx.media3:media3-effect` dependency.
|
|
46
|
+
2. Use `RgbFilter` or `HslAdjustment` for standard color grading.
|
|
47
|
+
|
|
48
|
+
### Phase two: Application
|
|
49
|
+
|
|
50
|
+
1. Configure `Composition.Builder` or `MediaItem.Builder` with the list of effects.
|
|
51
|
+
2. Inject the list of effects into the CameraX `Recorder` or `Preview` using the `setEffects` method.
|
|
52
|
+
|
|
53
|
+
*** ** * ** ***
|
|
54
|
+
|
|
55
|
+
## Low-light capture
|
|
56
|
+
|
|
57
|
+
For guidance on Night Mode Extensions and Low Light Boost,
|
|
58
|
+
[low-light.md](https://developer.android.com/agents/skills/camera/camerax/references/low-light).
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Foldable devices introduce unique challenges for camera applications, including
|
|
2
|
+
dynamic layout changes, multiple display orientations, and physical device
|
|
3
|
+
postures, such as tabletop and book modes.
|
|
4
|
+
|
|
5
|
+
## Manage fold states and postures
|
|
6
|
+
|
|
7
|
+
| State | Posture | User interaction | Implementation goal |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `FLAT` | Standard | Full screen preview | Conventional mobile phone layout. |
|
|
10
|
+
| `HALF_OPENED` | Tabletop | Lower half for controls | Split-screen layout, viewfinder on top, controls on bottom. |
|
|
11
|
+
| `HALF_OPENED` | Book | Side-by-side | Viewfinder on one panel, gallery and controls on the other. |
|
|
12
|
+
|
|
13
|
+
*** ** * ** ***
|
|
14
|
+
|
|
15
|
+
## Follow the implementation guide
|
|
16
|
+
|
|
17
|
+
### Detect posture changes
|
|
18
|
+
|
|
19
|
+
Use the Jetpack WindowManager library to observe the device's hinge state and
|
|
20
|
+
fold layout.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
```kotlin
|
|
24
|
+
lifecycleScope.launch {
|
|
25
|
+
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
|
26
|
+
windowInfoTracker.windowLayoutInfo(activity)
|
|
27
|
+
.collect { layoutInfo ->
|
|
28
|
+
val displayFeature = layoutInfo.displayFeatures
|
|
29
|
+
.filterIsInstance<FoldingFeature>()
|
|
30
|
+
.firstOrNull()
|
|
31
|
+
|
|
32
|
+
updateCameraLayout(displayFeature)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
<br />
|
|
39
|
+
|
|
40
|
+
### Handle tabletop mode
|
|
41
|
+
|
|
42
|
+
In Tabletop mode, horizontal fold, you should move the viewfinder to the top
|
|
43
|
+
half of the screen and the controls to the bottom half to prevent the user from
|
|
44
|
+
seeing a "bent" image.
|
|
45
|
+
|
|
46
|
+
- **Identify orientation:** Check `FoldingFeature.orientation`.
|
|
47
|
+
- **Calculate geometry:** Use `FoldingFeature.bounds` to identify the hinge's physical location on the screen.
|
|
48
|
+
- **Update UI:** Apply padding or constraints to move the `PreviewView` above the hinge.
|
|
49
|
+
|
|
50
|
+
### Coordinate mapping and `Viewport`
|
|
51
|
+
|
|
52
|
+
When the UI layout changes due to a fold, you **must** update the `Viewport` to
|
|
53
|
+
ensure that tap-to-focus and image capture coordinates remain accurate.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
```kotlin
|
|
57
|
+
val viewport = ViewPort.Builder(Rational(viewfinder.width, viewfinder.height), display.rotation)
|
|
58
|
+
.setScaleType(ViewPort.FILL_CENTER)
|
|
59
|
+
.build()
|
|
60
|
+
|
|
61
|
+
val useCaseGroup = UseCaseGroup.Builder()
|
|
62
|
+
.addUseCase(preview)
|
|
63
|
+
.setViewPort(viewport)
|
|
64
|
+
.build()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
<br />
|
|
68
|
+
|
|
69
|
+
### Rear display mode
|
|
70
|
+
|
|
71
|
+
Some foldables allow using the rear camera with the cover display while the
|
|
72
|
+
device is unfolded.
|
|
73
|
+
|
|
74
|
+
- **Verification:** If available through OEM SDKs or Android 14 (API level 34) or higher, check `DeviceState.REAR_DISPLAY_STATE`.
|
|
75
|
+
- **Logic:** Handle preview detachment and reattachment on different display surfaces with varying aspect ratios.
|
|
76
|
+
|
|
77
|
+
*** ** * ** ***
|
|
78
|
+
|
|
79
|
+
## Foldable pitfalls
|
|
80
|
+
|
|
81
|
+
- **Hinge distortion:** Don't span the camera preview across a hinge in `HALF_OPENED` state.
|
|
82
|
+
- **Physical orientation:** The camera sensor's physical orientation relative to the screen often changes when you fold or unfold the device. Always rely on `CameraInfo.getSensorRotationDegrees`.
|
|
83
|
+
- **Latency:** Rebinding `UseCase` objects during a fold event is expensive. Use the internal scaling of `PreviewView` before performing a full `bindToLifecycle` reconfiguration.
|