Visualização da câmera

Observação:esta página se refere ao pacote Camera2. A menos que seu app exija recursos específicos e de baixo nível do Camera2, recomendamos o uso do CameraX. CameraX e Camera2 oferecem suporte ao Android 5.0 (nível 21 da API) e versões mais recentes.

As câmeras e as visualizações da câmera nem sempre estão na mesma orientação em dispositivos Android.

A câmera fica em uma posição fixa no dispositivo, seja ele um smartphone, tablet ou computador. Quando a orientação do dispositivo mudar, a orientação da câmera mudará.

Como resultado, os apps de câmera geralmente presumem uma relação fixa entre a orientação do dispositivo e a proporção da visualização da câmera. Quando um smartphone está na orientação retrato, a visualização da câmera é considerada mais alta do que larga. Quando o smartphone e a câmera são girados para o modo paisagem, a visualização da câmera precisa ser mais larga do que alta.

No entanto, essas suposições são desafiadas por novos formatos, como dispositivos dobráveis, e modos de exibição, como várias janelas e várias telas. Os dispositivos dobráveis mudam o tamanho da tela e a proporção sem mudar a orientação. O modo de várias janelas restringe os apps de câmera a uma parte da tela, dimensionando a visualização da câmera, independente da orientação do dispositivo. O modo de várias telas permite o uso de telas secundárias que podem não estar na mesma orientação da tela principal.

Orientação da câmera

A Definição de compatibilidade do Android especifica que um sensor de imagem de câmera "PRECISA estar orientado de forma que a dimensão longa da câmera se alinhe à dimensão longa da tela. Ou seja, quando o dispositivo é usado na orientação paisagem, as câmeras PRECISAM capturar imagens na orientação paisagem. Isso se aplica independentemente da orientação natural do dispositivo, ou seja, é aplicado a dispositivos com foco no modo paisagem e em modo retrato.

A organização da câmera para a tela maximiza a área de exibição do visor da câmera em um app. Além disso, os sensores de imagem normalmente geram dados em proporções de paisagem, sendo 4:3 a mais comum.

Sensor do smartphone e da câmera na orientação retrato.
Figura 1. Relação típica da orientação do sensor do smartphone e da câmera.

A orientação natural do sensor da câmera é paisagem. Na Figura 1, o sensor da câmera frontal (aquela que aponta na mesma direção que a tela) é girado 270 graus em relação ao smartphone para obedecer à Definição de compatibilidade do Android.

Para expor a rotação do sensor para apps, a API camera2 inclui uma constante SENSOR_ORIENTATION. Para a maioria dos smartphones e tablets, o dispositivo informa uma orientação de sensor de 270 graus para câmeras frontais e 90 graus (ponto de vista da parte de trás do dispositivo) para câmeras traseiras, o que alinha a borda longa do sensor à borda longa do dispositivo. As câmeras de laptops geralmente relatam uma orientação do sensor de 0 ou 180 graus.

Como os sensores de imagem da câmera geram dados (um buffer de imagem) na orientação natural do sensor (paisagem), o buffer precisa ser girado no número de graus especificado por SENSOR_ORIENTATION para que a visualização da câmera apareça na vertical na orientação natural do dispositivo. Para câmeras frontais, a rotação é no sentido anti-horário. Para câmeras traseiras, sentido horário.

Por exemplo, para a câmera frontal na Figura 1, o buffer de imagem produzido pelo sensor da câmera tem esta aparência:

O sensor da câmera foi girado para a orientação paisagem com a imagem
            de lado. Parte de cima à esquerda.

A imagem precisa ser girada 270 graus no sentido anti-horário para que a orientação da visualização corresponda à orientação do dispositivo:

Sensor da câmera na orientação retrato com imagem na vertical.

Uma câmera traseira produzir um buffer de imagem com a mesma orientação do buffer acima, mas SENSOR_ORIENTATION é de 90 graus. Como resultado, o buffer é girado 90 graus no sentido horário.

Rotação do dispositivo

A rotação do dispositivo é o número de graus em que um dispositivo é girado em relação à orientação natural. Por exemplo, um smartphone na orientação paisagem tem uma rotação de 90 ou 270 graus, dependendo da direção de rotação.

Um buffer de imagem do sensor da câmera precisa ser girado no mesmo número de graus que a rotação do dispositivo (além dos graus de orientação do sensor) para que a visualização da câmera apareça na posição vertical.

Cálculo da orientação

A orientação adequada da visualização da câmera considera a orientação do sensor e a rotação do dispositivo.

A rotação geral do buffer de imagem do sensor pode ser calculada usando a seguinte fórmula:

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

em que sign é 1 para câmeras frontais, -1 para câmeras traseiras.

Para câmeras frontais, o buffer de imagem é girado no sentido anti-horário (em relação à orientação natural do sensor). Para câmeras traseiras, o buffer de imagem do sensor é girado no sentido horário.

A expressão deviceOrientationDegrees * sign + 360 converte a rotação do dispositivo de anti-horário para horário para câmeras traseiras, por exemplo, convertendo de 270 graus no sentido anti-horário para 90 graus em sentido horário. A operação de módulo escalona o resultado para menos de 360 graus (por exemplo, escalando 540 graus de rotação para 180).

Diferentes APIs relatam a rotação de dispositivos de forma diferente:

  • Display#getRotation() fornece a rotação no sentido anti-horário do dispositivo (do ponto de vista do usuário). Esse valor é inserido na fórmula acima como está.
  • OrientationEventListener#onOrientationChanged() retorna a rotação no sentido horário do dispositivo (do ponto de vista do usuário). Negue o valor para uso na fórmula acima.

Câmeras frontais

Visualização da câmera e sensor, ambos na orientação paisagem, e o sensor
            está com o lado direito para cima.
Figura 2. Visualização da câmera e sensor com smartphone girado em 90 graus para orientação paisagem.

Este é o buffer de imagem produzido pelo sensor da câmera na Figura 2:

Sensor da câmera na orientação paisagem com a imagem na vertical.

O buffer precisa ser girado 270 graus no sentido anti-horário para ajustar a orientação do sensor. Consulte Orientação da câmera acima:

O sensor da câmera foi girado para a orientação de retrato com a imagem de lado.
            No canto superior direito.

Em seguida, o buffer é girado mais 90 graus no sentido anti-horário para considerar a rotação do dispositivo, resultando na orientação correta da visualização da câmera na Figura 2:

O sensor da câmera foi girado para a orientação paisagem com a imagem
            na posição vertical.

Veja como a câmera virou à direita para a orientação paisagem:

Visualização da câmera e sensor, ambos na orientação paisagem, mas
            o sensor está de cabeça para baixo.
Figura 3. Visualização da câmera e sensor com smartphone girado em 270 graus (ou -90 graus) para a orientação paisagem.

Este é o buffer de imagem:

O sensor da câmera foi girado para a orientação paisagem com a imagem de cabeça para baixo.

O buffer precisa ser girado 270 graus no sentido anti-horário para ajustar a orientação do sensor:

Sensor da câmera classificado para orientação retrato com imagem lateral,
            no canto superior esquerdo.

Em seguida, o buffer é girado mais 270 graus no sentido anti-horário para considerar a rotação do dispositivo:

O sensor da câmera foi girado para a orientação paisagem com a imagem
            na posição vertical.

Câmeras traseiras

As câmeras traseiras geralmente têm uma orientação de sensor de 90 graus, conforme visto de trás do dispositivo. Ao orientar a visualização da câmera, o buffer de imagem do sensor é girado no sentido horário pela quantidade de rotação do sensor (em vez de anti-horário, como câmeras frontais), e o buffer de imagem é girado no sentido anti-horário pela quantidade de rotação do dispositivo.

Visualização da câmera e sensor, ambos na orientação paisagem, mas
            o sensor está de cabeça para baixo.
Figura 4. Smartphone com câmera traseira na orientação paisagem (girado em 270 ou -90 graus).

Este é o buffer de imagem do sensor da câmera na Figura 4:

O sensor da câmera foi girado para a orientação paisagem com a imagem de cabeça para baixo.

O buffer precisa ser girado 90 graus no sentido horário para ajustar a orientação do sensor:

Sensor da câmera classificado para orientação retrato com imagem lateral,
            no canto superior esquerdo.

Em seguida, o buffer é girado 270 graus no sentido anti-horário para considerar a rotação do dispositivo:

O sensor da câmera foi girado para a orientação paisagem com a imagem
            na posição vertical.

Proporção

A proporção da tela muda quando a orientação do dispositivo muda, mas também quando os dispositivos dobráveis são dobrados e desdobrados, quando as janelas são redimensionadas em ambientes de várias janelas e quando os apps são abertos em telas secundárias.

O buffer de imagem do sensor da câmera precisa ser orientado e dimensionado para corresponder à orientação e à proporção do elemento da interface do visor, conforme a interface muda dinamicamente a orientação, com ou sem o dispositivo mudar a orientação.

Em novos formatos ou em ambientes de várias janelas ou telas, se o app presume que a visualização da câmera tem a mesma orientação que o dispositivo (retrato ou paisagem), a visualização pode estar orientada incorretamente, dimensionada incorretamente ou ambas.

Dispositivo dobrável desdobrado com a visualização da câmera no modo retrato virada
            para os lados.
Figura 5. O dispositivo dobrável faz a transição da proporção de retrato para paisagem, mas o sensor da câmera permanece na orientação de retrato.

Na Figura 5, o aplicativo presumiu por engano que o dispositivo foi girado 90 graus no sentido anti-horário e, assim, o app girou a visualização no mesmo valor.

Dispositivo dobrável desdobrado com a visualização da câmera na vertical, mas comprimido
            devido ao escalonamento incorreto.
Figura 6. O dispositivo dobrável faz a transição da proporção de retrato para paisagem, mas o sensor da câmera permanece na orientação de retrato.

Na Figura 6, o app não ajustou a proporção do buffer de imagem para permitir que ele fosse dimensionado corretamente para se ajustar às novas dimensões do elemento da interface de visualização da câmera.

Os apps de câmera com orientação fixa geralmente apresentam problemas em dobráveis e outros dispositivos de tela grande, como laptops:

A visualização da câmera no laptop está na posição vertical, mas a interface do app está de lado.
Figura 7. App em modo retrato com orientação fixa no laptop.

Na Figura 7, a IU do app de câmera está de lado porque a orientação do app está restrita apenas ao retrato. A imagem do visor está orientada corretamente em relação ao sensor da câmera.

Modo retrato inserido

Apps de câmera que não oferecem suporte ao modo de várias janelas (resizeableActivity="false") e restringem a orientação (screenOrientation="portrait" ou screenOrientation="landscape") podem ser colocados no modo retrato encartado em dispositivos de tela grande para orientar corretamente a visualização da câmera.

Inserções de apps do modo retrato com efeito letterbox (encartes) apenas na orientação retrato, mesmo que a proporção da tela seja paisagem. Os apps somente paisagem têm efeito letterbox na orientação paisagem, mesmo que a proporção da tela seja retrato. A imagem da câmera é girada para se alinhar à interface do app, cortada para corresponder à proporção da visualização da câmera e redimensionada para preencher a visualização.

O modo retrato encartado é acionado quando a proporção do sensor de imagem da câmera e a proporção da atividade principal do app não correspondem.

Visualização da câmera e interface do app na orientação retrato adequada no laptop.
            A imagem de visualização ampla é dimensionada e cortada para se ajustar à orientação
            retrato.
Figura 8. App retrato com orientação fixa no modo retrato encartado no laptop.

Na Figura 8, o app de câmera somente na orientação retrato foi girado para mostrar a interface na posição vertical na tela do laptop. O app recebe o efeito letterbox devido à diferença na proporção entre o app no modo retrato e a tela no modo paisagem. A imagem de visualização da câmera foi girada para compensar a rotação da interface do app (devido ao modo retrato encartado), e a imagem foi cortada e dimensionada para se ajustar à orientação retrato, reduzindo o campo de visão.

Girar, cortar, dimensionar

O modo retrato encartado é invocado para um app de câmera somente retrato em uma tela com proporção de paisagem:

A visualização da câmera no laptop está na posição vertical, mas a interface do app está de lado.
Figura 9. App em modo retrato com orientação fixa no laptop.

O app tem efeito letterbox na orientação retrato:

O app foi girado para a orientação retrato e com efeito letterbox. A imagem está de lado, à direita.

A imagem da câmera é girada em 90 graus para ajustar a reorientação do app:

A imagem do sensor foi girada em 90 graus para ficar na posição vertical.

A imagem é cortada de acordo com a proporção da visualização da câmera e, em seguida, dimensionada para preencher a visualização (o campo de visão é reduzido):

Imagem cortada da câmera dimensionada para preencher a visualização da câmera.

Em dispositivos dobráveis, a orientação do sensor da câmera pode ser retrato, enquanto a proporção da tela é paisagem:

A visualização da câmera e a interface do app viraram a tela larga e desdobrada.
Figura 10. Dispositivo desdobrado com app de câmera somente para o modo retrato e proporções diferentes do sensor e da tela da câmera.

Como a visualização da câmera é girada para ajustar a orientação do sensor, a imagem fica corretamente orientada no visor, mas o app somente em modo retrato está de lado.

O modo retrato encartado precisa apenas colocar o app com efeito letterbox na orientação retrato para orientar corretamente o app e a visualização da câmera:

App com efeito letterbox na orientação de retrato com a visualização da câmera
            na posição vertical em um dispositivo dobrável.

API

No Android 12 (nível 31 da API) e versões mais recentes, os apps também podem controlar explicitamente o modo retrato encartado usando a propriedade SCALER_ROTATE_AND_CROP da classe CaptureRequest.

O valor padrão é SCALER_ROTATE_AND_CROP_AUTO, que permite ao sistema invocar o modo retrato encartado. SCALER_ROTATE_AND_CROP_90 é o comportamento do modo retrato encartado, conforme descrito acima.

Nem todos os dispositivos oferecem suporte a todos os valores de SCALER_ROTATE_AND_CROP. Para ver uma lista de valores compatíveis, consulte CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.

CameraX

A biblioteca Jetpack CameraX transforma a criação de um visor de câmera que acomoda a orientação do sensor e a rotação do dispositivo em uma tarefa simples.

O elemento de layout PreviewView cria uma visualização da câmera, ajustando automaticamente a orientação do sensor, a rotação do dispositivo e o dimensionamento. PreviewView mantém a proporção da imagem da câmera ao aplicar o tipo de escala FILL_CENTER, que centraliza a imagem, mas pode cortá-la para corresponder às dimensões de PreviewView. Para usar o efeito letterbox na imagem da câmera, defina o tipo de escala como FIT_CENTER.

Para aprender os conceitos básicos da criação de uma visualização da câmera com PreviewView, consulte Implementar uma visualização.

Para conferir um exemplo completo de implementação, consulte o repositório CameraXBasic no GitHub.

Visor da câmera

Assim como o caso de uso da Preview, a biblioteca CameraViewfinder fornece um conjunto de ferramentas para simplificar a criação de uma visualização da câmera. Ele não depende do CameraX Core para que possa ser integrado perfeitamente à base de código do Camera2.

Em vez de usar o Surface diretamente, você pode usar o widget CameraViewfinder para mostrar a transmissão da Camera2.

A CameraViewfinder usa internamente uma TextureView ou SurfaceView para mostrar a transmissão da câmera e aplica as transformações necessárias a elas para mostrar o visor corretamente. Isso envolve corrigir a proporção, a escala e a rotação.

Para solicitar a superfície do objeto CameraViewfinder, você precisa criar um ViewfinderSurfaceRequest.

Essa solicitação contém requisitos para a resolução da superfície e as informações do dispositivo de câmera de CameraCharacteristics.

Chamar requestSurfaceAsync() envia a solicitação para o provedor da plataforma, que é um TextureView ou SurfaceView, e recebe um ListenableFuture de Surface.

Chamar markSurfaceSafeToRelease() notifica o provedor da superfície de que ela não é necessária e que os recursos relacionados podem ser liberados.

Kotlin


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))
}

Java


    void startCamera(){
        Size previewResolution = new Size(width, height);
        ViewfinderSurfaceRequest viewfinderSurfaceRequest =
                new ViewfinderSurfaceRequest(previewResolution, characteristics);
        ListenableFuture<Surface> surfaceListenableFuture =
                cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest);

        Futures.addCallback(surfaceListenableFuture, new FutureCallback<Surface>() {
            @Override
            public void onSuccess(Surface result) {
                /* create a CaptureSession using this surface as usual */
            }
            @Override public void onFailure(Throwable t) { /* something went wrong */}
        },  ContextCompat.getMainExecutor(context));
    }

SurfaceView

SurfaceView é uma abordagem simples para criar uma visualização de câmera se a visualização não precisar de processamento e não for animada.

SurfaceView gira automaticamente o buffer de imagem do sensor da câmera para corresponder à orientação da tela, considerando a orientação do sensor e a rotação do dispositivo. No entanto, o buffer de imagem é dimensionado para se ajustar às dimensões SurfaceView sem considerar a proporção.

Garanta que a proporção do buffer de imagem corresponda à do SurfaceView, o que pode ser feito dimensionando o conteúdo do SurfaceView no método onMeasure() do componente:

O código-fonte computeRelativeRotation() está em Rotação relativa abaixo.

Kotlin

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)
}

Java

@Override
void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);

    int relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees);

    if (previewWidth > 0f && previewHeight > 0f) {

        /* Scale factor required to scale the preview to its original size on the x-axis. */
        float scaleX = (relativeRotation % 180 == 0)
                       ? (float) width / previewWidth
                       : (float) width / previewHeight;

        /* Scale factor required to scale the preview to its original size on the y-axis. */
        float scaleY = (relativeRotation % 180 == 0)
                       ? (float) height / previewHeight
                       : (float) height / previewWidth;

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

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

Para mais detalhes sobre como implementar SurfaceView como uma visualização da câmera, consulte Orientação da câmera.

TextureView

TextureView tem performance inferior à SurfaceView e mais trabalho, mas TextureView oferece controle máximo da visualização da câmera.

TextureView gira o buffer de imagem do sensor com base na orientação do sensor, mas não processa a rotação do dispositivo ou o dimensionamento de visualização.

O dimensionamento e a rotação podem ser codificados em uma transformação de matriz. Para aprender a dimensionar e girar corretamente uma TextureView, consulte Suporte a superfícies redimensionáveis no seu app de câmera

Rotação relativa

A rotação relativa do sensor da câmera é a quantidade de rotação necessária para alinhar a saída do sensor da câmera com a orientação do dispositivo.

A rotação relativa é usada por componentes como SurfaceView e TextureView para determinar os fatores de escalonamento x e y da imagem de visualização. Ele também é usado para especificar a rotação do buffer de imagem do sensor.

As classes CameraCharacteristics e Surface permitem o cálculo da rotação relativa do sensor da câmera:

Kotlin

/**
 * 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)!!

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

Java

/**
 * 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 int computeRelativeRotation(
    CameraCharacteristics characteristics,
    int surfaceRotationDegrees
){
    Integer sensorOrientationDegrees =
        characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);

    // Reverse device orientation for back-facing cameras.
    int sign = characteristics.get(CameraCharacteristics.LENS_FACING) ==
        CameraCharacteristics.LENS_FACING_FRONT ? 1 : -1;

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

Métricas de janela

O tamanho da tela não deve ser usado para determinar as dimensões do visor da câmera. O app da câmera pode estar sendo executado em uma parte da tela, seja no modo de várias janelas em dispositivos móveis ou no modo livre no ChromeOS.

WindowManager#getCurrentWindowMetrics() (adicionado no nível 30 da API) retorna o tamanho da janela do aplicativo em vez do tamanho da tela. Os métodos da biblioteca WindowManager do Jetpack WindowMetricsCalculator#computeCurrentWindowMetrics() e WindowInfoTracker#currentWindowMetrics() oferecem suporte semelhante com compatibilidade com versões anteriores à API de nível 14.

Rotação de 180 graus

Uma rotação de 180 graus de um dispositivo (por exemplo, da orientação natural para a orientação natural de cabeça para baixo) não aciona o callback onConfigurationChanged(). Por isso, a visualização da câmera pode estar de cabeça para baixo.

Para detectar uma rotação de 180 graus, implemente um DisplayListener e verifique a rotação do dispositivo com uma chamada para Display#getRotation() no callback onDisplayChanged().

Recursos exclusivos

Antes do Android 10, apenas a atividade mais visível em um ambiente de várias janelas estava no estado RESUMED. Isso era confuso para os usuários, porque o sistema não indicava qual atividade foi retomada.

O Android 10 (nível 29 da API) introduziu a retomada múltipla, em que todas as atividades visíveis estão no estado RESUMED. Atividades visíveis ainda poderão entrar no estado PAUSED se, por exemplo, uma atividade transparente estiver sobre a atividade ou ela não for focalizável, como no modo picture-in-picture. Consulte Suporte ao modo picture-in-picture.

Um aplicativo que usa a câmera, o microfone ou qualquer recurso exclusivo ou singleton na API de nível 29 ou mais recente precisa oferecer suporte à retomada múltipla. Por exemplo, se três atividades retomadas quiserem usar a câmera, somente uma vai poder acessar esse recurso exclusivo. Cada atividade precisa implementar um callback onDisconnected() para ficar ciente do acesso preventivo à câmera por uma atividade de prioridade mais alta.

Para ver mais informações, consulte Retomada múltipla.

Outros recursos