Notizie sui prodotti

Oltre le singole funzionalità: garantire le combinazioni di funzionalità con CameraX 1.5

Lettura di 6 minuti
Tahsin Masrur
Software Engineer

Le moderne app per la fotocamera sono caratterizzate da funzionalità potenti e sovrapposte. Gli utenti si aspettano di registrare video con HDR straordinario, acquisire movimenti fluidi a 60 FPS e ottenere filmati fluidi con la stabilizzazione dell'anteprima, spesso contemporaneamente.

Come sviluppatori, sappiamo che la realtà è più complicata. Come puoi garantire che un dispositivo specifico supporti effettivamente una determinata combinazione? Finora, l'attivazione di più funzionalità era spesso un azzardo. Potevi verificare il supporto delle singole funzionalità, ma la loro combinazione poteva portare a un comportamento indefinito o, peggio, a una sessione della fotocamera non riuscita. Questa incertezza costringe gli sviluppatori a essere conservativi, il che impedisce agli utenti di dispositivi idonei di accedere alla migliore esperienza possibile.

Ad esempio, pochissimi dispositivi premium supportano in modo affidabile i video HDR e a 60 FPS contemporaneamente. Di conseguenza, la maggior parte delle app evita di abilitare entrambe le funzionalità contemporaneamente per evitare una scarsa esperienza utente sulla maggior parte degli smartphone.

Per risolvere questo problema, stiamo introducendo Gruppo di funzionalità in CameraX , una nuova API progettata per eliminare questa incertezza. Ora puoi verificare se una combinazione specifica di funzionalità è supportata prima di configurare la fotocamera oppure indicare semplicemente a CameraX le tue priorità e lasciare che attivi la combinazione più supportata.

Per chi non conosce CameraX

Prima di approfondire la nuova API Gruppo di funzionalità, riepiloghiamo rapidamente cos'è CameraX. CameraX è una libreria di supporto Jetpack, creata per semplificare lo sviluppo di app per la fotocamera. Fornisce una superficie API coerente e facile da usare che funziona sulla maggior parte dei dispositivi Android, con compatibilità con le versioni precedenti fino ad Android 6.0 (livello API 23). Se non hai familiarità con CameraX, ti consigliamo di consultare la documentazione ufficiale e di provare il codelab per iniziare.

Cosa puoi creare con l'API Gruppo di funzionalità

Non devi più rischiare con le combinazioni di funzionalità e puoi offrire con sicurezza le migliori esperienze possibili con la fotocamera, ad esempio video HDR e a 60 FPS simultanei su hardware idoneo (ad es. Pixel 10 Pro), evitando con eleganza gli errori sui dispositivi che non supportano la combinazione.

unnamed.png

Pixel 10 Pro che abilita contemporaneamente HDR e 60 FPS

unnamed (1).png

Su un dispositivo meno recente in cui HDR e 60 FPS non possono essere eseguiti contemporaneamente, viene abilitato solo l'HDR, mentre l'opzione 60 FPS è disattivata.

Con l'API Gruppo di funzionalità puoi:

  • Creare UI dinamiche e più intelligenti: abilita o disabilita in modo intelligente le impostazioni nell'UI in base al supporto hardware in tempo reale. Ad esempio, se un utente abilita l'HDR, puoi disattivare immediatamente l'opzione 60 FPS se la combinazione non è supportata sul dispositivo. 
unsupported-features-disabled.gif
  • Offrire una modalità "Alta qualità" affidabile: configura la fotocamera con un elenco prioritario delle funzionalità desiderate. CameraX trova e abilita automaticamente la combinazione più supportata per un determinato dispositivo, garantendo un risultato ottimale senza una logica complessa e specifica per il dispositivo.
  • Evitare errori della sessione della fotocamera: verificando il supporto in anticipo, impedisci alla fotocamera di tentare di configurare una combinazione non supportata, eliminando una fonte comune di arresti anomali e offrendo un'esperienza utente fluida.

Come funziona: i componenti principali

La nuova API è incentrata su aggiunte chiave a SessionConfigCameraInfo.

  1. GroupableFeature: questa API introduce un insieme di funzionalità raggruppabili predefinite, come HDR_HLG10, FPS_60, PREVIEW_STABILIZATION e IMAGE_ULTRA_HDR. A causa di limitazioni computazionali, solo un insieme specifico di funzionalità può essere raggruppato con l'elevato grado di affidabilità fornito da questa API. Stiamo lavorando attivamente per espandere questo elenco e introdurremo il supporto per altre funzionalità nelle release future.
  2. Nuovi parametri SessionConfig: questa classe, utilizzata per avviare una sessione della fotocamera, ora accetta due nuovi parametri:
    • requiredFeatureGroup: utilizza questo parametro per le funzionalità che devono essere supportate per la riuscita della configurazione. È ideale per le funzionalità che un utente abilita esplicitamente, ad esempio attivando un'opzione "HDR". Per garantire un'esperienza deterministica e coerente, la chiamata bindToLifecycle genererà un'eccezione IllegalArgumentException se la combinazione richiesta non è supportata, anziché ignorare silenziosamente una richiesta di funzionalità. L'API CameraInfo#isFeatureGroupSupported (dettagli di seguito) deve essere utilizzata per eseguire una query su questo risultato in anticipo.
    • preferredFeatureGroup: utilizza questo parametro per le funzionalità desiderabili ma facoltative, ad esempio quando vuoi implementare una modalità "Alta qualità" predefinita. Fornisci un elenco delle funzionalità desiderate ordinate in base alle tue priorità e CameraX abilita automaticamente la combinazione con la priorità più alta supportata dal dispositivo.
  3. CameraInfo#isFeatureGroupSupported(): questo è il metodo di query principale per verificare esplicitamente se un gruppo di funzionalità è supportato. È ideale per fornire agli utenti solo le opzioni di funzionalità supportate nell'UI dell'app. Passa un SessionConfig e restituisce un valore booleano che indica se la combinazione è supportata. Se intendi associare un SessionConfig con le funzionalità richieste, devi utilizzare prima questa API per assicurarti che sia supportata. 

Implementazione pratica

Vediamo come utilizzare questi componenti per creare un'esperienza migliore con la fotocamera.

Scenario 1: modalità "Alta qualità" con il massimo impegno

Se vuoi abilitare le migliori funzionalità possibili per impostazione predefinita, puoi fornire un elenco prioritario a preferredFeatureGroup. In questo esempio, indichiamo a CameraX di dare la priorità all'HDR, poi a 60 FPS e infine alla stabilizzazione dell'anteprima. CameraX gestisce la complessità della verifica di tutte le combinazioni possibili e della scelta della migliore supportata dal dispositivo.

Ad esempio, se un dispositivo è in grado di gestire HDR e 60 FPS insieme, ma non con la stabilizzazione dell'anteprima, CameraX abiliterà le prime due e ignorerà la terza. In questo modo, ottieni la migliore esperienza possibile senza scrivere controlli complessi e specifici per il dispositivo.

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)

        }

    }

)

Per questo snippet di codice, CameraX tenterà di abilitare le combinazioni di funzionalità nel seguente ordine di priorità, selezionando la prima completamente supportata dal dispositivo:

  1. HDR + 60 FPS + stabilizzazione dell'anteprima
  2. HDR + 60 FPS
  3. HDR + stabilizzazione dell'anteprima
  4. HDR
  5. 60 FPS + stabilizzazione dell'anteprima
  6. 60 FPS
  7. Stabilizzazione dell'anteprima
  8. Nessuna delle funzionalità sopra indicate

Scenario 2: creazione di un'UI reattiva

Per creare un'UI che risponda alle selezioni dell'utente e impedisca agli utenti di selezionare una combinazione di funzionalità non supportata, puoi eseguire una query direttamente per il supporto. La funzione riportata di seguito controlla quali funzionalità sono incompatibili con le selezioni correnti dell'utente, consentendoti di disattivare gli elementi dell'UI corrispondenti.

/**

 * 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

}

Puoi quindi collegare questa logica al tuo ViewModel o al controller dell'UI per reagire all'input dell'utente e riassociare la fotocamera con una configurazione garantita.

// 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,

        )

    )

}

Per vedere questi concetti in un'applicazione funzionante, puoi esplorare la nostra app di test interna. Fornisce un'implementazione completa degli scenari "con il massimo impegno" e "UI reattiva" descritti sopra.

Nota: questa è un'applicazione di test e non un esempio supportato ufficialmente. Sebbene sia un ottimo riferimento per l'API Gruppo di funzionalità, non è stata ottimizzata per l'utilizzo in produzione.

Inizia subito

L'API Gruppo di funzionalità elimina l'ambiguità dell'utilizzo delle funzionalità avanzate della fotocamera. Fornendo un modo deterministico per eseguire query sul supporto delle funzionalità, puoi creare app per la fotocamera più potenti e affidabili con sicurezza.

L'API è disponibile in versione sperimentale in CameraX 1.5 e diventerà completamente stabile nella release 1.6, con ulteriori supporto e miglioramenti in arrivo.

Per saperne di più, consulta la documentazione ufficiale. Non vediamo l'ora di scoprire cosa creerai e attendiamo con ansia i tuoi feedback. Condividi le tue opinioni e segnala eventuali problemi tramite i seguenti canali:

Continua a leggere