Produktneuheiten

Mehr als einzelne Funktionen: Funktionskombinationen mit CameraX 1.5 garantieren

Lesezeit: 6 Minuten
Tahsin Masrur
Softwaretechniker

Moderne Kamera-Apps zeichnen sich durch leistungsstarke, sich überschneidende Funktionen aus. Nutzer erwarten, dass sie Videos mit beeindruckendem HDR aufnehmen, flüssige Bewegungen mit 60 FPS erfassen und mit der Vorschau-Stabilisierung butterweiche Aufnahmen erhalten – oft alles gleichzeitig.

Als Entwickler wissen wir, dass die Realität komplizierter ist. Wie können Sie garantieren, dass ein bestimmtes Gerät eine bestimmte Kombination unterstützt? Bisher war das Aktivieren mehrerer Funktionen oft ein Glücksspiel. Sie konnten zwar prüfen, ob die einzelnen Funktionen unterstützt werden, aber die Kombination konnte zu undefiniertem Verhalten oder schlimmer noch zu einer fehlgeschlagenen Kamerasitzung führen. Diese Unsicherheit zwingt Entwickler, konservativ zu sein, was verhindert, dass Nutzer auf leistungsstarken Geräten die bestmögliche Erfahrung erhalten.

Beispielsweise unterstützen nur sehr wenige Premiumgeräte HDR und 60 FPS-Video gleichzeitig zuverlässig. Daher vermeiden die meisten Apps, beides gleichzeitig zu aktivieren, um eine schlechte Nutzererfahrung auf den meisten Smartphones zu verhindern.

Um dieses Problem zu beheben, führen wir Feature Group in CameraX ein – eine neue API, die dieses Rätselraten überflüssig macht. Sie können jetzt abfragen, ob eine bestimmte Kombination von Funktionen unterstützt wird, bevor Sie die Kamera konfigurieren. Alternativ können Sie CameraX einfach Ihre Prioritäten mitteilen und die am besten unterstützte Kombination für Sie aktivieren lassen.

Für CameraX-Neulinge

Bevor wir uns mit der neuen Feature Group API befassen, fassen wir kurz zusammen, was CameraX ist. CameraX ist eine Jetpack-Supportbibliothek, die Ihnen die Entwicklung von Kamera-Apps erleichtern soll. Sie bietet eine konsistente und benutzerfreundliche API-Oberfläche, die auf den meisten Android-Geräten funktioniert und abwärtskompatibel zu Android 6.0 (API-Level 23) ist. Wenn Sie CameraX noch nicht kennen, empfehlen wir Ihnen, die offizielle Dokumentation zu lesen und das Codelab auszuprobieren, um loszulegen.

Was Sie mit der Feature Group API entwickeln können

Sie müssen nicht mehr auf Funktionskombinationen setzen und können die bestmöglichen Kamerafunktionen anbieten – z. B. gleichzeitiges HDR- und 60-FPS-Video auf leistungsstarker Hardware (z. B. einem Pixel 10 Pro). Gleichzeitig können Sie Fehler auf Geräten vermeiden, die die Kombination nicht unterstützen.

unnamed.png

Pixel 10 Pro, auf dem sowohl HDR als auch 60 FPS gleichzeitig aktiviert sind

unnamed (1).png

Auf einem älteren Gerät, auf dem HDR und 60 FPS nicht gleichzeitig ausgeführt werden können, ist nur HDR aktiviert, während die Option für 60 FPS deaktiviert ist.

Mit der Feature Group API haben Sie folgende Möglichkeiten:

  • Intelligentere, dynamische UIs erstellen:Aktivieren oder deaktivieren Sie Einstellungen in Ihrer UI intelligent auf Grundlage der Hardwareunterstützung in Echtzeit. Wenn ein Nutzer beispielsweise HDR aktiviert, können Sie die Option für 60 FPS sofort ausgrauen und deaktivieren, wenn die Kombination auf diesem Gerät nicht unterstützt wird. 
unsupported-features-disabled.gif
  • Zuverlässigen Modus für hohe Qualität anbieten : Konfigurieren Sie die Kamera mit einer priorisierten Liste der gewünschten Funktionen. CameraX findet und aktiviert automatisch die am besten unterstützte Kombination für jedes Gerät. So erhalten Sie ein hervorragendes Ergebnis ohne komplexe, gerätespezifische Logik.
  • Fehler bei Kamerasitzungen vermeiden:Wenn Sie die Unterstützung im Voraus prüfen, verhindern Sie, dass die Kamera versucht, eine nicht unterstützte Kombination zu konfigurieren. So vermeiden Sie eine häufige Ursache für Abstürze und bieten eine reibungslose Nutzererfahrung.

Funktionsweise: Die Kernkomponenten

Die neue API basiert auf wichtigen Ergänzungen zu SessionConfig und CameraInfo.

  1. GroupableFeature: Diese API führt eine Reihe vordefinierter gruppierbarer Funktionen ein, z. B. HDR_HLG10, FPS_60, PREVIEW_STABILIZATION und IMAGE_ULTRA_HDR. Aufgrund von Rechenbeschränkungen kann nur eine bestimmte Anzahl von Funktionen mit der hohen Zuverlässigkeit gruppiert werden, die diese API bietet. Wir arbeiten aktiv daran, diese Liste zu erweitern, und werden in zukünftigen Versionen Unterstützung für weitere Funktionen einführen.
     
  2. Neue SessionConfig Parameter: Diese Klasse, die zum Starten einer Kamerasitzung verwendet wird, akzeptiert jetzt zwei neue Parameter:
    • requiredFeatureGroup: Verwenden Sie diesen Parameter für Funktionen, die unterstützt werden müssen , damit die Konfiguration erfolgreich ist. Das ist ideal für Funktionen, die ein Nutzer explizit aktiviert, z. B. durch Aktivieren einer HDR-Option. Um eine deterministische und konsistente Erfahrung zu gewährleisten, löst der Aufruf bindToLifecycle eine IllegalArgumentException aus, wenn die angeforderte Kombination nicht unterstützt wird, anstatt eine Feature Request einfach zu ignorieren. Die API CameraInfo#isFeatureGroupSupported (Details unten) sollte verwendet werden, um dieses Ergebnis im Voraus abzufragen.
    • preferredFeatureGroup: Verwenden Sie diesen Parameter für Funktionen, die wünschenswert, aber optional sind, z. B. wenn Sie einen Standardmodus für hohe Qualität implementieren möchten. Sie geben eine Liste der gewünschten Funktionen an, sortiert nach Ihren Prioritäten. CameraX aktiviert automatisch die Kombination mit der höchsten Priorität, die vom Gerät unterstützt wird.
  3. CameraInfo#isFeatureGroupSupported(): Dies ist die wichtigste Abfragemethode, um explizit zu prüfen, ob eine Funktionsgruppe unterstützt wird. Sie eignet sich gut, um Nutzern in der UI Ihrer App nur unterstützte Funktionsoptionen anzubieten. Sie übergeben eine SessionConfig und die Methode gibt einen booleschen Wert zurück, der angibt, ob die Kombination unterstützt wird. Wenn Sie eine SessionConfig mit erforderlichen Funktionen binden möchten, sollten Sie zuerst diese API verwenden, um zu prüfen, ob sie unterstützt wird. 

Implementierung in der Praxis

Sehen wir uns an, wie Sie diese Komponenten verwenden können, um eine bessere Kamerafunktion zu entwickeln.

Szenario 1: Modus für hohe Qualität nach dem Best-Effort-Prinzip

Wenn Sie standardmäßig die bestmöglichen Funktionen aktivieren möchten, können Sie eine priorisierte Liste für preferredFeatureGroup angeben. In diesem Beispiel weisen wir CameraX an, HDR, dann 60 FPS und schließlich die Vorschau-Stabilisierung zu priorisieren. CameraX übernimmt die Komplexität, alle möglichen Kombinationen zu prüfen und die beste auszuwählen, die vom Gerät unterstützt wird.

Wenn ein Gerät beispielsweise HDR und 60 fps gleichzeitig verarbeiten kann, aber nicht mit der Vorschau-Stabilisierung, aktiviert CameraX die ersten beiden und verwirft die dritte. So erhalten Sie die bestmögliche Erfahrung, ohne komplexe, gerätespezifische Prüfungen schreiben zu müssen.

cameraProvider.bindToLifecycle(

    lifecycleOwner,

    cameraSelector,

    SessionConfig(

        useCases = listOf(preview, videoCapture),

        // The order of features in this list determines their priority. 

        // CameraX will enable the best-supported combination based on these

        // priorities: HDR_HLG10 > FPS_60 > Preview Stabilization.  

        preferredFeatureGroup =

           listOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION),

    ).apply {

        // (Optional) Get a callback with the enabled features

        // to update your UI. 

        setFeatureSelectionListener { selectedFeatures ->

            updateUiIndicators(selectedFeatures)

        }

    }

)

Für diesen Code-Snippet versucht CameraX, Funktionskombinationen in der folgenden Prioritätsreihenfolge zu aktivieren und wählt die erste aus, die vom Gerät vollständig unterstützt wird:

  1. HDR + 60 FPS + Vorschau-Stabilisierung
  2. HDR + 60 FPS
  3. HDR + Vorschau-Stabilisierung
  4. HDR
  5. 60 FPS + Vorschau-Stabilisierung
  6. 60 FPS
  7. Vorschau-Stabilisierung
  8. Keine der oben genannten Funktionen

Szenario 2: Reaktive UI erstellen

Wenn Sie eine UI erstellen möchten, die auf Nutzerauswahlen reagiert und verhindert, dass Nutzer eine nicht unterstützte Funktionskombination auswählen, können Sie direkt nach der Unterstützung fragen. Die Funktion unten prüft, welche Funktionen mit den aktuellen Auswahlen des Nutzers inkompatibel sind, sodass Sie die entsprechenden UI-Elemente deaktivieren können.

/**

 * Returns a list of features that are NOT supported in combination

 * with the currently selected features.

 */

fun getUnsupportedFeatures(

    currentFeatures: Set<GroupableFeature>

): Set<GroupableFeature> {

    val unsupportedFeatures = mutableSetOf<GroupableFeature>()

    val appFeatureOptions = setOf(HDR_HLG10, FPS_60, PREVIEW_STABILIZATION)


    // Iterate over every available feature option in your app. 

    appFeatureOptions.forEach { featureOption ->

        // Skip features the user has already selected. 

        if (currentFeatures.contains(featureOption)) return@forEach


        // Check if adding this new feature is supported. 

        val isSupported = cameraInfo.isFeatureGroupSupported(

            SessionConfig(

                useCases = useCases,

                // Check the new feature on top of existing ones.

                requiredFeatureGroup = currentFeatures + featureOption

            )

        )


        if (!isSupported) {

            unsupportedFeatures.add(featureOption)

        }

    }


    return unsupportedFeatures

}

Sie können diese Logik dann in Ihr ViewModel oder Ihren UI-Controller einbinden, um auf Nutzereingaben zu reagieren und die Kamera mit einer garantiert funktionierenden Konfiguration neu zu binden.

// Invoked when user turns some feature on/off.

fun onFeatureChange(currentFeatures: Set<GroupableFeature>) {

    // Identify features that are unsupported with the current selection.

    val unsupportedFeatures = getUnsupportedFeatures(currentFeatures)



    // Update app UI so that users can't enable them.

    updateDisabledFeatures(unsupportedFeatures)



    // Since the UI now only allows selecting supported feature combinations, 

    // `currentFeatures` is always valid. This allows setting

    // `requiredFeatureGroup` directly, without needing to re-check for

    // support or set a feature selection listener.  

    cameraProvider.bindToLifecycle(

        lifecycleOwner,

        cameraSelector,

        SessionConfig(

            useCases = listOf(preview, videoCapture),

            requiredFeatureGroup = currentFeatures,

        )

    )

}

Wenn Sie diese Konzepte in einer funktionierenden Anwendung sehen möchten, können Sie unsere interne Test-App ausprobieren. Sie bietet eine vollständige Implementierung der beiden oben beschriebenen Szenarien („Best Effort“ und „Reaktive UI“).

Hinweis: Dies ist eine Testanwendung und kein offiziell unterstütztes Beispiel. Sie ist zwar eine gute Referenz für die Feature Group API, wurde aber nicht für die Produktionsnutzung optimiert.

Jetzt loslegen

Die Feature Group API beseitigt die Unklarheiten bei der Arbeit mit erweiterten Kamerafunktionen. Da Sie auf deterministische Weise nach der Unterstützung von Funktionen fragen können, können Sie leistungsstärkere und zuverlässigere Kamera-Apps entwickeln.

Die API ist in CameraX 1.5 als experimentell verfügbar und soll in der Version 1.6 vollständig stabil werden. Weitere Unterstützung und Verbesserungen sind auf dem Weg.

Weitere Informationen finden Sie in der offiziellen Dokumentation. Wir sind gespannt auf Ihre Kreationen und freuen uns auf Ihr Feedback. Teilen Sie uns Ihre Meinung mit und melden Sie Probleme über die folgenden Kanäle:

Verfasst von:

Weiterlesen