Your old phone is mounted in the corner of the shop, recording. It is connected to the shop's Wi-Fi — the icon is there, full bars. And at the end of the month the mobile bill on that phone is higher than it has ever been, on a handset nobody carries and nobody uses.
The Wi-Fi is connected. The Wi-Fi is just not, as far as Android is concerned, working.
This is one of the most common and least explained situations in a phone-as-camera setup, and it is almost always the same thing: the network has a captive portal — the sign-in page that shops, hostels, guesthouses, cafés, offices and apartment buildings put in front of their Wi-Fi. Android has a specific, documented opinion about networks like that, and once you know what the opinion is, the behaviour stops being mysterious and becomes something you can plan around.
Why does my phone security camera use mobile data when it is connected to Wi-Fi?
Because "connected to Wi-Fi" and "this Wi-Fi can reach the internet" are two different facts, and Android tracks them separately. A network behind a sign-in page is connected but not validated, and Android's default routing prefers a network that is validated. So anything on the phone that wants the internet — including a live stream going out to YouTube — can quietly go out over mobile data instead, while the Wi-Fi sits there looking perfectly healthy.
The part that matters for a camera: this does not affect a live view that is served from the phone itself. Background Camera RemoteStream runs a small web server on the phone, so when you open the camera's address from a laptop or another phone on the same Wi-Fi, that traffic never needs the internet at all. It never leaves the local network. A captive portal can block the path to the outside world and leave the path across the room completely untouched.
That split — local works, outbound does not — is the whole story, and the rest of this piece is why.
Android tracks two separate bits, and most people only know about one
When Android connects to a network, it records a set of capabilities for it. Two of them are doing the work here.
The first is NET_CAPABILITY_INTERNET. The reference page describes it in a single sentence: it indicates that the network "should be able to reach the internet." Note the word should. Android's own connectivity guide is blunter about it — this capability is, in its words, "about setup and not actual ability to reach public servers," and a network can carry it and still "be subject to a captive portal."
The second is NET_CAPABILITY_VALIDATED, and this is the one that reflects reality. It means connectivity on the network "was successfully validated" — Android actually probed it and something answered. The Read network state page states the consequence directly: a network behind a captive portal "doesn't have this capability."
The class documentation for NetworkCapabilities puts the pair together in a line worth keeping: a network "may or may not actually provide connectivity," and apps that care about real connectivity "should usually look at both these capabilities."
So the shop Wi-Fi your camera phone is sitting on has the first bit and not the second. It is set up to reach the internet. It cannot currently reach the internet. Both are true, and the Wi-Fi icon shows you neither.
There is a third capability in play too: NET_CAPABILITY_CAPTIVE_PORTAL, which Android sets when a network "was found to have a captive portal in place last time it was probed." That phrase — last time it was probed — is doing quiet work, and we will come back to it.
What Android does about it
Once a network is unvalidated, Android has to decide where your traffic actually goes, and this is where the mobile bill comes from.
Every app has a default network, and the connectivity guide says plainly that it "is determined by the system," that the system "typically prefers unmetered networks to metered ones and faster networks to slower ones," and — the sentence to underline — that "the network that is set as the default network can change at any time."
A Wi-Fi network that failed validation is not a good candidate for carrying internet traffic, because as far as the system can tell it does not carry internet traffic. Mobile data, which validated fine, is. So the default moves.
Nothing on the phone announces this. There is no error, no dropped connection, no state the app can show you. The recording keeps recording. The Wi-Fi stays connected. Traffic that needs the outside world simply leaves by a different, metered door.
Android does surface the situation once, to the user, through ACTION_CAPTIVE_PORTAL_SIGN_IN — the "sign in to network" notification. The ConnectivityManager reference describes the trigger as a device that "has connected to a network that has presented a captive portal," one "which is blocking Internet connectivity." That notification is the system's one and only attempt to get a human involved.
On a phone that is mounted in a corner with its screen off and nobody looking at it, that notification is seen by no one.
The part I did not expect: you cannot ask for a network that works
This is the detail that reframed the whole problem for me, and it is sitting in plain sight in the ConnectivityManager reference.
You would reasonably assume that an app which needs real internet could simply ask for one — build a NetworkRequest that says give me a network that is validated and not behind a portal, hand it to requestNetwork, and let the platform sort it out. The API looks like it is shaped for exactly that. requestNetwork will "attempt to find the best network that matches the passed NetworkRequest" and will even try "to bring up one that does if none currently satisfies the criteria."
It does not work, and the documentation says why. It is, in the reference's words, "presently unsupported to request a network with mutable NetworkCapabilities" — capabilities that describe states a network "may never attain," because the framework "does not know how to go about satisfying a request with these capabilities."
Validation is mutable. Captive-portal status is mutable. They change based on what happens out on the network, not on anything the device controls. So they cannot go into a request.
You can only read those bits off a network you already have. There is no way to ask the system for the Wi-Fi that works. There is only connecting, finding out, and reacting. Every app on the phone is in the same position, which is worth knowing before you assume yours is broken: this is not a limitation any camera app chose.
And the platform is explicit that it stays in charge regardless — network selection is made "at its own discretion," and a network that no longer matches any request "may be disconnected at any time."
The "Ignore" button is a bigger decision than it looks
Somebody sets the camera up, the sign-in notification appears, they are busy, they dismiss it. On many builds, dismissing that prompt is not a neutral act.
The CaptivePortal class exists so the sign-in screen can tell the system how things went, and one of its two meaningful methods is ignoreNetwork(). The documentation describes it as the case where "the user does not want to pursue signing in to the captive portal," and then states two consequences. The system "should continue to prefer other networks without captive portals" — that is the mobile-data preference, now made sticky. And: "The system will not retest the network for a captive portal."
It will not retest. So even after somebody signs the network in later from a different device, or the portal is removed entirely, that phone may go on treating that Wi-Fi as second-class.
The other method is the way back: reportCaptivePortalDismissed(), after which "the framework will re-evaluate the network's connectivity and might take further action." That is what a successful sign-in triggers. If you are in the "everything looks connected and nothing works" state, forgetting the network and rejoining it from scratch is the crude version of the same thing, and it is usually the fastest fix available from the glass.
The two-network test
Here is a check you can run in a few minutes, on any phone, with no app-specific knowledge and nothing to install. Call it the two-network test. Its whole purpose is to separate the camera is broken from the internet path is broken, which are constantly mistaken for each other.
- Set the camera up where it will actually live, on the Wi-Fi it will actually use. Start recording.
- On the camera phone, turn mobile data off entirely. Leave Wi-Fi on. You have now removed the escape route, so anything that still works is genuinely working over that Wi-Fi.
- From a second device on the same Wi-Fi — a laptop, another phone — open the camera's local address and confirm you get a picture. If you do, the recorder, the Wi-Fi association and the local path are all healthy. This is the half that a captive portal does not touch.
- Now, on the camera phone, open any browser and load a site you have never visited from that phone. If a sign-in page appears instead, that network has a portal. If the page simply fails, the network has no working internet at all.
- Turn mobile data back on only if you actually want it on. On a metered or prepaid plan, consider leaving it off for the life of the camera.
Step 5 is the one that saves money, and it is the one people skip. A camera phone that has no mobile data cannot spend mobile data. If the only thing you need from it is a live view on the same Wi-Fi and files stored locally, it does not need a working internet connection at all — and turning the radio off converts a silent, open-ended cost into a known zero.
Where this bites hardest
Some of this is specific to how you are set up, and it is worth being direct about which situations actually suffer.
A shop, a stall, a workshop, a guesthouse, a shared building. These are exactly the networks that run portals, and they are also exactly the places where a spare phone as a camera makes the most sense. The portal is not a misconfiguration; it is the point. Someone wants a tap-through before customers get online.
Prepaid and metered data. If the phone has a SIM with credit on it, an unvalidated Wi-Fi turns that credit into the fallback path for anything outbound. The cost is invisible until the balance is gone, because nothing failed — traffic was carried, successfully, by the expensive radio.
Anything going out to the internet. Streaming to YouTube Live genuinely needs real, validated internet; a portal blocks it and no local architecture can rescue that. If outbound streaming is the reason you set this up, the portal is a real blocker and the answer is a network without one.
Local-only setups are barely affected. If what you want is an offline security camera — recording to the phone, viewed from across the room or across the building on the same Wi-Fi — a captive portal is mostly a non-event. The live view is served by the phone. The recordings are on the phone. Neither one asks the internet for permission. That is a consequence of the architecture rather than a feature anyone added: when there is no cloud in the path, there is no cloud outage, no account check, and nothing that stops working because a sign-in page is in the way.
The practical setup order
If you are putting a phone camera on a network you do not control, this order will save you an evening:
- Join the Wi-Fi and complete the sign-in page first, on the camera phone itself, before you mount anything. Do not dismiss the notification.
- Then decide about mobile data. Off is the safe default for a camera. On is a choice you should make deliberately, knowing it is the fallback path.
- Then run the two-network test, so you know which half of the system works before you need it to.
- Prefer a network without a portal if you have the option — a home router, or a phone hotspot you control. Portals are built for humans with screens who tap things, and a mounted camera is neither.
None of this requires changing how the camera works. It requires knowing that Android is making a routing decision on your behalf, based on a bit you cannot see, on a network you did not configure.
If you want to go further on the adjacent failure modes: what actually happens to a phone camera during a power cut or an internet outage covers why those two are not the same event; live view stopped, recording did not walks the three reasons the stream goes and the files keep coming; and if outbound streaming is what you are after, streaming to YouTube Live from an Android phone with the screen off runs that whole path end to end.
Background Camera RemoteStream records with the screen off, stores everything locally on the device, and serves its live view from a web server running on the phone itself — so the across-the-room path does not depend on the internet being reachable.
- Google Play: https://play.google.com/store/apps/details?id=com.superfunicular.digicam
- Site: https://superfunicular.com
Documentation references throughout are to Android's public developer documentation, linked inline. The behaviour described is platform behaviour and applies to any app on the device, not only to ours.
Top comments (0)