Projizierten Kontext verwenden, um auf die Hardware von KI-Brillen zuzugreifen

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‑Brillen

Nachdem Sie die erforderlichen Berechtigungen angefordert und erhalten haben, kann Ihre App auf die Hardware der KI‑Brille zugreifen. Der Schlüssel für den Zugriff auf die Hardware der Brille (anstelle der Hardware des Smartphones) ist die Verwendung eines projizierten Kontexts.

Es gibt zwei Möglichkeiten, einen projizierten Kontext zu erhalten, je nachdem, wo Ihr Code ausgeführt wird:

Projizierten Kontext abrufen, wenn Ihr Code in einer KI‑Brillenaktivität ausgeführt wird

Wenn der Code Ihrer App in einer KI‑Brillenaktivität ausgeführt wird, ist der Aktivitätskontext bereits ein projizierter Kontext. In diesem Fall können Aufrufe innerhalb dieser Aktivität bereits auf die Hardware der Brille zugreifen.

Projizierten Kontext für Code abrufen, der in einer Smartphone-App-Komponente ausgeführt wird

Wenn ein Teil Ihrer App außerhalb der KI‑Brillenaktivität (z. B. eine Smartphone-Aktivität oder ein Dienst) auf die Hardware der Brille zugreifen muss, muss er explizit einen projizierten Kontext abrufen. Verwenden Sie dazu die createProjectedDeviceContext() Methode:

@OptIn(ExperimentalProjectedApi::class)
private fun getGlassesContext(context: Context): Context? {
    return try {
        // From a phone Activity or Service, get a context for the AI glasses.
        ProjectedContext.createProjectedDeviceContext(context)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Failed to create projected device context", e)
        null
    }
}

Gültigkeit prüfen

Umschließen Sie den createProjectedDeviceContext Aufruf mit dem ProjectedContext.isProjectedDeviceConnected. Solange diese Methode true zurückgibt, bleibt der projizierte Kontext für das verbundene Gerät gültig und die Smartphone-App-Aktivität oder der Dienst (z. B. ein CameraManager) kann auf die Hardware der KI‑Brille zugreifen.

Beim Trennen der Verbindung bereinigen

Der projizierte Kontext ist an den Lebenszyklus des verbundenen Geräts gebunden und wird daher zerstört, wenn die Verbindung zum Gerät getrennt wird. Wenn die Verbindung zum Gerät getrennt wird, ProjectedContext.isProjectedDeviceConnected gibt false zurück. Ihre App sollte auf diese Änderung achten und alle Systemdienste (z. B. einen CameraManager) oder Ressourcen bereinigen, die von Ihrer App mit diesem projizierten Kontext erstellt wurden.

Bei erneuter Verbindung neu initialisieren

Wenn die Verbindung zum KI‑Brillengerät wiederhergestellt wird, kann Ihre App mit createProjectedDeviceContext() eine weitere projizierte Kontextinstanz abrufen und dann alle Systemdienste oder Ressourcen mit dem neuen projizierten Kontext neu initialisieren.

Über Bluetooth auf Audio zugreifen

Derzeit werden KI‑Brillen als Standard-Bluetooth-Audiogerät mit Ihrem Smartphone verbunden. Sowohl das Headset- als auch das A2DP-Profil (Advanced Audio Distribution Profile) e werden unterstützt. Mit diesem Ansatz kann jede Android-App, die Audioeingabe oder ‑ausgabe unterstützt, auf Brillen verwendet werden, auch wenn sie nicht speziell für die Unterstützung von Brillen entwickelt wurde. In einigen Fällen ist die Verwendung von Bluetooth möglicherweise besser für den Anwendungsfall Ihrer App geeignet als der Zugriff auf die Hardware der Brille über einen projizierten Kontext.

Wie bei jedem Standard-Bluetooth-Audiogerät wird die Berechtigung zum Erteilen der RECORD_AUDIO Berechtigung vom Smartphone und nicht von der Brille gesteuert.

Bild mit der Kamera der KI‑Brille aufnehmen

Wenn Sie ein Bild mit der Kamera der KI‑Brille aufnehmen möchten, richten Sie den CameraX-Anwendungsfall ImageCapture ein und binden Sie ihn an die Kamera der Brille. Verwenden Sie dazu den richtigen Kontext für Ihre App:

private fun startCameraOnGlasses(activity: ComponentActivity) {
    // 1. Get the CameraProvider using the projected context.
    // When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
    val projectedContext = try {
        ProjectedContext.createProjectedDeviceContext(activity)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "AI Glasses context could not be created", e)
        return
    }

    val cameraProviderFuture = ProcessCameraProvider.getInstance(projectedContext)

    cameraProviderFuture.addListener({
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        // 2. Check for the presence of a camera.
        if (!cameraProvider.hasCamera(cameraSelector)) {
            Log.w(TAG, "The selected camera is not available.")
            return@addListener
        }

        // 3. Query supported streaming resolutions using Camera2 Interop.
        val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
        val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
        val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(
            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
        )

        // 4. Define the resolution strategy.
        val targetResolution = Size(1920, 1080)
        val resolutionStrategy = ResolutionStrategy(
            targetResolution,
            ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER
        )
        val resolutionSelector = ResolutionSelector.Builder()
            .setResolutionStrategy(resolutionStrategy)
            .build()

        // 5. If you have other continuous use cases bound, such as Preview or ImageAnalysis,
        // you can use  Camera2 Interop's CaptureRequestOptions to set the FPS
        val fpsRange = Range(30, 60)
        val captureRequestOptions = CaptureRequestOptions.Builder()
            .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange)
            .build()

        // 6. Initialize the ImageCapture use case with options.
        val imageCapture = ImageCapture.Builder()
            // Optional: Configure resolution, format, etc.
            .setResolutionSelector(resolutionSelector)
            .build()

        try {
            // Unbind use cases before rebinding.
            cameraProvider.unbindAll()

            // Bind use cases to camera using the Activity as the LifecycleOwner.
            cameraProvider.bindToLifecycle(
                activity,
                cameraSelector,
                imageCapture
            )
        } catch (exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }
    }, ContextCompat.getMainExecutor(activity))
}

Wichtige Punkte zum Code

  • Ruft eine Instanz von ProcessCameraProvider mit dem projizierten Gerätekontext ab.
  • Im Bereich des projizierten Kontexts wird die primäre, nach außen gerichtete Kamera der KI‑Brille beim Auswählen einer Kamera DEFAULT_BACK_CAMERA zugeordnet.
  • Bei einer Vorabprüfung wird mit cameraProvider.hasCamera(cameraSelector) geprüft, ob die ausgewählte Kamera auf dem Gerät verfügbar ist, bevor fortgefahren wird.
  • Verwendet Camera2 Interop mit Camera2CameraInfo, um die zugrunde liegende CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP zu lesen. Dies kann für erweiterte Prüfungen der unterstützten Auflösungen nützlich sein.
  • Ein benutzerdefiniertes ResolutionSelector wird erstellt, um die Ausgabe bildauflösung für ImageCapture genau zu steuern.
  • Erstellt einen ImageCapture-Anwendungsfall, der mit einem benutzerdefinierten ResolutionSelector konfiguriert ist.
  • Bindet den ImageCapture-Anwendungsfall an den Lebenszyklus der Aktivität. Dadurch wird das Öffnen und Schließen der Kamera automatisch anhand des Aktivitätsstatus verwaltet (z. B. wird die Kamera angehalten, wenn die Aktivität pausiert wird).

Nachdem die Kamera der KI‑Brille eingerichtet wurde, können Sie mit der Klasse ImageCapture von CameraX ein Bild aufnehmen. Informationen zur Verwendung von takePicture() zum Aufnehmen eines Bilds finden Sie in der CameraX-Dokumentation.

Video mit der Kamera der KI‑Brille aufnehmen

Wenn Sie mit der Kamera der KI‑Brille ein Video anstelle eines Bilds aufnehmen möchten, ersetzen Sie die ImageCapture Komponenten durch die entsprechenden VideoCapture Komponenten und ändern Sie die Logik für die Aufnahmeausführung.

Die wichtigsten Änderungen sind die Verwendung eines anderen Anwendungsfalls, das Erstellen einer anderen Ausgabedatei und das Starten der Aufnahme mit der entsprechenden Methode zur Videoaufzeichnung. Weitere Informationen zur VideoCapture API und ihrer Verwendung finden Sie in der Dokumentation zur Videoaufnahme von CameraX.

In der folgenden Tabelle sind die empfohlene Auflösung und Framerate je nach Anwendungsfall Ihrer App aufgeführt:

Anwendungsfall Auflösung Frame rate
Videokommunikation 1280 × 720 15 FPS
Computer Vision 640 × 480 10 FPS
KI-Videostreaming 640 × 480 1 FPS

Von einer KI‑Brillenaktivität aus auf die Hardware eines Smartphones zugreifen

Eine KI‑Brillenaktivität kann auch auf die Hardware des Smartphones (z. B. die Kamera oder das Mikrofon) zugreifen, indem sie mit createHostDeviceContext(context) den Kontext des Host geräts (Smartphone) abruft:

@OptIn(ExperimentalProjectedApi::class)
private fun getPhoneContext(activity: ComponentActivity): Context? {
    return try {
        // From an AI glasses Activity, get a context for the phone.
        ProjectedContext.createHostDeviceContext(activity)
    } catch (e: IllegalStateException) {
        Log.e(TAG, "Failed to create host device context", e)
        null
    }
}

Wenn Sie in einer Hybrid-App (einer App, die sowohl mobile als auch KI‑Brillenerlebnisse enthält) auf Hardware oder Ressourcen zugreifen, die spezifisch für das Hostgerät (Smartphone) sind, müssen Sie explizit den richtigen Kontext auswählen, damit Ihre App auf die richtige Hardware zugreifen kann: