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 de câmera nem sempre estão na mesma orientação no Android dispositivos.

Uma câmera está em uma posição fixa no dispositivo, mesmo que ele não esteja é um smartphone, tablet ou computador. Quando a orientação do dispositivo muda, o mudanças na orientação da câmera.

Como resultado, os apps de câmera geralmente assumem uma relação fixa entre o 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 amplo. Quando o smartphone e a câmera são girados para o modo paisagem, é esperado que a visualização da câmera seja mais larga do que alta.

Mas essas suposições são desafiadas por novos formatos, como dispositivos dobráveis dispositivos e modos de exibição como várias janelas e Várias telas. Dispositivos dobráveis mudam o tamanho da tela e a proporção sem mudar orientação. O modo de várias janelas restringe os apps da câmera a uma parte tela, dimensionando a visualização da câmera, independentemente da orientação do dispositivo. O modo de várias telas permite o uso de telas secundárias que talvez não precisa 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 distância a dimensão da câmera se alinha à dimensão longa da tela. Ou seja, quando o dispositivo estiver na orientação paisagem, as câmeras PRECISAM capturar imagens a orientação de paisagem. Isso se aplica independentemente da integridade natural orientação; ou seja, aplica-se a dispositivos primários em modo paisagem, dispositivos principais no modo retrato".

A disposição entre a câmera e a tela maximiza a área de exibição em um app de câmera. Além disso, os sensores de imagem normalmente emitem dados 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 entre o sensor do smartphone e da câmera orientação.

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

Para expor a rotação do sensor a apps, o A API camera2 inclui um SENSOR_ORIENTATION constante. Na maioria dos smartphones e tablets, o dispositivo informa uma orientação do sensor. de 270 graus para câmeras frontais e 90 graus (ponto de vista da parte traseira do dispositivo) para as câmeras traseiras, que alinham a borda longa do com a borda longa do dispositivo. As câmeras de laptop geralmente relatam um orientação do sensor de 0 ou 180 graus.

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

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

Sensor da câmera girado para a orientação paisagem com imagem
            de lado, no canto superior esquerdo.

A imagem deve ser girada 270 graus no sentido anti-horário para que o orientação corresponde à orientação do dispositivo:

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

Uma câmera traseira produz um buffer de imagem com a mesma orientação como o buffer acima, mas SENSOR_ORIENTATION é 90 graus. Como resultado, é 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. Por exemplo, um smartphone na orientação paisagem tem um dispositivo rotação de 90 ou 270 graus, dependendo da direção da rotação.

Um buffer de imagem do sensor da câmera precisa ser girado no mesmo número de graus que o rotação do dispositivo (além dos graus de orientação do sensor) para o 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 o sensor orientação e rotação do dispositivo.

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

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

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

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

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

Diferentes APIs informam a rotação do dispositivo de maneira diferente:

  • Display#getRotation() fornece a rotação no sentido anti-horário (do ponto do usuário de vista). Esse valor é incorporado à fórmula acima no estado em que se encontra.
  • OrientationEventListener#onOrientationChanged() retorna a rotação no sentido horário do dispositivo (do ponto de vista do usuário). Negue o valor que será usado na fórmula acima.

Câmeras frontais

Visualização da câmera e sensor na orientação paisagem, sensor
            é o lado certo para cima.
Figura 2. Visualização da câmera e sensor com o smartphone virado 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 imagem na vertical.

O buffer precisa ser girado em 270 graus no sentido anti-horário para ajustar o sensor Orientação da câmera (consulte Orientação da câmera acima):

Sensor da câmera girado para a orientação de retrato com a imagem lateralmente.
            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 do visualização da câmera na Figura 2:

Sensor da câmera girado para a orientação paisagem com imagem
            direito.

Veja como a câmera está virada para a direita, na orientação paisagem:

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

Este é o buffer de imagem:

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

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

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

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

Sensor da câmera girado para a orientação paisagem com imagem
            direito.

Câmeras traseiras

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

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

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

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

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

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

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

Sensor da câmera girado para a orientação paisagem com imagem
            direito.

Proporção

A proporção da tela muda quando a orientação do dispositivo muda, mas também quando dobráveis se dobram e desdobram quando as janelas são redimensionadas no modo de várias janelas ambientes 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 ao orientação e proporção do elemento da interface do visor como a interface muda dinamicamente a orientação, com ou sem a alteração do dispositivo orientação.

Em novos formatos ou em ambientes de várias janelas ou telas, se sua presume que a visualização da câmera tem a mesma orientação que o dispositivo (retrato ou paisagem) talvez sua visualização não esteja na posição certa, incorretamente ou ambos.

Dispositivo dobrável desdobrado com a visualização da câmera em modo retrato ativada
            de lado.
Figura 5. Transições de dispositivos dobráveis do modo retrato para paisagem proporção, mas o sensor da câmera permanece na orientação retrato.

Na figura 5, o aplicativo presumiu por engano que o dispositivo foi girado 90o graus em sentido anti-horário; Assim, o app girou a visualização no mesmo nível.

Dispositivo dobrável desdobrado com a visualização da câmera na vertical, mas apertada
            devido a um escalonamento incorreto.
Figura 6. Transições de dispositivos dobráveis do modo retrato para paisagem proporção, mas o sensor da câmera permanece na orientação retrato.

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

Os apps de câmera com orientação fixa geralmente apresentam problemas em dispositivos 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 de orientação retrato em um laptop com orientação fixa.

Na Figura 7, a interface do app da câmera está lateralmente porque a orientação do app está restrito ao modo retrato. A imagem do visor está orientada corretamente em relação ao sensor da câmera.

Ajustar modo retrato

Apps de câmera que não são compatíveis com o modo de várias janelas (resizeableActivity="false") e restringem a orientação (screenOrientation="portrait") ou screenOrientation="landscape") pode ser colocado no modo retrato embutido em dispositivos de tela grande para orientar corretamente a visualização da câmera.

Encartes com efeito letterbox (encartes) de apps somente retrato no modo retrato orientação, mesmo que a proporção da tela seja paisagem. Apps somente paisagem têm efeito letterbox na orientação paisagem, mesmo que a proporção da tela é retrato. A imagem da câmera é girada para ficar alinhada com a interface do app, cortada para corresponder à proporção da visualização da câmera; e dimensionada para preencher a visualização.

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

Visualização da câmera e interface do app na orientação retrato correta em um laptop.
            A imagem de visualização ampla é dimensionada e cortada para se ajustar ao modo retrato
            orientação.
Figura 8. App retrato com orientação fixa no modo retrato inserido ativado laptop.

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

Girar, cortar, dimensionar

O modo retrato inserido é 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 de retrato com orientação fixa no laptop.

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

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

A imagem da câmera é girada em 90 graus para se ajustar à reorientação do aplicativo:

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

A imagem é cortada na proporção da visualização da câmera e redimensionada 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 for paisagem:

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

Como a visualização da câmera é girada para se ajustar à orientação do sensor, a imagem está devidamente orientada no visor, mas o aplicativo apenas de retrato fica de lado.

O encarte do modo retrato só precisa 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 visualização da câmera
            na posição vertical em um dispositivo dobrável.

API

A partir do Android 12 (nível 31 da API), os apps também podem controlar explicitamente o encarte de retrato usando o SCALER_ROTATE_AND_CROP do elemento CaptureRequest .

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

Nem todos os dispositivos oferecem suporte a todos os valores de SCALER_ROTATE_AND_CROP. Para obter uma lista de valores suportados, consulte CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES

CameraX

Biblioteca Jetpack CameraX torna a criação de um visor da câmera que acomoda a orientação do sensor e a rotação do dispositivo como uma tarefa simples.

O elemento de layout PreviewView cria uma visualização da câmera, ajustando automaticamente para a orientação do sensor, rotação e escalonamento de dispositivos. PreviewView mantém a proporção do imagem da câmera aplicando o FILL_CENTER tipo de escala, 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 as noções básicas da criação de uma visualização da câmera com o PreviewView, consulte Implementar uma visualização.

Para um exemplo completo de implementação, consulte a CameraXBasic no GitHub.

Visor da câmera

Assim como no caso de uso de Preview, o CameraViewfinder oferece um conjunto de ferramentas para simplificar a criação de uma visualização da câmera. Como ele não depende do CameraX Core, pode ser integrado perfeitamente ao seu base de código existente da Camera2.

Em vez de usar Surface diretamente, use o CameraViewfinder para exibir a transmissão da Camera2.

O CameraViewfinder usa internamente um TextureView ou um SurfaceView. para exibir o feed da câmera e aplica as transformações necessárias nelas ao exibir 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.

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

Ligando para requestSurfaceAsync() envia a solicitação para o provedor de superfície, que é um TextureView ou SurfaceView e recebe um ListenableFuture de Surface.

Ligando para markSurfaceSafeToRelease() notifica o provedor de superfície de que ela não é necessária e está relacionada recursos 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 é um uma abordagem simples para criar uma visualização da câmera caso ela não exigem processamento e não são animados.

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

Você precisa garantir que a proporção do buffer de imagem corresponda ao formato proporção do SurfaceView, que pode ser alcançada dimensionando o conteúdo do SurfaceView no ciclo de vida onMeasure() :

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 menor desempenho que SurfaceView e muito mais trabalho, mas o TextureView oferece o máximo de controle 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 nem o escalonamento de visualização.

O dimensionamento e a rotação podem ser codificados Matrix (link em inglês). Para saber como dimensionar e girar corretamente uma TextureView, consulte Suporte a superfícies redimensionáveis no app de câmera

Rotação relativa

A rotação relativa do sensor da câmera é a quantidade de rotação necessária para alinhe a saída do sensor da câmera à 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 especifica a rotação do buffer de imagem do sensor.

A CameraCharacteristics e As classes 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 da câmera visor o app da câmera pode estar em execução 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 de o tamanho da tela. Os métodos da biblioteca WindowManager do Jetpack WindowMetricsCalculator#computeCurrentWindowMetrics() e WindowInfoTracker#currentWindowMetrics() fornecem 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, de orientação natural para orientação natural de cabeça para baixo) não aciona o onConfigurationChanged() o retorno de chamada. Como resultado, a visualização da câmera pode estar de cabeça para baixo.

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

Recursos exclusivos

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

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

Um aplicativo que usa a câmera, o microfone ou qualquer aplicativo o recurso singleton na API de nível 29 ou mais recente precisa oferecer suporte à retomada múltipla. Para exemplo, se três atividades retomadas quiserem usar a câmera, somente uma poderá para acessar esse recurso exclusivo. Cada atividade deve implementar uma onDisconnected() para manter o acesso preemptivo à câmera com prioridade mais alta atividades.

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

Outros recursos