From meta-vr
Guides porting existing Android 2D apps to Meta Quest and Horizon OS — input adaptation, panel layout, and design requirements. Use when adapting a mobile Android app for Quest.
How this skill is triggered — by the user, by Claude, or both
Slash command
/meta-vr:hz-android-2d-portingThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill when:
Use this skill when:
Horizon OS is built on Android (AOSP) and can run standard Android applications inside panels -- floating 2D windows positioned in 3D space. Most well-built Android apps work on Quest with minimal changes, but several areas require attention:
The goal of porting is to make the app feel native to the Quest experience while preserving existing functionality.
Invoke metavr (the Quest device CLI) via metavr <args>. The command is published as the npm package metavr, so if metavr is not on PATH you can run the same CLI via npx -y metavr <args> — no global install needed; npx fetches the latest published version on demand.
The examples in this doc call metavr directly; the npx -y metavr <args> form above is the equivalent when metavr is not on PATH (the published npm package is still metavr).
Install the existing APK on a connected Quest device and test basic functionality:
metavr app install path/to/your-app.apk
metavr app launch com.example.yourapp
Note any immediate issues: crashes, black screens, input problems, or layout breakage.
The most common porting issue is input. Touch events are translated from the controller pointer, but:
See Input Adaptation Reference for detailed guidance.
Panels are resizable and can have various aspect ratios. Your app must handle:
Use responsive layout strategies such as ConstraintLayout or Jetpack Compose. See Panel Layout Reference.
Update your build configuration to target Horizon OS:
// build.gradle.kts
android {
defaultConfig {
minSdk = 29 // Android 10 minimum
targetSdk = 34 // API 34 or higher required for all new 2D panel apps
}
}
Add required manifest entries for device targeting. See Gradle Setup Reference.
Test with all supported input methods:
Use the XR Simulator for rapid iteration, then validate on-device.
Before submitting to the Horizon Store:
| Feature | Status | Notes |
|---|---|---|
| Standard Android Views | Supported | TextView, RecyclerView, etc. |
| Jetpack Compose | Supported | Full Compose UI toolkit |
| WebView | Supported | Chromium-based |
| Media playback (ExoPlayer) | Supported | Video and audio |
| Networking (HTTP, WebSocket) | Supported | Wi-Fi connectivity |
| Room / SQLite | Supported | Local database |
| WorkManager | Supported | Background tasks |
| Notifications | Supported | Horizon OS notification panel |
| Bluetooth (peripherals) | Supported | Keyboard, mouse, gamepad |
| Android Accessibility APIs | Supported | TalkBack equivalent available |
| Feature | Status | Notes |
|---|---|---|
| Camera (front-facing) | Not available | No standard camera in 2D mode |
| Telephony / SMS | Not available | No cellular radio |
| NFC | Not available | No NFC hardware |
| GPS / Fine location | Limited | Wi-Fi-based location only |
| Fingerprint / BiometricPrompt | Not available | Use Meta account auth instead |
| Split-screen (multi-window) | Limited | Use Spatial SDK panels instead |
| Google Play Services | Not available | Use Meta equivalents or alternatives |
| ARCore | Not available | Use Meta Spatial SDK for spatial features |
| Multi-touch gestures | Limited | Single pointer from controller |
| Issue | Cause | Fix |
|---|---|---|
| App crashes on launch | Missing Google Play Services dependency | Remove or make GMS optional |
| Buttons too small to tap | Touch targets under 48dp | Increase minimum tap target size |
| No scroll in lists | Swipe-based scroll not triggered | Ensure RecyclerView/LazyColumn handles generic scroll events |
| Keyboard doesn't appear | Custom input field not using InputConnection | Use standard EditText or TextField |
| Layout broken | Fixed-size layout assumptions | Use responsive layouts with ConstraintLayout or Compose |
| App requests unavailable permissions | Camera, telephony, etc. | Guard with hasSystemFeature() checks |
| APK rejected for prohibited permissions | Library or plugin silently added a prohibited permission | Run aapt dump permissions your-app.apk, then check prohibited list |
| APK rejected for invalid signature | Signed with v1-only scheme | v2 signing is default in AGP 7.0+; for older AGP, add v2SigningEnabled = true to your signing config |
Apps not specifically targeting Horizon OS run in compatibility mode:
Apps that target Horizon OS with proper manifest entries run in native mode:
Quest devices have mobile-class hardware with strict thermal limits:
npx claudepluginhub meta-quest/agentic-tools --plugin meta-vrUpgrades Meta Quest apps to newer Horizon OS SDK versions with migration guides, deprecated API replacements, and changelog references.
Creates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.