Short answer: No — on Android, one app holds a given camera at a time, and the tie-break is not first-come-first-served. It is priority, and priority follows the screen. If a phone is quietly recording as a security camera and someone unlocks it and opens the camera app, the system hands the lens to the app in front and your recorder receives an
onDisconnectedcallback. That is documented, intended behaviour, not a crash and not a bug, and no app can opt out of it. Below: the exact mechanism quoted from Android's own reference documentation, the five distinct ways a camera can be taken away from a running app, what recovery is actually guaranteed (less than you think), and six things the documentation does not say.
If you run a phone as a camera — mine or anyone's — this is the failure mode that produces the most confusing bug reports, because nothing crashes, no error dialog appears, and the app that lost the camera is often not the app the user was touching.
Can two apps use the same Android camera at the same time?
Short answer: not through any public API. There is no supported way for two third-party apps to hold the same camera simultaneously. Android's camera2 package does have a concurrency API, but read what it is actually for — CameraManager.getConcurrentCameraIds() returns combinations of cameras that can be configured at once, and the reference is explicit about the boundary:
"The devices in these combinations can be concurrently configured by the same client camera application. Using these camera devices concurrently by two different applications is not guaranteed to be supported, however."
— CameraManager, Android API reference
That is one app driving two cameras (front and back, say), not two apps sharing one. For the case people actually mean — my recorder and your video call, same lens, same second — the platform's answer is that somebody loses.
Background Camera RemoteStream records with the screen off and keeps footage on the device, and it is bound by exactly this rule like everything else on the platform. Which is why the honest setup advice, at the end of all the engineering, is a camera phone nobody picks up.
What happens when another app opens the camera while my app is recording?
Short answer: your app is evicted, and it is told after the fact. The winner is decided by priority, and the documentation states the rule plainly in the openCamera() description:
"As of API level 23, devices for which the
AvailabilityCallback.onCameraUnavailable(String)callback has been called due to the device being in use by a lower-priority, background camera API client can still potentially be opened by calling this method when the calling camera API client has a higher priority than the current camera API client using this device. In general, if the top, foreground activity is running within your application process, your process will be given the highest priority when accessing the camera, and this method will succeed even if the camera device is in use by another camera API client. Any lower-priority application that loses control of the camera in this way will receive anCameraDevice.StateCallback.onDisconnected(CameraDevice)callback."
— CameraManager, Android API reference
Read the middle sentence again, because it is the whole article: if the top, foreground activity belongs to your process, you get the highest priority. Not the app that asked first. Not the app with the foreground service. Not the app with the persistent notification. The app the human is looking at.
There is a second clause in the same paragraph that surprises people who have never hit it:
"Opening the same camera ID twice in the same application will similarly cause the
CameraDevice.StateCallback.onDisconnected(CameraDevice)callback being fired for theCameraDevicefrom the first open call and all ongoing tasks being dropped."
An app can evict itself. If your service holds camera 0 and some other component in the same process opens camera 0 again — a preview screen, a poorly guarded retry, a second instance after a config change — the first handle is disconnected and its ongoing work is dropped. This is a common self-inflicted version of the bug and it looks identical from the outside.
The rule in one sentence
Android arbitrates the camera by priority, priority tracks user focus, and the losing app is notified rather than consulted.
That design is correct for a phone: the thing on screen is the thing the person wants. It is a bad fit for a device sitting on a shelf recording a driveway, where the whole point is that nobody is holding it. The platform has no "this device is furniture" mode — and building one would mean letting a background app outrank the person in front of the screen, which is exactly the power you would not want any other app to have.
Eviction is a handoff, not a fault
The onDisconnected docs are worth reading closely, because the tone of them tells you how routine this is:
"The method called when a camera device is no longer available for use. ... Any attempt to call methods on this
CameraDevicewill throw aCameraAccessException. The disconnection could be due to a change in security policy or permissions; the physical disconnection of a removable camera device; or the camera being needed for a higher-priority camera API client. There may still be capture callbacks that are invoked after this method is called, or new image buffers that are delivered to active outputs. The default implementation logs a notice to the system log about the disconnection."
— CameraDevice.StateCallback, Android API reference
Three things fall out of that paragraph.
It is not an error. onDisconnected is separate from onError. The default behaviour is a log line. The platform is telling you that being evicted is an ordinary event in the life of a camera client, ranked alongside somebody unplugging a USB webcam.
There is a tail. "There may still be capture callbacks that are invoked after this method is called, or new image buffers that are delivered to active outputs." Frames can arrive after the disconnect notice. If your teardown assumes the pipeline stops the instant the callback fires, you will write those frames into a file you have already decided to finalise — a good way to produce a recording that is technically present and practically broken. The file-level version of that failure — and the two fixes for it — is covered in Why an Interrupted Android Recording Won't Play (moov Atom, Scoped Storage, and Two Fixes).
Nobody is required to tell the user. A log notice is not a notification. From outside the phone, an evicted 24/7 camera looks exactly like a working one until you go looking for the footage.
Five ways a camera gets taken away
onError carries exactly five documented codes, and they describe genuinely different situations. All five descriptions below are quoted from CameraDevice.StateCallback:
| Constant | What the reference says | In practice |
|---|---|---|
ERROR_CAMERA_IN_USE (1) |
"the camera device is in use already ... This error can be produced when opening the camera fails due to the camera being used by a higher-priority camera API client." | You tried to open and lost the priority contest. |
ERROR_MAX_CAMERAS_IN_USE (2) |
"The system-wide limit for number of open cameras has been reached, and more camera devices cannot be opened until previous instances are closed." | Not about your app at all — a device-wide ceiling. |
ERROR_CAMERA_DISABLED (3) |
"the camera device could not be opened due to a device policy." | A device admin or work profile turned cameras off. |
ERROR_CAMERA_DEVICE (4) |
"the camera device has encountered a fatal error. The camera device needs to be re-opened to be used again." | Reopen and carry on. |
ERROR_CAMERA_SERVICE (5) |
"the camera service has encountered a fatal error. The Android device may need to be shut down and restarted to restore camera function, or there may be a persistent hardware problem." | The bad one. |
Note the asymmetry that trips people up: ERROR_CAMERA_IN_USE is what you get when you try to take the camera and lose. onDisconnected is what you get when you had it and lost it. They are the two sides of one event, and if you only handle the error path you will never see the eviction.
There is also a sixth way to lose the camera that produces no callback at all, and it is the nastiest of the set.
The quick-settings camera toggle: not an error, a blank feed
Android 12 and higher ship a device-wide camera kill switch in Quick Settings. What does an app see when a user flips it? The documentation is unambiguous, and it is not what most developers assume:
"The camera and microphone toggles affect all apps on the device: When the user turns off camera access, your app receives a blank camera feed."
— Explain access to more sensitive information, Android developer guide
No exception. No error code. No disconnect. The capture session stays up, the encoder keeps encoding, the file keeps growing, the live view keeps streaming — and every frame is blank. A monitoring app in this state is healthy by every internal measure it has and useless by the only measure that matters.
The same page notes that when a user "launches an app that needs access to camera or microphone information, the system reminds the user that the device-wide toggle is turned off." That covers launching. It says nothing about an app that was already running when the toggle flipped, which is the exact case for an unattended camera.
What recovery is actually guaranteed
Less than you would like. The prescribed cleanup:
"You should clean up the camera with
CameraDevice.closeafter this happens, as it is not recoverable until the camera can be opened again. For most use cases, this will be when the camera again becomes available."
— CameraDevice.StateCallback
So: close the handle, then wait for a chance to reopen. Android gives you a hint for when to try, AvailabilityCallback.onCameraAccessPrioritiesChanged(), added in API level 29 — and the reference is refreshingly honest about how weak a hint it is:
"An application that was previously denied camera access due to a higher-priority user already using the camera, or that was disconnected from an active camera session due to a higher-priority user trying to open the camera, should try to open the camera again if it still wants to use it. Note that multiple applications may receive this callback at the same time, and only one of them will succeed in opening the camera in practice, depending on exact access priority levels and timing."
— CameraManager.AvailabilityCallback, Android API reference
"Only one of them will succeed in opening the camera in practice" is the design being candid. Recovery is a race you re-enter, not a queue you hold a place in. The practical shape of a correct implementation is: handle onDisconnected, close, register the availability callback, retry on the hint with backoff, and treat every reopen as something that can fail again immediately. And notice what is missing from all of the above — any statement about how long the gap will be.
What the documentation does not tell you
The most useful part of reading primary sources carefully is noticing the shape of the holes. Six, specifically:
-
The priority levels are never enumerated. The strongest statement anywhere is "In general, if the top, foreground activity is running within your application process, your process will be given the highest priority." There is no table, no ordering, no rule for how two foreground apps rank against each other.
onCameraAccessPrioritiesChangeddeliberately hedges with "depending on exact access priority levels and timing." - A camera-typed foreground service is never claimed to confer camera priority. The foreground-service documentation is about permission and lifecycle. Nothing in it says your service outranks anything for camera access, and it would be easy to assume otherwise.
-
No eviction latency is specified. There is no documented bound between a higher-priority
openCamera()and the loser'sonDisconnected(). - No retry policy or timing guarantee exists for reopening. "For most use cases, this will be when the camera again becomes available" is the entirety of the guidance.
-
The camera toggle is never connected to any error code.
ERROR_CAMERA_DISABLEDis documented as being about device policy and links only toDevicePolicyManager.setCameraDisabled(). Nothing ties the Quick Settings toggle to a callback. The only documented app-visible effect is the blank feed. - There is no documented third-party path to sharing a camera between two apps. The concurrency API is scoped to one client application, and cross-app concurrency is described as "not guaranteed to be supported" — which is a statement about guarantees, not a promise that it sometimes works.
Where a doc is silent, an app that behaves as if the silence were a guarantee will eventually be wrong on somebody's phone. That is a large part of why we publish the limits rather than the marketing version.
What this means if you're running a phone as a camera
The practical consequences are mostly about people, not code.
The threat is a human hand, not a background process. The three most common ways a 24/7 recording ends are: someone opens the stock camera app, someone opens a QR or document scanner inside a banking, payments or messaging app, and someone takes a video call. All three are foreground activities, so all three win.
Dedicate the device. This is the single highest-value setup decision and it is free. A phone used as a camera should be a phone that nobody uses as a phone. The counterpart problem — what Android does to an app you never open — is its own trap, covered in Android hibernation, permission auto-reset, and the one toggle that prevents both.
Check the footage, not the notification. A persistent notification proves a service is alive. It does not prove the service still holds the camera, and with the privacy toggle flipped it does not even prove the frames aren't blank. Once a week, open a recent file and look at it.
If a household shares the phone, say so out loud. Whoever picks up the camera phone to scan a payment code has ended the recording for as long as they hold it, and possibly longer if the app's retry loses the race. That is a conversation, not a settings change.
On the developer side, the checklist is short and unforgiving: implement onDisconnected as a first-class path rather than an error case; close the device before retrying; expect frames after the disconnect notice; guard against opening the same camera ID twice in your own process; register onCameraAccessPrioritiesChanged and treat it as a hint; and surface the gap to the user rather than hiding it, because a recording with a hole in it that you know about is worth more than one you don't.
Honest limitations of our own app
Background Camera RemoteStream obeys every rule above. It cannot outrank the foreground app, it does not get advance warning of eviction, and it cannot detect a blank feed caused by the device-wide camera toggle any better than the platform allows — a blank frame is a valid frame as far as the pipeline is concerned. What it can do is what any correctly built camera client can do: hold a camera-typed foreground service so that the screen turning off is not itself an eviction, handle the disconnect path deliberately, and reopen when the camera comes back. The rest is the platform's decision, and the platform's decision is the right one for phones.
Related reading
- How an Android Phone Keeps Recording Video With the Screen Off: Foreground Services, Camera2, and the OS Fighting You — the process-lifecycle layer underneath this one.
- One Camera, Two Consumers: Why Recording and Live-Streaming at the Same Time Depends on Your Phone's Camera2 Hardware Level — what one app can do with one camera, and where the hardware caps it.
- Why Does My Android Camera Stop Recording When the Screen Turns Off? Doze, WorkManager, and the Right Way to Build a Foreground Service — the other big class of silent stoppage.
- How an Android Phone Serves Its Own Live Camera Feed Over Your LAN: An Embedded Ktor Server Deep-Dive — what happens to viewers when the capture side drops out.
- What Happens to a Phone Security Camera During a Power Cut or an Internet Outage? — the other two failure domains, and why they are opposites.
Background Camera RemoteStream — record with the screen off, watch it live over your own network, keep the footage on the phone. No account, no cloud, no subscription.
- Google Play: https://play.google.com/store/apps/details?id=com.superfunicular.digicam&utm_source=devto&utm_medium=article&utm_campaign=2026w34
- Website: https://superfunicular.com/?utm_source=devto&utm_medium=article&utm_campaign=2026w34
Built in Kotlin on Camera2 with an embedded Ktor server, across 75+ AI-assisted development sessions. If you've hit the eviction path in your own app and found a recovery pattern that holds up on real devices, the comments are the right place — that part is underdocumented for everyone.
Top comments (0)