Camera Preview Shows White Screen in APK - Overlay Visible but Camera Not Displayed

I’ve been working on an Ionic project that involves using the Capacitor Camera Preview plugin to take selfies. Everything works fine when I run the app in the browser or on an emulator. However, when I build the APK and run it on a physical device, the camera preview shows a white screen. The overlay elements are visible, but the camera feed is not displayed.

I’ve ensured that the CameraPreviewOptions are correctly set, and I’ve tried adjusting the z-index and background styles as suggested in various forums, but the issue persists. Here are the details of my setup:

Relevant Code Snippets

TypeScript (bp-tirar-selfie.component.ts):

import { Component, OnInit } from '@angular/core';
import { CameraPreview, CameraPreviewOptions } from '@capacitor-community/camera-preview';
import { SharedModule } from '../../shared.module';
import { InstrucoesSelfieComponent } from './modal-instrucoes-selfie/instrucoes-selfie.component';
import { ModalController, NavController } from '@ionic/angular';
import { VisualizarFotoComponent } from './modal-visualizar-foto/visualizar-foto.component';
import { OverlayService } from 'src/app/core/services/overlay/overlay.service';

const cameraPreviewOptions: CameraPreviewOptions = {
  position: 'front',
  className: 'cameraPreview',
  parent: 'cameraPreview', // Ensure this element exists in your template
  toBack: true, // Push the camera preview behind the web view content
};

@Component({
  selector: 'app-bp-tirar-selfie',
  templateUrl: './bp-tirar-selfie.component.html',
  styleUrls: ['./bp-tirar-selfie.component.scss'],
  standalone: true,
  imports: [SharedModule],
})
export class BpTirarSelfieComponent implements OnInit {
  public cameraActive = false;
  public image: string | null = null;
  public selfieUsuario = '';

  constructor(private modalCtrl: ModalController, private overlayService: OverlayService) { }

  ngOnInit() {
    this.mostrarInstrucoes();
  }

  public async mostrarInstrucoes() {
    const modal = await this.modalCtrl.create({
      component: InstrucoesSelfieComponent,
      backdropDismiss: false,
    });

    modal.onDidDismiss().then(() => {
      this.openCamera();
    });

    return await modal.present();
  }

  public openCamera() {
    CameraPreview.start(cameraPreviewOptions);
    this.cameraActive = true;
  }

  public async takePicture() {
    try {
      const result = await CameraPreview.capture();
      const base64PictureData = result.value;
      sessionStorage.setItem('fotoFace', base64PictureData);
      this.stopCamera();
      await this.verificarFoto(base64PictureData);
    } catch (error) {
      console.error(error);
      this.overlayService.toast({
        message: 'Erro ao tirar foto, por favor tente novamente.',
        duration: 2000,
        color: 'danger',
      });
    }
  }

  public async verificarFoto(foto: string) {
    const modal = await this.modalCtrl.create({
      component: VisualizarFotoComponent,
      componentProps: {
        foto: 'data:image/png;base64,' + foto,
      },
    });

    modal.onDidDismiss().then((ret) => {
      if (ret.data && ret.data === 'mudar') {
        sessionStorage.removeItem('fotoFace');
        this.openCamera();
      } else {
        this.returnPage();
      }
    });

    return await modal.present();
  }

  public async returnPage() {
    await this.stopCamera();
    this.modalCtrl.dismiss();
  }

  public async switchCamera() {
    CameraPreview.flip();
  }

  public async stopCamera() {
    CameraPreview.stop();
  }
}

HTML (bp-tirar-selfie.component.html):

<ion-content>
  <div id="cameraPreview" class="cameraPreview">
    <!-- Camera feed will be displayed here -->
  </div>
  <img class="molde-cabeca" src="/assets/images/perfil/face.png" *ngIf="cameraActive" />
  <p class="texto" *ngIf="cameraActive">
    Enquadre seu rosto na moldura e aperte o botão Amarelo para tirar uma nova
    foto. Tire máscaras, óculos e outros adereços.
  </p>
  <div *ngIf="cameraActive">
    <ion-fab vertical="bottom" horizontal="start">
      <ion-fab-button color="light" (click)="returnPage()" routerDirection="back">
        <ion-icon name="arrow-back"></ion-icon>
      </ion-fab-button>
    </ion-fab>
    <ion-fab vertical="bottom" horizontal="center">
      <ion-fab-button color="warning" (click)="takePicture()">
        <ion-icon name="camera"></ion-icon>
      </ion-fab-button>
    </ion-fab>
    <ion-fab vertical="bottom" horizontal="end">
      <ion-fab-button color="light" (click)="switchCamera()">
        <ion-icon name="camera-reverse-sharp"></ion-icon>
      </ion-fab-button>
    </ion-fab>
  </div>
</ion-content>

CSS (bp-tirar-selfie.component.scss):

.cameraPreview {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1; /* Ensure it's behind other elements */
  background: transparent;
}

ion-content {
  --background: transparent; /* Make sure the background is transparent */
  position: relative; /* Ensure the content positions correctly */
  z-index: 0; /* Default z-index for content */
}

.molde-cabeca {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1; /* Ensure the frame is above the camera preview */
}

Problem Description

  • When running the app on a device using the APK, the camera preview area shows a white screen.
  • The overlay elements (e.g., the frame image) are visible and interactable.
  • The camera feed is not displayed, though the camera appears to function as expected (e.g., taking pictures works).

Assuming you’ve debugged (looked for any errors) on your Android device looking at DevTools via chrome://inspect/#devices and LogCat in Android Studio?

Also, what version of Capacitor and the plugin are you using?

It’s not showing any error log in chrome://inspect/#devices. Clicking the yellow button only takes a snapshot.


Those are the versions that I am using.

 "@capacitor-community/camera-preview": "^6.0.0",
    "@capacitor/android": "5.6.0",
    "@capacitor/app": "5.0.7",
    "@capacitor/browser": "^5.2.0",
    "@capacitor/core": "^6.1.0",
    "@capacitor/haptics": "5.0.7",
    "@capacitor/ios": "5.6.0",
    "@capacitor/keyboard": "5.0.8",
    "@capacitor/share": "^6.0.1",
    "@capacitor/status-bar": "5.0.7",

First, you have mix-matched versions for Capacitor and its plugins. Everything should be on v5 or v6.

Depending on if you are using Capacitor 5 or 6, you also need to use the correct version for @capacitor-community/camera-preview.

Version 6 of this plugin requires Capacitor 6.

If you are using Capacitor 5, use version 5
(source)

`I’ve tried to use version 5 of the plugin, but the error persists. So, I updated my Capacitor version, but I’m still getting the error.

Updating to 6.0 | Capacitor Documentation (capacitorjs.com)

"@capacitor-community/camera-preview": "^6.0.0",
"@capacitor/android": "^6.0.0",
"@capacitor/app": "^6.0.0",
"@capacitor/browser": "^6.0.0",
"@capacitor/core": "^6.0.0",
"@capacitor/haptics": "^6.0.0",
"@capacitor/ios": "^6.0.0",
"@capacitor/keyboard": "^6.0.0",
"@capacitor/share": "^6.0.0",
"@capacitor/status-bar": "^6.0.0",`
"@capacitor/cli": "^6.0.0",

Hi everyone,

I wanted to update you on the issue I was facing with the camera preview showing a white screen in the APK. After further investigation and some trial and error, I found the solution.

Solution:

The problem was caused by using the Camera Preview plugin within a modal. It appears that the plugin does not function correctly when initialized inside a modal. Instead, it needs to be used directly on a page.

If the camera preview shows a white screen in your APK but overlays are visible, it could be due to camera permissions or compatibility issues with the device’s camera hardware. Check permissions in your manifest file and ensure your camera initialization code handles different device configurations correctly. Updating device drivers or testing on different devices may also help identify the issue.

If clicking the yellow button only takes a snapshot and you’re not seeing any error logs in chrome://inspect/#devices