Erste Aktivität für KI-Brillen erstellen

XR‑Geräte, für die der Leitfaden gilt
Dieser Leitfaden hilft Ihnen dabei, Erlebnisse für die folgenden Arten von XR-Geräten zu entwickeln.
KI‑Brille

Das Erlebnis mit der KI‑Brille basiert auf der vorhandenen Android-ActivityFramework- API und umfasst zusätzliche Konzepte, um die besonderen Aspekte der KI‑Brille zu unterstützen. Im Gegensatz zu XR‑Headsets, auf denen eine vollständige APK auf dem Gerät ausgeführt wird, verwenden KI‑Brillen eine spezielle Aktivität, die in der vorhandenen App auf Ihrem Smartphone ausgeführt wird. Diese Aktivität wird vom Hostgerät auf die KI‑Brille projiziert.

Wenn Sie das Erlebnis mit der KI‑Brille für Ihre App erstellen möchten, erweitern Sie Ihre vorhandene Smartphone-App indem Sie eine neue projizierte Activity für die KI‑Brille erstellen. Diese Aktivität dient als Haupteinstiegspunkt für Ihre App auf der KI‑Brille. Dieser Ansatz vereinfacht die Entwicklung, da Sie die Geschäftslogik zwischen Ihren Smartphone- und KI‑Brillen-Erlebnissen gemeinsam nutzen können.

Versionskompatibilität

Prüfen Sie die Anforderungen an die Android SDK-Kompatibilität für das Jetpack XR SDK.

Abhängigkeiten

Fügen Sie die folgenden Bibliotheksabhängigkeiten für die KI‑Brille hinzu:

Groovy

dependencies {
    implementation "androidx.xr.runtime:runtime:1.0.0-alpha12"
    implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha11"
    implementation "androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha11"
    implementation "androidx.xr.projected:projected:1.0.0-alpha06"
    implementation "androidx.xr.arcore:arcore:1.0.0-alpha12"
}

Kotlin

dependencies {
    implementation("androidx.xr.runtime:runtime:1.0.0-alpha12")
    implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha11")
    implementation("androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha11")
    implementation("androidx.xr.projected:projected:1.0.0-alpha06")
    implementation("androidx.xr.arcore:arcore:1.0.0-alpha12")
}

Aktivität im Manifest Ihrer App deklarieren

Wie bei anderen Arten von Aktivitäten müssen Sie Ihre Aktivität in der Manifestdatei Ihrer App deklarieren, damit das System sie sehen und ausführen kann.

<application>
  <activity
      android:name="com.example.xr.projected.GlassesMainActivity"
      android:exported="true"
      android:requiredDisplayCategory="xr_projected"
      android:label="Example AI Glasses activity">
      <intent-filter>
          <action android:name="android.intent.action.MAIN" />
      </intent-filter>
  </activity>
</application>

Wichtige Punkte zum Code

  • Gibt xr_projected für das Attribut android:requiredDisplayCategory an, um dem System mitzuteilen, dass diese Aktivität einen projizierten Kontext verwenden soll, um auf die Hardware eines verbundenen Geräts zuzugreifen.

Aktivität erstellen

Als Nächstes erstellen Sie eine kleine Aktivität, mit der etwas auf der KI‑Brille angezeigt werden kann, wenn das Display eingeschaltet ist.

@OptIn(ExperimentalProjectedApi::class)
class GlassesMainActivity : ComponentActivity() {

    private var displayController: ProjectedDisplayController? = null
    private var isVisualUiSupported by mutableStateOf(false)
    private var areVisualsOn by mutableStateOf(true)
    private var isPermissionDenied by mutableStateOf(false)

    // Register the permissions launcher using the ProjectedPermissionsResultContract.
    private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> =
        registerForActivityResult(ProjectedPermissionsResultContract()) { results ->
            if (results[Manifest.permission.CAMERA] == true) {
                isPermissionDenied = false
                initializeGlassesFeatures()
            } else {
                // Handle permission denial.
                isPermissionDenied = true
            }
        }

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

        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onDestroy(owner: LifecycleOwner) {
                displayController?.close()
                displayController = null
            }
        })

        if (hasCameraPermission()) {
            initializeGlassesFeatures()
        } else {
            requestHardwarePermissions()
        }

        setContent {
            GlimmerTheme {
                HomeScreen(
                    areVisualsOn = areVisualsOn,
                    isVisualUiSupported = isVisualUiSupported,
                    isPermissionDenied = isPermissionDenied,
                    onRetryPermission = { requestHardwarePermissions() },
                    onClose = { finish() }
                )
            }
        }
    }

    private fun initializeGlassesFeatures() {
        lifecycleScope.launch {
            // Check device capabilities
            val projectedDeviceController = ProjectedDeviceController.create(this@GlassesMainActivity)
            isVisualUiSupported = projectedDeviceController.capabilities.contains(CAPABILITY_VISUAL_UI)

            val controller = ProjectedDisplayController.create(this@GlassesMainActivity)
            displayController = controller
            val observer = GlassesLifecycleObserver(
                context = this@GlassesMainActivity,
                controller = controller,
                onVisualsChanged = { visualsOn -> areVisualsOn = visualsOn }
            )
            lifecycle.addObserver(observer)
        }
    }

    private fun hasCameraPermission(): Boolean {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
                PackageManager.PERMISSION_GRANTED
    }

    private fun requestHardwarePermissions() {
        val params = ProjectedPermissionsRequestParams(
            permissions = listOf(Manifest.permission.CAMERA),
            rationale = "Camera access is required to overlay digital content on your physical environment."
        )
        requestPermissionLauncher.launch(listOf(params))
    }
}

Wichtige Punkte zum Code

Zusammensetzbare Funktion implementieren

Die von Ihnen erstellte Aktivität verweist auf eine zusammensetzbare Funktion HomeScreen, die Sie implementieren müssen. Im folgenden Code wird Jetpack Compose Glimmer verwendet, um eine zusammensetzbare Funktion zu definieren, mit der Text auf dem Display der KI‑Brille angezeigt werden kann:

@Composable
fun HomeScreen(
    areVisualsOn: Boolean,
    isVisualUiSupported: Boolean,
    isPermissionDenied: Boolean,
    onRetryPermission: () -> Unit,
    onClose: () -> Unit,
    modifier: Modifier = Modifier
) {
    Box(
        modifier = modifier
            .surface(focusable = false)
            .fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        if (isPermissionDenied) {
            Card(
                title = { Text("Permission Required") },
                action = { Button(onClick = onClose) { Text("Exit") } }
            ) {
                Text("Camera access is needed to use AI glasses features.")
                Button(onClick = onRetryPermission) { Text("Retry") }
            }
        } else if (isVisualUiSupported) {
            Card(
                title = { Text("Android XR") },
                action = {
                    Button(onClick = onClose) {
                        Text("Close")
                    }
                }
            ) {
                if (areVisualsOn) {
                    Text("Hello, AI Glasses!")
                } else {
                    Text("Display is off. Audio guidance active.")
                }
            }
        } else {
            Text("Audio Guidance Mode Active")
        }
    }
}

Wichtige Punkte zum Code

  • Wie bereits in Ihrer Aktivität definiert, enthält die Funktion HomeScreen die zusammensetzbaren Inhalte, die der Nutzer sieht, wenn das Display der KI‑Brille eingeschaltet ist.
  • Die Jetpack Compose Glimmer Text-Komponente zeigt den Text „Hallo, KI‑Brille!“ auf dem Display der Brille an.
  • Die Jetpack Compose Glimmer-Komponente Button schließt die Aktivität, indem sie finish() über onClose in der KI‑Brillen-Aktivität aufruft.

Prüfen, ob die KI‑Brille verbunden ist

Mit der Methode ProjectedContext.isProjectedDeviceConnected können Sie prüfen, ob die KI‑Brille eines Nutzers mit seinem Smartphone verbunden ist, bevor Sie Ihre Aktivität starten. Diese Methode gibt einen Flow<Boolean> zurück, den Ihre App beobachten kann, um Echtzeit-Updates zum Verbindungsstatus zu erhalten.

Aktivität starten

Nachdem Sie eine grundlegende Aktivität erstellt haben, können Sie sie auf Ihrer Brille starten. Um auf die Hardware der Brille zuzugreifen, muss Ihre App Ihre Aktivität mit bestimmten Optionen starten, die dem System mitteilen, dass ein projizierter Kontext verwendet werden soll. Das sehen Sie im folgenden Code:

val options = ProjectedContext.createProjectedActivityOptions(context)
val intent = Intent(context, GlassesMainActivity::class.java)
context.startActivity(intent, options.toBundle())

Die createProjectedActivityOptions Methode in ProjectedContext generiert die erforderlichen Optionen, um Ihre Aktivität in einem projizierten Kontext zu starten. Der Parameter context kann ein Kontext vom Smartphone oder vom Gerät der Brille sein.

Nächste Schritte

Nachdem Sie Ihre erste Aktivität für die KI‑Brille erstellt haben, können Sie die Funktionalität auf verschiedene Weise erweitern: