Produktneuheiten

Über einzelne Funktionen hinaus: 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 in beeindruckendem HDR aufnehmen, flüssige Bewegungen mit 60 fps erfassen und mit der Vorschau-Stabilisierung butterweiche Aufnahmen erhalten können – 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 es oft ein Glücksspiel, mehrere Funktionen zu aktivieren. Sie können die Unterstützung für einzelne Funktionen prüfen, aber die Kombination von Funktionen kann zu undefiniertem Verhalten oder schlimmer noch zu einer fehlgeschlagenen Kamerasitzung führen. Diese Unsicherheit zwingt Entwickler, konservativ zu sein, was dazu führt, dass Nutzer auf leistungsfähigen Geräten nicht die bestmögliche Erfahrung erhalten.

So unterstützen nur sehr wenige Premium-Geräte HDR- und 60‑FPS-Videos gleichzeitig. Daher wird in den meisten Apps nicht beides gleichzeitig aktiviert, um eine schlechte Nutzererfahrung auf den meisten Smartphones zu vermeiden.

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 vor der Konfiguration der Kamera abfragen, ob eine bestimmte Kombination von Funktionen unterstützt wird. Alternativ können Sie CameraX einfach Ihre Prioritäten mitteilen und die Bibliothek die am besten unterstützte Kombination für Sie aktivieren lassen.

Für CameraX-Neulinge

Bevor wir uns die neue Feature Group API ansehen, wollen wir kurz zusammenfassen, was CameraX ist. CameraX ist eine Jetpack-Supportbibliothek, die die Entwicklung von Kamera-Apps vereinfachen soll. Sie bietet eine einheitliche und benutzerfreundliche API, die auf den meisten Android-Geräten funktioniert und abwärtskompatibel mit Android 6.0 (API-Level 23) ist. Wenn Sie CameraX noch nicht kennen, empfehlen wir Ihnen, sich die offizielle Dokumentation anzusehen und das Codelab auszuprobieren.

Was Sie mit der Feature Group API entwickeln können

Sie müssen nicht mehr auf bestimmte Funktionskombinationen setzen, sondern können auf kompatibler Hardware (z.B. Pixel 10 Pro) die bestmöglichen Kamerafunktionen wie gleichzeitige HDR- und 60‑FPS-Videos anbieten und gleichzeitig Fehler auf Geräten vermeiden, die die Kombination nicht unterstützen.

unnamed.png

Pixel 10 Pro mit HDR und 60 fps gleichzeitig

unnamed (1).png

Auf älteren Geräten, auf denen 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:Einstellungen in Ihrer UI basierend auf der Hardwareunterstützung in Echtzeit intelligent aktivieren oder deaktivieren. 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 „High-Quality“-Modus bereitstellen : 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 ein bestimmtes Gerät. So wird ein optimales Ergebnis erzielt, ohne dass eine komplexe, gerätespezifische Logik erforderlich ist.
  • Kamera-Sitzungsfehler vermeiden:Wenn Sie die Unterstützung im Voraus überprüfen, wird verhindert, dass die Kamera versucht, eine nicht unterstützte Kombination zu konfigurieren. So wird eine häufige Ursache für Abstürze vermieden und eine reibungslose Nutzererfahrung ermöglicht.

Funktionsweise: Die Kernkomponenten

Die neue API basiert auf wichtigen Ergänzungen von 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 Gruppe von Funktionen mit der hohen Zuverlässigkeit gruppiert werden, die diese API bietet. Wir arbeiten aktiv daran, diese Liste zu erweitern und in zukünftigen Releases Unterstützung für weitere Funktionen einzuführen.
     
  2. Neue SessionConfig-Parameter:Diese Klasse, die zum Starten einer Kamerasitzung verwendet wird, akzeptiert jetzt zwei neue Parameter:
    • requiredFeatureGroup: Verwenden Sie diese Option für Funktionen, die unbedingt unterstützt werden müssen, damit die Konfiguration erfolgreich ist. Das ist ideal für Funktionen, die ein Nutzer explizit aktiviert, z. B. durch Umlegen eines „HDR“-Schalters. Um eine deterministische und konsistente Nutzererfahrung zu gewährleisten, wird beim Aufruf von bindToLifecycle eine IllegalArgumentException ausgegeben, wenn die angeforderte Kombination nicht unterstützt wird. Eine Funktionsanfrage wird also nicht einfach ignoriert. Mit der CameraInfo#isFeatureGroupSupported API (Details unten) sollte dieses Ergebnis vorab abgefragt werden.
    • preferredFeatureGroup: Verwenden Sie diese Option für Funktionen, die wünschenswert, aber optional sind, z. B. wenn Sie einen Standardmodus „Hohe Qualität“ implementieren möchten. Sie geben eine Liste der gewünschten Funktionen an, die nach Priorität sortiert ist. CameraX aktiviert dann automatisch die Kombination mit der höchsten Priorität, die vom Gerät unterstützt wird.
  3. CameraInfo#isFeatureGroupSupported(): Dies ist die zentrale Abfragemethode, um explizit zu prüfen, ob eine Funktionsgruppe unterstützt wird. Sie eignet sich gut, um Nutzern in der Benutzeroberfläche Ihrer App nur unterstützte Funktionsoptionen anzubieten. Sie übergeben einen SessionConfig und erhalten einen booleschen Wert zurück, der angibt, ob die Kombination unterstützt wird. Wenn Sie ein SessionConfig mit erforderlichen Funktionen binden möchten, sollten Sie zuerst diese API verwenden, um sicherzustellen, dass es unterstützt wird. 

Implementierung in der Praxis

Sehen wir uns an, wie Sie diese Komponenten nutzen können, um die Kamerafunktionen zu verbessern.

Szenario 1: Modus „Hohe Qualität“ (Best Effort)

Wenn Sie die bestmöglichen Funktionen standardmäßig 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, aber nicht mit der Vorschau-Stabilisierung verarbeiten kann, aktiviert CameraX die ersten beiden und verwirft die dritte. So erhalten Sie die bestmögliche Leistung, 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)

        }

    }

)

Bei diesem Code-Snippet versucht CameraX, Funktionskombinationen in der folgenden Prioritätsreihenfolge zu aktivieren. Die erste Kombination, die das Gerät vollständig unterstützt, wird ausgewählt:

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

Szenario 2: Reaktive Benutzeroberfläche erstellen

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

  /**

 * 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 sich unsere interne Test-App ansehen. Sie bietet eine vollständige Implementierung der oben beschriebenen Szenarien „Best Effort“ und „Reaktive Benutzeroberfläche“.

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 den Einsatz in der Produktion optimiert.

Jetzt starten

Die Feature Group API beseitigt die Unklarheiten bei der Verwendung erweiterter Kamerafunktionen. Da Sie auf diese Weise deterministisch abfragen können, ob eine Funktion unterstützt wird, können Sie leistungsstärkere und zuverlässigere Kamera-Apps entwickeln.

Die API ist in CameraX 1.5 als experimentell verfügbar und soll im Release 1.6 vollständig stabil werden. Weitere Unterstützung und Verbesserungen sind geplant.

Weitere Informationen finden Sie in der offiziellen Dokumentation. Wir sind gespannt auf eure Kreationen und freuen uns auf euer Feedback. Wir würden uns freuen, wenn du uns deine Meinung über die folgenden Kanäle mitteilst und uns auf Probleme aufmerksam machst:

Verfasst von:

Weiterlesen