You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Meta Quest 2自定义Android 2D启动器无法识别为默认Home应用

Meta Quest 2自定义VR启动器不被识别问题排查与解决

我正在使用Kotlin和Jetpack Compose为Meta Quest 2开发自定义启动器,目标是替换默认的Oculus Home,但在AndroidManifest.xml中添加必要的Intent Filter后,应用仍不被识别为启动器。该应用在安卓手机上运行正常。

现有代码

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.VR_MODE" />
    <uses-permission android:name="com.oculus.auth.fbpermission.USE_ACCOUNTS_META_INTERNAL_ONLY"/>
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
    <uses-feature android:name="android.hardware.vr.headtracking" android:required="true"/>
    <uses-feature android:name="android.hardware.vr.high_performance" android:required="true"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TestOrbitterApplication"
        tools:targetApi="31">

        <meta-data android:name="android.software.vr.mode" android:value="true" />

        <!-- Custom Launcher Configuration -->
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:theme="@style/Theme.TestOrbitterApplication"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.HOME" />
            </intent-filter>
        </activity>
    </application>
</manifest>

MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            TestOrbitterApplicationTheme {
                AppListScreen()
            }
        }
    }

    private fun getInstalledApps(): List<AppInfo> {
        val pm = packageManager
        val apps = mutableListOf<AppInfo>()

        val packages = pm.getInstalledApplications(PackageManager.GET_META_DATA)

        for (app in packages) {
            val label = pm.getApplicationLabel(app).toString()
            val icon = pm.getApplicationIcon(app)
            val packageName = app.packageName

            // Exclude system apps (optional)
            if (pm.getLaunchIntentForPackage(packageName) != null) {
                apps.add(AppInfo(label, icon, packageName))
            }
        }
        return apps
    }

    @Composable
    fun AppListScreen() {
        val apps = remember { getInstalledApps() }

        LazyColumn(modifier = Modifier.fillMaxSize()) {
            items(apps) { app ->
                AppItem(app)
            }
        }
    }

    @Composable
    fun AppItem(app: AppInfo) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(10.dp)
                .clickable {
                    launchApp(app.packageName)
                },
            horizontalArrangement = Arrangement.Start
        ) {
            Image(
                bitmap = app.icon.toBitmap().asImageBitmap(),
                contentDescription = app.name,
                modifier = Modifier.size(48.dp)
            )
            Spacer(modifier = Modifier.width(10.dp))
            Text(text = app.name, style = MaterialTheme.typography.bodyLarge)
        }
    }

    private fun launchApp(packageName: String) {
        val intent = packageManager.getLaunchIntentForPackage(packageName)
        if (intent != null) {
            startActivity(intent)
        } else {
            Log.e("Launcher", "App not found: $packageName")
        }
    }
}

data class AppInfo(val name: String, val icon: Drawable, val packageName: String)

fun Drawable.toBitmap(): Bitmap {
    if (intrinsicWidth <= 0 || intrinsicHeight <= 0) {
        // Create a fallback placeholder icon (black 48x48)
        return Bitmap.createBitmap(48, 48, Bitmap.Config.ARGB_8888).apply {
            eraseColor(android.graphics.Color.BLACK)
        }
    }

    val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
    val canvas = android.graphics.Canvas(bitmap)
    setBounds(0, 0, canvas.width, canvas.height)
    draw(canvas)
    return bitmap
}

已尝试的ADB命令及结果

  • 命令:adb shell cmd package set-home-activity com.chicmic.testorbitterapplication/.MainActivity
    错误:Failed to set default home.
  • 命令:adb shell pm list packages | grep "com.chicmic.testorbitterapplication"
    结果:package:com.chicmic.testorbitterapplication
  • 命令:adb shell pm grant com.chicmic.testorbitterapplication android.permission.SET_HOME_APP
    错误:Exception occurred while executing 'grant': java.lang.IllegalArgumentException: Unknown permission: android.permission.SET_HOME_APP
  • 命令:adb shell am start -c android.intent.category.HOME -a android.intent.action.MAIN
    结果:Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] } Warning: Activity not started, intent has been delivered to currently running top-most instance.
  • 命令:adb shell cmd package resolve-activity --brief android.intent.action.MAIN android.intent.category.HOME
    结果:No activity found

解决方法

1. 添加Oculus专属Intent Category

Meta Quest的系统启动器识别需要额外的Oculus特定类别,修改Activity的Intent Filter:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.HOME" />
    <!-- 新增Oculus HOME类别 -->
    <category android:name="com.oculus.intent.category.HOME" />
</intent-filter>

2. 调整Activity的VR适配属性

Quest设备要求启动器Activity具备特定的屏幕配置,添加以下属性到Activity标签:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:theme="@style/Theme.TestOrbitterApplication"
    android:launchMode="singleTask"
    android:resizeableActivity="false"
    android:screenOrientation="landscape">
    <!-- Intent Filter 内容 -->
</activity>

3. 清理无效权限

移除com.oculus.auth.fbpermission.USE_ACCOUNTS_META_INTERNAL_ONLY权限,该权限为Meta内部应用专用,第三方应用无法获取,会导致系统验证失败。

4. 使用正确的ADB命令设置默认启动器

Quest设备的定制系统使用不同的命令设置默认启动器:

# 清除现有默认启动器设置
adb shell cmd package reset-preferred-apps

# 设置你的应用为默认启动器
adb shell am set-default-home com.chicmic.testorbitterapplication/.MainActivity

5. 验证启动器识别状态

执行以下命令检查系统是否识别你的启动器:

adb shell cmd package query-intent --action android.intent.action.MAIN --category android.intent.category.HOME

如果输出包含你的应用包名,说明系统已识别,此时可以长按Quest的Home键,选择你的应用作为默认启动器。

内容的提问来源于stack exchange,提问作者Kanwarpreet Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:27:05