关于 portal
portal 是帮助开发者为已停售的 Meta Portal 设备构建或移植 Android 应用的技能,适用于拥有设备并希望侧载应用的人。它集中说明无 Google Mobile Services 的限制、设备界面要求、构建配置及调试流程,并配合 metavr 使用。
主要功能
- 01说明 Portal 设备兼容要求
- 02提供无 Google 服务依赖的开发指引
- 03涵盖触控屏与电视启动配置
- 04给出界面、无障碍和麦克风约束
- 05使用 metavr 执行设备调试
- 06提供 Android 工具链与移植参考
适用场景
- 01将现有 Android 应用移植到 Portal
- 02为 Portal 设备配置应用清单和启动入口
- 03排查应用安装后不显示或启动崩溃
- 04通过 metavr 查看日志和截取屏幕
MCP 相关
该技能与 metavr 配合使用;README 提及 metavr 可将 MCP 接入编辑器。技能本身提供 Portal 开发说明,未说明其暴露 MCP 工具。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ meta-quest/ agentic-tools --skill portal安装后在 Claude Code 中输入/portal确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
resources/android-sdk-setup.mdapp-requirements.mdcompose-theme.mddebugging.mddesign-guidelines.mddevice-setup.mdmetavr.mdnative-toolchain.mdporting-existing-apps.mdsample-prompts.mdsmart-camera-sdk.md详细介绍
Portal
此技能用于构建面向 Meta Portal 设备系列的 Android 应用。Portal 设备已停产(于 2022 年底停止销售),但现在已启用 ADB,因此所有者可以侧载自己的应用。
硬件:基于 Snapdragon 的 Android 平板电脑和电视棒,运行经过修改的 AOSP,不包含 Google Mobile Services。设备有多个型号,均为触屏或电视设备。根据设备不同,minSdkVersion 为 28(Android 9)或 29(Android 10)。
此技能与 metavr(Meta VR CLI)配合使用——请先安装它。所有地方都使用 metavr adb 代替原始 adb。有关通过 npx 一行安装、在编辑器中设置 MCP,以及与 Portal 相关的命令概览,请参阅 resources/metavr.md。完整的 metavr-cli 技能也包含在同一仓库中,可加载以获取更深入的参考。
硬性限制——编写任何代码前请先阅读
如果你只记得几件事,请记住这些。每一项都是 Portal 应用经常遇到的一类错误。
- 不使用 Google Mobile Services。 不使用 Play Services、Firebase、FCM、Play Billing、Google Sign-In、Google Maps SDK、AdMob 或 ML Kit。依赖 GMS 的应用会在启动时崩溃。请选择非 GMS 替代方案——请参阅
resources/app-requirements.md。 - 必须满足
minSdkVersion ≤ 28(Portal 硬件最高支持 API 29)。对于新应用,targetSdkVersion 29是最稳妥的默认值。对于移植现有应用,高于 29 的targetSdkVersion通常也能正常工作——已通过实测验证targetSdk = 36。除非观察到具体的运行时问题,否则不要浪费时间降低现有应用的目标 SDK。 - 必须配置 Launcher intent-filter。 触控设备需要
MAIN + LAUNCHER;Portal TV 需要MAIN + LEANBACK_LAUNCHER。不需要DEFAULT类别(已在 Portal 上通过实测验证——只有MAIN + LAUNCHER的应用也会显示在主屏幕磁贴网格中)。如果没有配置其中之一,应用虽然会安装,但永远不会显示在主屏幕上。 - 应用图标必须在
mipmap-xxxhdpi/中包含 PNG 文件作为回退。请在启动 Activity 上声明android:icon(触控设备)或android:banner(TV)。你也可以同时提供自适应图标(mipmap-anydpi-v26/)和其他密度的 PNG——当自适应 XML 无法渲染时,Portal 的启动器会正确回退到mipmap-xxxhdpi中的 PNG。仅包含自适应图标(没有 PNG 回退)的应用在 Portal 上不会显示可见图标。 - 没有联系人 API,也没有账户/凭据 API。
READ_CONTACTS会被拒绝。账户提供程序不会返回任何内容。 5a. 基本麦克风采集可用;远场/波束成形麦克风阵列不可用。 标准RECORD_AUDIO会打开AudioRecord流,并从handset-mic(单声道麦克风)接收真实音频。"Hey Portal" 唤醒词使用的远场波束成形阵列受 Meta 签名的原生权限(com.facebook.alohasdk.permission.RECORD_AUDIO_PRIVILEGED)限制,侧载应用无法使用。因此,基本语音功能可用;侧载应用无法实现唤醒词检测和高质量的远距离拾音。详情请参阅resources/app-requirements.md§ 麦克风采集。 - 采用适用于桌面的触控 UI,而不是手机形态。 Portal 放在台面或支架上,用户会在 50–100 cm 外进行交互。触控目标 ≥ 64 dp(主要操作为 96 dp),正文文本 ≥ 16 sp(Portal+ 上为 18 sp),优先采用横屏布局。完整的 Portal 设计系统(字体排版、间距、配色、WCAG 比例、TalkBack 规则)请参阅
resources/design-guidelines.md;对于 Jetpack Compose 应用,resources/compose-theme.md提供了可直接复制粘贴的主题起始模板,会将这些规则融入Color.kt/Theme.kt/Type.kt。 - 预留顶部约 64 dp 的空间(仅当顶部内容距离画布边缘不足 64 dp 时需要)。Portal 顶部有一条常驻系统浮层:返回/主页按钮(左上)和Wi-Fi/状态信息(右上)。它会浮在应用内容上方,不会自动添加安全区域内边距。顶部 UI 紧贴边缘的应用(边缘到边缘工具栏、粘性标题、全出血模态框)会被浮层遮挡。顶部内容自然位于画布边缘下方 ≥ 80 dp 的应用无需做任何更改。浮层胶囊为白色,因此顶部区域使用浅色背景的应用在增加内边距后还需要额外添加深色遮罩——请参阅
resources/app-requirements.md§ 顶部系统浮层。
设备矩阵
| 设备 | minSdkVersion | 连接方式 |
|---|---|---|
| Portal(第 1 代和第 2 代) | 28 / 29 | USB-C(背面) |
| Portal Mini | 29 | USB-C(背面) |
| Portal+(第 1 代和第 2 代) | 28 / 29 | USB-C(背面) |
| Portal Go | 29 | USB-C(背面橡胶盖下方) |
| Portal TV | 29 | USB-C |
如果要覆盖所有设备,请设置 minSdkVersion 28。如果无需支持第 1 代 Portal / Portal+,则可以将目标版本设为 29。
快速开始
先准备工具链,不要手动到处找。 构建需要主机上的两项内容:JDK(Gradle/AGP 在其上运行)和 Android SDK。使用 Google 的 android CLI 安装 SDK——不要翻遍文件系统去找 SDK。对于 JDK,如果已安装 Android Studio,请将 JAVA_HOME 指向 Android Studio 自带的 JBR;否则安装 Temurin 17。android CLI 只安装 SDK,不提供 JDK。 完整指南:resources/android-sdk-setup.md。
# 1) Get a JDK 17 (one-time, host machine — Gradle / AGP run on it; the `android` CLI does NOT install one)
# If Android Studio is installed, reuse its bundled JBR (no install needed):
# export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
# Otherwise install Temurin 17:
# brew install --cask temurin@17 && export JAVA_HOME="$(/usr/libexec/java_home -v 17)"
java -version # should report 17.x (or 21.x if using Android Studio JBR)
# 2) Install Google's `android` CLI (it manages the SDK), then install the SDK packages
# macOS: brew tap android/tap && brew install android-cli
# Any OS: curl -fsSL https://dl.google.com/android/cli/latest/darwin_arm64/install.sh | bash (see § 1 for other OSes)
# Windows: winget install --id Google.AndroidCLI
android update # keep the CLI current
# Install the SDK. For a new project: API 28 + 29. For porting, also install whatever compileSdk needs (often 35/36).
android sdk install platforms/android-28 platforms/android-29 platform-tools build-tools/34.0.0
export ANDROID_HOME="$HOME/Library/Android/sdk" # macOS — Linux uses ~/Android/Sdk
# 3) Install metavr (one-time, host machine — standalone binary, no Node.js needed)
# See resources/metavr.md for all install options (incl. npx without install) and MCP-into-your-editor setup.
curl -fsSL https://developers.meta.com/horizon/install-cli/ | sh # macOS/Linux
# Windows (PowerShell): iwr -useb https://developers.meta.com/horizon/install-cli/windows/ | iex
metavr --version
# (or with Node.js 16+: npx -y metavr --version, no install required)
# 4) Enable ADB on the Portal
# Portal: Settings → Debug → ADB Enabled. Enter PIN if prompted.
# Connect USB-C. Tap "Allow" on the device the first time you connect.
# 5) Verify
metavr device list
# Should list one Portal device. Example: 819PGF02P010SL23 device Portal aloha
# (or npx -y metavr device list)
# 6) Build + install + launch
# No ./gradlew in the project? Bootstrap the wrapper first — see resources/android-sdk-setup.md § 0a.
./gradlew assembleDebug
metavr app install -r app/build/outputs/apk/debug/app-debug.apk # -r/--replace reinstalls, keeping data
metavr app launch com.example.myapp # or: metavr adb shell am start -n com.example.myapp/.MainActivity
# (or prefix with npx -y if you use the npm distribution instead of the standalone binary)
如果 metavr device list 中没有显示设备,请再次轻触 Portal 上的 ADB Enabled——该开关可能与 USB 连接发生竞态。
构建配置
app/build.gradle.kts:
android {
compileSdk = 35
defaultConfig {
minSdk = 28
targetSdk = 29
}
}
compileSdk = 35(或最新版本)即可。与 Portal 兼容性相关的是 min/target。
Manifest
启动器入口因设备系列而异。
触控设备(Portal、Portal Mini、Portal+、Portal Go):
<activity
android:name=".MainActivity"
android:icon="@mipmap/ic_launcher"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Portal TV(使用 LEANBACK_LAUNCHER 和 android:banner,代替 android:icon):
<activity
android:name=".MainActivity"
android:banner="@drawable/banner"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
缺少这些配置时,应用虽然会安装,但不会显示。要通过一个 APK 支持两个设备系列,请在同一 activity 上声明这两种 intent filter。
可用 / 不可用的权限
| 功能 | 状态 |
|---|---|
| 摄像头 | 常规 CAMERA 权限 |
| 麦克风 | 常规 RECORD_AUDIO 权限 |
| 扬声器 | 无需权限 |
| 蓝牙 | 常规 BLUETOOTH* 权限 |
| 网络 | 常规 INTERNET / ACCESS_NETWORK_STATE |
| 触控 / 键盘输入 | 无需权限 |
| 存储写入 | 常规 WRITE_EXTERNAL_STORAGE(Android 9 模型) |
| 存储删除(跨应用) | 仅限应用自身拥有的内容。否则请使用:metavr adb shell rm,或安装文件管理器应用 |
联系人(READ_CONTACTS) | 不可用。 运行时会拒绝 |
设备账号(AccountManager) | 不可用。 账号提供方不会返回任何内容 |
Smart Camera SDK(待提供二进制文件)
Portal 的摄像头由系统 Smart Camera 服务驱动,该服务负责面部 / 身体跟踪、取景和自动平移缩放,以确保人物处于画面中。应用不会直接通过 Camera2 驱动摄像头来实现这些效果——它们会向 Smart Camera 服务请求会话,并传入 ModeSpec(自动取景、桌面取景、会议取景、固定裁剪等)。
独立的 Smart Camera SDK 正在开发中。计划中的 Gradle 坐标:com.facebook.portal:smartcamera:1.1.+。二进制文件发布前,请参阅 resources/smart-camera-sdk.md 中的 API 草图——接口形式相同,ModeSpec 模式相同,入口点也是 SmartCameraControlConnectionFactory。
仍可通过标准 Camera2 API 获取原始视频帧;Smart Camera SDK 用于控制取景,而非像素。
调试循环
metavr adb logcat # full logcat
metavr adb logcat *:E # errors only
metavr adb logcat -s AndroidRuntime DEBUG libc # crash signals
metavr log -c # clear the log buffer (NOT `metavr adb logcat -c` — that flag is rejected)
metavr adb shell dumpsys activity activities # what's running
metavr app clear com.example.myapp # wipe app data (or: metavr adb shell pm clear <pkg>)
metavr app uninstall com.example.myapp # uninstall
metavr capture screenshot -o screen.png # save a PNG of the screen
更多模式和常见故障情况(图标缺失、安装后应用不可见、应用首次启动时崩溃等),请参阅 resources/debugging.md。
资源
resources/metavr.md— metavr 是什么、单行安装命令、将 MCP 接入编辑器、与 Portal 相关的命令resources/device-setup.md— 面向用户的完整设备准备操作指南resources/android-sdk-setup.md— 安装 JDK 17、Android CLI、SDK 平台 / build-toolsresources/native-toolchain.md— NDK / CMake / Ninja 设置(项目包含原生代码时使用;介绍深度验证约定,因为仅靠source.properties并不足够)resources/app-requirements.md— 清单、图标、无 GMS、设计检查清单(深入介绍)resources/porting-existing-apps.md— 将现有 Android 应用移植到 Portal 的操作指南(无 GMS 版本、原生代码、常见故障)resources/design-guidelines.md— 字体排印、间距、颜色、无障碍功能、电视 / D-pad、Smart Camera 用户体验resources/compose-theme.md— 可直接复制粘贴的 Jetpack Compose 主题入门模板(强制深色主题、Portal 配色、内置 Inter 字体排印、触控目标),以及无 GMS 字体修复方法resources/smart-camera-sdk.md— Smart Camera API 概览(待提供二进制文件)resources/debugging.md—metavr adblogcat / 截图 / dumpsys 模式resources/sample-prompts.md— 可用于 Claude / Cursor / 等工具的入门提示词