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

Anwendbare XR‑Geräte
Dieser Leitfaden hilft Ihnen dabei, Erlebnisse für diese Arten von XR-Geräten zu entwickeln.
AI Glasses

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 primäre Möglichkeiten, einen projizierten Kontext abzurufen, je nachdem, wo Ihr Code ausgeführt wird:

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

Wenn der Code Ihrer App in der Aktivität Ihrer KI-Brille ausgeführt wird, ist der zugehörige Aktivitätskontext bereits ein projizierter Kontext. In diesem Szenario können Anrufe, die im Rahmen dieser Aktivität getätigt werden, bereits auf die Hardware der Brille zugreifen.

Projizierten Kontext abrufen, wenn Ihr Code in der Smartphone-App-Komponente ausgeführt wird

Wenn ein Teil Ihrer App außerhalb der Aktivität für die KI-Brille (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 Methode createProjectedDeviceContext():

// From a phone Activity, get a context for the AI glasses
try {
    val glassesContext = ProjectedContext.createProjectedDeviceContext(this)
    // Now use glassesContext to access glasses' system services
} catch (e: IllegalStateException) {
    // Projected device was not found
}

Gültigkeit prüfen

Nachdem Sie den projizierten Kontext erstellt haben, beobachten Sie ProjectedContext.isProjectedDeviceConnected. Auch wenn diese Methode true zurückgibt, bleibt der projizierte Kontext für das verbundene Gerät gültig und Ihre Smartphone-App-Aktivität oder Ihr Dienst (z. B. 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, gibt ProjectedContext.isProjectedDeviceConnected den Wert false zurück. Ihre App sollte auf diese Änderung reagieren und alle Systemdienste (z. B. CameraManager) oder Ressourcen bereinigen, die von Ihrer App mit diesem projizierten Kontext erstellt wurden.

Bei erneuter Verbindung neu initialisieren

Wenn die KI-Brille die Verbindung wiederherstellt, 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 die Profile für A2DP (Advanced Audio Distribution Profile) werden unterstützt. Mit diesem Ansatz kann jede Android-App, die Audioeingabe oder ‑ausgabe unterstützt, auf einer Brille verwendet werden, auch wenn sie nicht speziell für die Unterstützung von Brillen entwickelt wurde. In einigen Fällen kann die Verwendung von Bluetooth für den Anwendungsfall Ihrer App besser geeignet sein 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 Berechtigung RECORD_AUDIO vom Smartphone und nicht von der Brille gesteuert.

Bild mit der Kamera der KI-Brille aufnehmen

Wenn Sie mit der Kamera der KI-Brille ein Bild aufnehmen möchten, richten Sie den use case ImageCapture von CameraX ein und binden Sie ihn mit dem richtigen Kontext für Ihre App an die Kamera der Brille:

private fun startCamera() {
    // Get the CameraProvider using the projected context.

    val cameraProviderFuture = ProcessCameraProvider.getInstance(
        ProjectedContext.createProjectedDeviceContext(this)
    )

    cameraProviderFuture.addListener({
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Select the camera. When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    
        // Check for the presence of a camera before initializing the ImageCapture use case.
       if (!cameraProvider.hasCamera(cameraSelector)) {
            Log.w(TAG, "The selected camera is not available.")
            return@addListener
        }

        // Get supported streaming resolutions.
        val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
        val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
        val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)

        // 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()

        // 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, 30)
        val captureRequestOptions = CaptureRequestOptions.Builder()
                .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,fpsRange)
                .build()

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

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

            // 4. Bind use cases to camera
            cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageCapture)

        } catch(exc: Exception) {
            // This catches exceptions like IllegalStateException if use case binding fails
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

Wichtige Punkte zum Code

  • Ruft eine Instanz von ProcessCameraProvider mit dem Kontext des Geräts mit der Projektionsfläche ab.
  • Im Rahmen des projizierten Kontexts entspricht die primäre, nach außen gerichtete Kamera der KI-Brille der DEFAULT_BACK_CAMERA, wenn eine Kamera ausgewählt wird.
  • Bei einer Vorabprüfung wird cameraProvider.hasCamera(cameraSelector) verwendet, um zu prüfen, 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. Das kann für erweiterte Prüfungen der unterstützten Auflösungen nützlich sein.
  • Ein benutzerdefinierter ResolutionSelector wird erstellt, um die Auflösung des Ausgabebilds 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 basierend auf dem Status der Aktivität 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 ImageCapture-Klasse von CameraX ein Bild aufnehmen. In der CameraX-Dokumentation finden Sie Informationen zur Verwendung von takePicture() zum Aufnehmen eines Bildes.

Video mit der Kamera der KI-Brille aufnehmen

Wenn Sie mit der Kamera der KI-Brille ein Video statt eines Bildes aufnehmen möchten, ersetzen Sie die ImageCapture-Komponenten durch die entsprechenden VideoCapture-Komponenten und ändern Sie die Logik für die Aufnahme.

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

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

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

Auf die Hardware eines Smartphones über eine KI-Brillenaktivität zugreifen

Eine KI-Brillenaktivität kann auch auf die Hardware des Smartphones (z. B. die Kamera oder das Mikrofon) zugreifen, indem sie createHostDeviceContext(context) verwendet, um den Kontext des Hostgeräts (Smartphone) abzurufen:

// From an AI glasses Activity, get a context for the phone
val phoneContext = ProjectedContext.createHostDeviceContext(this)
// Now use phoneContext to access the phone's hardware

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