Skip to content

✨ [Android] Torch stays on when app is sent to background #4028

Description

@DmytroMedvediuk

Prerequisites

What problem are you trying to solve?

On Android, when the user sends the app to the background (home button,
recent apps, incoming call), the torch remains physically on even if
torch="off" is subsequently set from JS.

The root cause is that Android does not automatically interrupt the camera
hardware on backgrounding (unlike iOS, where the OS interrupts the
AVCaptureSession at the hardware level). The Camera component stays mounted
with torch="on", and the JS thread can be paused before the prop update
propagates to the native layer — leaving the LED physically lit.

Workarounds like AppState listeners or setting isActive={false} on
background suffer from the same race condition: by the time the JS event
fires and the native bridge delivers the new prop, the app may already be
suspended.

iOS is unaffected — the OS interrupts the capture session hardware-level,
which also cuts power to the torch.

Proposed API / solution

Add a boolean prop turnOffTorchOnBackground (default true) that, when
enabled, natively turns off the torch the moment the app backgrounds.

Native implementation:

  • Android: implement LifecycleEventListener in CameraView, turn off
    torch synchronously in onHostPause() before the JS thread is suspended.
  • iOS: subscribe to UIApplication.willResignActiveNotification and set
    device.torchMode = .off directly on the capture queue.

This approach is fully synchronous on the native side and does not depend
on the JS thread being responsive.

Example usage:

 <Camera
   device={device}
   isActive={isActive}
   torch={torchEnabled ? 'on' : 'off'}
   turnOffTorchOnBackground   // new prop, opt-out if needed
 />

Alternatives considered

  • AppState listener in JS (setTorchEnabled(false) on 'background') —
    unreliable due to JS thread suspension timing on Android.
  • Setting isActive={false} on background — same race condition; also
    re-initializes the full camera session on resume, which is heavier than
    just toggling the torch.
  • Imperative ref API (camera.current.setTorch('off')) — still JS-driven,
    doesn't solve the timing issue.

Platforms this should target

Android

Would you be willing to contribute this?

Maybe, with guidance.

Additional context

No response

Submission

  • I described the problem, not just the solution.
  • I wrote this request in my own words. I did not paste AI-generated proposals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✨ featureProposes a new feature or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions