Anteprima fotocamera

Nota: questa pagina fa riferimento al pacchetto Camera2. A meno che la tua app non richieda funzionalità specifiche di basso livello di Camera2, ti consigliamo di utilizzare CameraX. Sia CameraX che Camera2 supportano Android 5.0 (livello API 21) e versioni successive.

Le fotocamere e le anteprime della fotocamera non hanno sempre lo stesso orientamento sui dispositivi Android.

Una fotocamera si trova in una posizione fissa su un dispositivo, indipendentemente dal fatto che si tratti di uno smartphone, un tablet o un computer. Quando l'orientamento del dispositivo cambia, cambia anche l'orientamento della videocamera.

Di conseguenza, le app per fotocamera generalmente presuppongono una relazione fissa tra l'orientamento del dispositivo e le proporzioni dell'anteprima della fotocamera. Quando uno smartphone è in orientamento verticale, si presume che l'anteprima della fotocamera sia più alta che larga. Quando lo smartphone (e la fotocamera) vengono ruotati in modalità Orizzontale, l'anteprima della fotocamera dovrebbe essere più larga che alta.

Tuttavia, queste ipotesi vengono messe in discussione da nuovi fattori di forma, come i dispositivi pieghevoli, e da modalità di visualizzazione come multi-finestra e multi-display. I dispositivi pieghevoli cambiano le dimensioni e le proporzioni del display senza cambiare l'orientamento. La modalità multi-finestra limita le app della fotocamera a una parte dello schermo, ridimensionando l'anteprima della fotocamera indipendentemente dall'orientamento del dispositivo. La modalità multi-display consente l'utilizzo di display secondari che potrebbero non avere lo stesso orientamento del display principale.

Orientamento della fotocamera

La definizione di compatibilità Android specifica che un sensore di immagine della fotocamera "DEVE essere orientato in modo che la dimensione lunga della fotocamera sia allineata alla dimensione lunga dello schermo. In altre parole, quando il dispositivo viene tenuto in orientamento orizzontale, le fotocamere DEVONO acquisire le immagini in orientamento orizzontale. Questo vale indipendentemente dall'orientamento naturale del dispositivo, ovvero si applica sia ai dispositivi con orientamento principale orizzontale sia a quelli con orientamento principale verticale."

La disposizione della fotocamera rispetto allo schermo massimizza l'area di visualizzazione del mirino della fotocamera in un'app della fotocamera. Inoltre, i sensori di immagine in genere generano i dati in proporzioni orizzontali, di cui 4:3 è la più comune.

Smartphone e sensore della fotocamera entrambi con orientamento verticale.
Figura 1. Relazione tipica tra l'orientamento dello smartphone e quello del sensore della fotocamera.

L'orientamento naturale del sensore della fotocamera è orizzontale. Nella figura 1, il sensore della fotocamera anteriore (la fotocamera rivolta nella stessa direzione del display) è ruotato di 270 gradi rispetto allo smartphone per rispettare la definizione di compatibilità Android.

Per esporre la rotazione del sensore alle app, l'API camera2 include una costante SENSOR_ORIENTATION. Per la maggior parte degli smartphone e dei tablet, il dispositivo segnala un'orientamento del sensore di 270 gradi per le fotocamere anteriori e di 90 gradi (punto di vista dal retro del dispositivo) per le fotocamere posteriori, che allinea il bordo lungo del sensore con il bordo lungo del dispositivo. Le fotocamere dei laptop in genere segnalano un'orientamento del sensore di 0 o 180 gradi.

Poiché i sensori di immagine della fotocamera generano i dati (un buffer di immagini) nell'orientamento naturale del sensore (orizzontale), il buffer di immagini deve essere ruotato del numero di gradi specificato da SENSOR_ORIENTATION affinché l'anteprima della fotocamera venga visualizzata in verticale nell'orientamento naturale del dispositivo. Per le fotocamere anteriori, la rotazione è in senso antiorario; per le fotocamere posteriori, in senso orario.

Ad esempio, per la fotocamera anteriore nella figura 1, il buffer di immagini prodotto dal sensore della fotocamera ha il seguente aspetto:

Sensore della fotocamera ruotato in orientamento orizzontale con l'immagine
            laterale, in alto a sinistra.
Figura 2. Buffer di immagini non elaborate da un sensore della fotocamera anteriore nel suo orientamento orizzontale naturale.

L'immagine deve essere ruotata di 270 gradi in senso antiorario in modo che l'orientamento dell'anteprima corrisponda a quello del dispositivo:

Sensore della fotocamera in orientamento verticale con l'immagine dritta.
Figura 3. Buffer di immagini della fotocamera anteriore ruotato di 270 gradi in senso antiorario per corrispondere all'orientamento verticale del dispositivo.

Una fotocamera posteriore produrrebbe un buffer di immagini con lo stesso orientamento del buffer precedente, ma SENSOR_ORIENTATION è di 90 gradi. Di conseguenza, il buffer viene ruotato di 90 gradi in senso orario.

Rotazione del dispositivo

La rotazione del dispositivo è il numero di gradi di rotazione di un dispositivo rispetto al suo orientamento naturale. Ad esempio, uno smartphone in orientamento orizzontale ha una rotazione del dispositivo di 90 o 270 gradi, a seconda della direzione di rotazione.

Un buffer di immagini del sensore della fotocamera deve essere ruotato dello stesso numero di gradi della rotazione del dispositivo (oltre ai gradi di orientamento del sensore) affinché l'anteprima della fotocamera venga visualizzata in verticale.

Calcolo dell'orientamento

L'orientamento corretto dell'anteprima della fotocamera tiene conto dell'orientamento del sensore e della rotazione del dispositivo.

La rotazione complessiva del buffer di immagini del sensore può essere calcolata utilizzando la seguente formula:

rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

dove sign è 1 per le fotocamere anteriori, -1 per le fotocamere posteriori.

Per le fotocamere anteriori, il buffer delle immagini viene ruotato in senso antiorario (rispetto all'orientamento naturale del sensore). Per le fotocamere posteriori, il buffer di immagini del sensore viene ruotato in senso orario.

L'espressione deviceOrientationDegrees * sign + 360 converte la rotazione del dispositivo da senso antiorario a senso orario per le fotocamere posteriori (ad esempio, convertendo 270 gradi in senso antiorario in 90 gradi in senso orario). L'operazione modulo scala il risultato a meno di 360 gradi (ad esempio, scala 540 gradi di rotazione a 180).

API diverse segnalano la rotazione del dispositivo in modo diverso:

  • Display#getRotation() fornisce la rotazione in senso antiorario del dispositivo (dal punto di vista dell'utente). Questo valore viene inserito nella formula precedente così com'è.
  • OrientationEventListener#onOrientationChanged() restituisce la rotazione in senso orario del dispositivo (dal punto di vista dell'utente). Nega il valore da utilizzare nella formula precedente.

Fotocamere anteriori

Anteprima della fotocamera e sensore entrambi in orientamento orizzontale, sensore
            in posizione verticale.
Figura 4. Anteprima e sensore della fotocamera con lo smartphone ruotato di 90° in orientamento orizzontale.

Ecco il buffer di immagini prodotto dal sensore della fotocamera nella figura 4:

Sensore della videocamera con orientamento orizzontale e immagine verticale.
Figura 5. Buffer di immagini prodotto dal sensore della fotocamera anteriore quando lo smartphone viene ruotato di 90 gradi in senso antiorario.

Il buffer deve essere ruotato di 270 gradi in senso antiorario per adattarsi all'orientamento del sensore (vedi Orientamento della fotocamera sopra):

Sensore della fotocamera ruotato in orientamento verticale con l'immagine di lato,
            in alto a destra.
Figura 6. Buffer di immagini ruotato di 270 gradi in senso antiorario per adattarlo all'orientamento del sensore.

Poi il buffer viene ruotato di altri 90 gradi in senso antiorario per tenere conto della rotazione del dispositivo, ottenendo l'orientamento corretto dell'anteprima della fotocamera nella figura 4:

Sensore della fotocamera ruotato in orizzontale con l'immagine
            in verticale.
Figura 7. Buffer di immagini dopo un'ulteriore rotazione di 90 gradi in senso antiorario per l'orientamento del dispositivo.

Ecco la fotocamera ruotata a destra in orientamento orizzontale:

Anteprima della fotocamera e sensore entrambi in orientamento orizzontale, ma il sensore è capovolto.
Figura 8. Anteprima della fotocamera e sensore con lo smartphone ruotato di 270° (o -90°) in orientamento orizzontale.

Ecco il buffer dell'immagine:

Sensore della fotocamera ruotato in orientamento orizzontale con l'immagine capovolta.
Figura 9. Buffer di immagini prodotto dal sensore della fotocamera anteriore quando lo smartphone viene ruotato di 270 gradi in senso antiorario.

Il buffer deve essere ruotato di 270 gradi in senso antiorario per adattarsi all'orientamento del sensore:

Sensore della fotocamera ruotato in orientamento verticale con l'immagine di lato,
            in alto a sinistra.
Figura 10. Buffer di immagini ruotato di 270 gradi in senso antiorario per adattarlo all'orientamento del sensore.

Il buffer viene quindi ruotato di altri 270 gradi in senso antiorario per tenere conto della rotazione del dispositivo:

Sensore della fotocamera ruotato in orizzontale con l'immagine
            in verticale.
Figura 11. Buffer di immagini dopo un'ulteriore rotazione di 270 gradi in senso antiorario per l'orientamento del dispositivo.

Fotocamere posteriori

Le fotocamere posteriori in genere hanno un orientamento del sensore di 90 gradi (visto dal retro del dispositivo). Quando si orienta l'anteprima della fotocamera, il buffer dell'immagine del sensore viene ruotato in senso orario in base alla rotazione del sensore (anziché in senso antiorario come le fotocamere anteriori), quindi il buffer dell'immagine viene ruotato in senso antiorario in base alla rotazione del dispositivo.

Anteprima della fotocamera e sensore entrambi in orientamento orizzontale, ma il sensore è capovolto.
Figura 12. Smartphone con fotocamera posteriore in orientamento orizzontale (ruotato di 270 o -90 gradi).

Ecco il buffer di immagini del sensore della fotocamera nella figura 12:

Sensore della fotocamera ruotato in orientamento orizzontale con l'immagine capovolta.
Figura 13. Buffer di immagini prodotto dal sensore della fotocamera posteriore quando lo smartphone è in orientamento orizzontale.

Il buffer deve essere ruotato di 90 gradi in senso orario per adattarsi all'orientamento del sensore:

Sensore della fotocamera ruotato in orientamento verticale con l'immagine di lato,
            in alto a sinistra.
Figura 14. Buffer di immagini ruotato di 90 gradi in senso orario per adattarlo all'orientamento del sensore posteriore.

Poi il buffer viene ruotato di 270 gradi in senso antiorario per tenere conto della rotazione del dispositivo:

Sensore della fotocamera ruotato in orizzontale con l'immagine
            in verticale.
Figura 15. Buffer di immagini dopo una rotazione di 270 gradi in senso antiorario per l'orientamento del dispositivo.

Proporzioni

Le proporzioni del display cambiano quando cambia l'orientamento del dispositivo, ma anche quando i pieghevoli vengono aperti e chiusi, quando le finestre vengono ridimensionate in ambienti multi-finestra e quando le app si aprono su display secondari.

Il buffer di immagini del sensore della fotocamera deve essere orientato e ridimensionato in modo da corrispondere all'orientamento e alle proporzioni dell'elemento UI del mirino, poiché l'UI cambia dinamicamente l'orientamento, con o senza la modifica dell'orientamento del dispositivo.

Sui nuovi fattori di forma o in ambienti multi-finestra o multi-display, se la tua app presuppone che l'anteprima della fotocamera abbia lo stesso orientamento del dispositivo (verticale o orizzontale), l'anteprima potrebbe essere orientata o ridimensionata in modo errato o entrambe le cose.

Dispositivo pieghevole aperto con l'anteprima della fotocamera in modalità Ritratto ruotata di lato.
Figura 16. Il dispositivo pieghevole passa dalle proporzioni verticali a quelle orizzontali, ma il sensore della fotocamera rimane in orientamento verticale.

Nella figura 16, l'applicazione ha erroneamente presupposto che il dispositivo fosse ruotato di 90 gradi in senso antiorario, quindi l'app ha ruotato l'anteprima della stessa quantità.

Dispositivo pieghevole aperto con anteprima della fotocamera in verticale, ma schiacciata a causa di una scalabilità errata.
Figura 17. Il dispositivo pieghevole passa dalle proporzioni verticali a quelle orizzontali con un'anteprima della fotocamera ridimensionata in modo errato.

Nella figura 17, l'app non ha regolato le proporzioni del buffer di immagini per consentire la scalabilità corretta in base alle nuove dimensioni dell'elemento UI di anteprima della fotocamera.

Le app per fotocamera con orientamento fisso in genere presentano problemi sui pieghevoli e su altri dispositivi con schermi di grandi dimensioni, come i laptop:

L'anteprima della fotocamera sul laptop è verticale, ma la UI dell'app è orizzontale.
Figura 18. App con orientamento verticale fisso su un laptop.

Nella figura 18, la UI dell'app della fotocamera è laterale perché l'orientamento dell'app è limitato solo alla modalità verticale. L'immagine del mirino è orientata correttamente rispetto al sensore della fotocamera.

Modalità Ritratto con riquadro

Le app della fotocamera che non supportano la modalità multi-finestra (resizeableActivity="false") e limitano l'orientamento (screenOrientation="portrait" o screenOrientation="landscape") possono essere posizionate in modalità Ritratto con riquadro sui dispositivi con schermi grandi per orientare correttamente l'anteprima della fotocamera.

La modalità Ritratto con inset inserisce le app solo in modalità Ritratto (inset) con orientamento verticale, anche se le proporzioni del display sono orizzontali. Le app solo orizzontali vengono visualizzate in formato letterbox con orientamento orizzontale, anche se il formato del display è verticale. L'immagine della fotocamera viene ruotata per allinearsi alla UI dell'app, ritagliata in modo da corrispondere alle proporzioni dell'anteprima della fotocamera e poi ridimensionata per riempire l'anteprima.

La modalità Ritratto con riquadro viene attivata quando le proporzioni del sensore di immagine della fotocamera e le proporzioni dell'attività principale dell'applicazione non corrispondono.

Anteprima della fotocamera e UI dell'app con orientamento verticale corretto sul laptop.
            L'immagine di anteprima larga viene ridimensionata e ritagliata per adattarsi all'orientamento verticale.
Figura 19. App con orientamento verticale fisso in modalità Ritratto con riquadro su laptop.

Nella figura 19, l'app della fotocamera solo in modalità Ritratto è stata ruotata per visualizzare la UI in verticale sul display del laptop. L'app è in formato letterbox a causa della differenza di proporzioni tra l'app verticale e il display orizzontale. L'immagine di anteprima della fotocamera è stata ruotata per compensare la rotazione della UI dell'app (a causa della modalità Ritratto con inset) ed è stata ritagliata e ridimensionata per adattarsi all'orientamento verticale, riducendo il campo visivo.

Ruota, ritaglia, ridimensiona

La modalità Ritratto inserito viene richiamata per un'app della fotocamera solo in modalità Ritratto su un display con proporzioni orizzontali:

L'anteprima della fotocamera sul laptop è verticale, ma la UI dell'app è orizzontale.
Figura 20. App con orientamento verticale fisso su laptop.

L'app è in formato letterbox con orientamento verticale:

App ruotata in orientamento verticale e con formato letterbox. L'immagine è laterale, con la parte superiore a destra.
Figura 21. App solo verticale ruotata e con letterbox su un display orizzontale, prima della rotazione dell'immagine del sensore.

L'immagine della fotocamera viene ruotata di 90 gradi per adattarsi al nuovo orientamento dell'app:

Immagine del sensore ruotata di 90 gradi per raddrizzarla.
Figura 22. Immagine della fotocamera ruotata di 90 gradi per l'allineamento con la UI dell'app riorientata.

L'immagine viene ritagliata in base alle proporzioni dell'anteprima della fotocamera, quindi ridimensionata per riempire l'anteprima (il campo visivo viene ridotto):

Immagine della fotocamera ritagliata e ridimensionata per riempire l'anteprima della fotocamera.
Figura 23. Immagine della fotocamera ritagliata e ridimensionata per riempire l'anteprima della fotocamera in modalità Ritratto.

Sui dispositivi pieghevoli, l'orientamento del sensore della fotocamera può essere verticale, mentre le proporzioni del display sono orizzontali:

Anteprima della fotocamera e UI dell'app ruotate lateralmente sul display ampio e aperto.
Figura 24. Dispositivo aperto con app Fotocamera solo in modalità Ritratto e proporzioni diverse del sensore della fotocamera e del display.

Poiché l'anteprima della fotocamera viene ruotata per adattarsi all'orientamento del sensore, l'immagine è orientata correttamente nel mirino, ma l'app solo verticale è laterale.

La modalità Ritratto con riquadro deve solo applicare il letterbox all'app con orientamento verticale per orientare correttamente l'app e l'anteprima della fotocamera:

App in formato letterbox con orientamento verticale e anteprima della fotocamera
            in verticale su un dispositivo pieghevole.
Figura 25. App solo verticale con formato letterbox in modalità verticale con riquadro su un dispositivo pieghevole aperto.

API

A partire da Android 12 (livello API 31), le app possono anche controllare esplicitamente la modalità Ritratto con inset tramite la proprietà SCALER_ROTATE_AND_CROP della classe CaptureRequest.

Il valore predefinito è SCALER_ROTATE_AND_CROP_AUTO, che consente al sistema di richiamare la modalità Ritratto con riquadro. SCALER_ROTATE_AND_CROP_90 è il comportamento della modalità Ritratto con riquadro descritto in precedenza.

Non tutti i dispositivi supportano tutti i valori SCALER_ROTATE_AND_CROP. Per ottenere un elenco dei valori supportati, consulta CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.

CameraX

La libreria Jetpack CameraX semplifica la creazione di un mirino della fotocamera che si adatta all'orientamento del sensore e alla rotazione del dispositivo.

L'elemento di layout PreviewView crea un'anteprima della fotocamera, regolando automaticamente l'orientamento del sensore, la rotazione del dispositivo e la scalabilità. PreviewView mantiene le proporzioni dell'immagine della fotocamera applicando il tipo di scala FILL_CENTER, che centra l'immagine, ma potrebbe ritagliarla in modo che corrisponda alle dimensioni di PreviewView. Per applicare il letterbox all'immagine della videocamera, imposta il tipo di scala su FIT_CENTER.

Per scoprire le nozioni di base sulla creazione di un'anteprima della fotocamera con PreviewView, consulta Implementa un'anteprima.

Per un esempio completo di implementazione, consulta il repository CameraXBasic su GitHub.

CameraViewfinder

Analogamente al caso d'uso Anteprima, la libreria CameraViewfinder fornisce un insieme di strumenti per semplificare la creazione di un'anteprima della fotocamera. Non dipende da CameraX Core, quindi puoi integrarla facilmente nel tuo codebase Camera2 esistente.

Anziché utilizzare direttamente Surface, puoi utilizzare il widget CameraViewfinder per visualizzare il feed videocamera per Camera2.

CameraViewfinder utilizza internamente un TextureView o un SurfaceView per visualizzare il feed videocamera e applica le trasformazioni necessarie per visualizzare correttamente il mirino. Ciò comporta la correzione delle proporzioni, della scala e della rotazione.

Per richiedere la superficie dall'oggetto CameraViewfinder, devi creare un ViewfinderSurfaceRequest.

Questa richiesta contiene i requisiti per la risoluzione della superficie e le informazioni sul dispositivo della videocamera di CameraCharacteristics.

La chiamata a requestSurfaceAsync() invia la richiesta al provider della piattaforma, che è TextureView o SurfaceView, e riceve un ListenableFuture di Surface.

La chiamata a markSurfaceSafeToRelease() comunica al provider della superficie che quest'ultima non è necessaria e che le risorse correlate possono essere rilasciate.

fun startCamera() {
    val previewResolution = Size(width, height)
    val viewfinderSurfaceRequest =
        ViewfinderSurfaceRequest(previewResolution, characteristics)
    val surfaceListenableFuture =
        cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)

    Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
        override fun onSuccess(surface: Surface) {
            /* create a CaptureSession using this surface as usual */
        }
        override fun onFailure(t: Throwable) { /* something went wrong */ }
    }, ContextCompat.getMainExecutor(context))
}

SurfaceView

SurfaceView è un approccio semplice per creare un'anteprima della fotocamera se l'anteprima non richiede l'elaborazione e non è animata.

SurfaceView ruota automaticamente il buffer di immagini del sensore della fotocamera in modo che corrisponda all'orientamento del display, tenendo conto sia dell'orientamento del sensore sia della rotazione del dispositivo. Tuttavia, il buffer dell'immagine viene ridimensionato per adattarsi alle dimensioni SurfaceView senza considerare le proporzioni.

Devi assicurarti che le proporzioni del buffer dell'immagine corrispondano alle proporzioni di SurfaceView, il che può essere ottenuto scalando i contenuti di SurfaceView nel metodo onMeasure() del componente:

(Il codice sorgente computeRelativeRotation() si trova in Rotazione relativa di seguito.)

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    val width = MeasureSpec.getSize(widthMeasureSpec)
    val height = MeasureSpec.getSize(heightMeasureSpec)

    val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees)

    if (previewWidth > 0f && previewHeight > 0f) {
        /* Scale factor required to scale the preview to its original size on the x-axis. */
        val scaleX =
            if (relativeRotation % 180 == 0) {
                width.toFloat() / previewWidth
            } else {
                width.toFloat() / previewHeight
            }
        /* Scale factor required to scale the preview to its original size on the y-axis. */
        val scaleY =
            if (relativeRotation % 180 == 0) {
                height.toFloat() / previewHeight
            } else {
                height.toFloat() / previewWidth
            }

        /* Scale factor required to fit the preview to the SurfaceView size. */
        val finalScale = min(scaleX, scaleY)

        setScaleX(1 / scaleX * finalScale)
        setScaleY(1 / scaleY * finalScale)
    }
    setMeasuredDimension(width, height)
}

Per maggiori dettagli sull'implementazione di SurfaceView come anteprima della fotocamera, consulta Orientamenti della fotocamera.

TextureView

TextureView è meno efficiente di SurfaceView e richiede più lavoro, ma TextureView ti offre il massimo controllo dell'anteprima della fotocamera.

TextureView ruota il buffer dell'immagine del sensore in base all'orientamento del sensore, ma non gestisce la rotazione del dispositivo o la scalabilità dell'anteprima.

La scalabilità e la rotazione possono essere codificate in una trasformazione Matrix. Per scoprire come scalare e ruotare correttamente un TextureView, consulta Supporta le superfici ridimensionabili nell'app Fotocamera.

Rotazione relativa

La rotazione relativa del sensore della fotocamera è la quantità di rotazione necessaria per allineare l'output del sensore della fotocamera all'orientamento del dispositivo.

La rotazione relativa viene utilizzata da componenti come SurfaceView e TextureView per determinare i fattori di scalabilità x e y per l'immagine di anteprima. Viene utilizzato anche per specificare la rotazione del buffer dell'immagine del sensore.

Le classi CameraCharacteristics e Surface consentono di calcolare la rotazione relativa del sensore della fotocamera:

/**
 * Computes rotation required to transform the camera sensor output orientation to the
 * device's current orientation in degrees.
 *
 * @param characteristics The CameraCharacteristics to query for the sensor orientation.
 * @param surfaceRotationDegrees The current device orientation as a Surface constant.
 * @return Relative rotation of the camera sensor output.
 */
public fun computeRelativeRotation(
    characteristics: CameraCharacteristics,
    surfaceRotationDegrees: Int
): Int {
    val sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0

    // Reverse device orientation for back-facing cameras.
    val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT
    ) 1 else -1

    // Calculate desired orientation relative to camera orientation to make
    // the image upright relative to the device orientation.
    return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360
}

Metriche della finestra

Le dimensioni dello schermo non devono essere utilizzate per determinare le dimensioni del mirino della fotocamera; l'app della fotocamera potrebbe essere in esecuzione in una parte dello schermo, in modalità multi-finestra sui dispositivi mobili o in modalità libera su ChromeOS.

WindowManager#getCurrentWindowMetrics() (aggiunto nel livello API 30) restituisce le dimensioni della finestra dell'applicazione anziché quelle dello schermo. I metodi della libreria Jetpack WindowManager WindowMetricsCalculator#computeCurrentWindowMetrics() e WindowInfoTracker#currentWindowMetrics() forniscono un supporto simile con compatibilità con le versioni precedenti fino al livello API 14.

Rotazione: 180°

Una rotazione di 180 gradi di un dispositivo (ad esempio, dall'orientamento naturale all'orientamento naturale capovolto) non attiva il callback onConfigurationChanged(). Di conseguenza, l'anteprima della videocamera potrebbe essere capovolta.

Per rilevare una rotazione di 180 gradi, implementa un DisplayListener e controlla la rotazione del dispositivo con una chiamata a Display#getRotation() nel callback onDisplayChanged().

Risorse esclusive

Prima di Android 10, solo l'attività visibile in primo piano in un ambiente multi-finestra era nello stato RESUMED. Questo creava confusione negli utenti perché il sistema non forniva alcuna indicazione su quale attività fosse stata ripresa.

Android 10 (livello API 29) ha introdotto la ripresa multipla, in cui tutte le attività visibili sono nello stato RESUMED. Le attività visibili possono comunque entrare nello stato PAUSED se, ad esempio, un'attività trasparente si trova sopra l'attività o l'attività non è attivabile, ad esempio in modalità Picture in picture (consulta Supporto di Picture in picture).

Un'applicazione che utilizza la fotocamera, il microfono o qualsiasi risorsa esclusiva o singleton con livello API 29 o superiore deve supportare la ripresa multipla. Ad esempio, se tre attività riprese vogliono utilizzare la fotocamera, solo una può accedere a questa risorsa esclusiva. Ogni attività deve implementare un callback onDisconnected() per rimanere informata sull'accesso preventivo alla fotocamera da parte di un'attività con priorità più alta.

Per ulteriori informazioni, consulta la sezione Ripresa multipla.

Risorse aggiuntive