Why a QR Code Scans on iPhone but Not on Android — featured illustration
Technology

Why a QR Code Scans on iPhone but Not on Android

5 min read
Create a QR code

The symbology is standardized but decoder effort is not: nothing tells a reader how many frames to try or where to set the threshold between dark and light, so a marginal code reads on the more forgiving one and stalls on the other. Android also has no single scanning path, since the stock camera, the manufacturer's own software, Google Lens and third-party apps can each take the job. In practice the answer is almost always that the code is marginal or the scanning feature is switched off, not that the phone is incompatible.

A visitor at your booth raises an iPhone and the page opens before the phone is even level. The person standing beside them holds an Android phone at the same card, same light, same distance, and gets nothing for fifteen seconds. Then they shrug and walk away.

Nothing about the printed code changed between those two attempts. What changed is everything that happens after light hits the sensor: how the image is turned into dark and light pixels, which piece of software gets to try, and what the phone decides to do with the string it recovers.

A decoder is not one piece of software

The symbology itself is standardized. Modules, finder patterns, timing patterns, error correction at roughly 7, 15, 25 and 30 percent for levels L, M, Q and H, versions 1 through 40, a quiet zone of four modules. Every decoder agrees on all of that.

What is not standardized is effort. Nothing tells a decoder how many frames to try before giving up, where to set the threshold that splits gray pixels into dark and light, how much perspective skew to correct, or whether to retry at a different threshold when the first pass fails. Those are implementation choices, and they differ between vendors and between versions of the same product.

The practical result: a marginal code reads on one phone and stalls on another, and both devices are behaving correctly. If your code is slightly small for the scan distance, or ink spread has thickened the dark modules, or the contrast is weaker on paper than it looked on screen, you are relying on the more forgiving decoder. The iPhone in that story did not prove the code is fine. It proved that one decoder tolerates the flaw. The mechanics of that read are covered in how QR codes work.

Android is not one camera app

On the Android side there is no single scanning path. Depending on the device and the OS version, the code might be read by the stock camera app, by a scanning feature the manufacturer added to its own camera software, by Google Lens, by a tile in the quick settings tray, or by a third-party app the owner installed. Some of those paths are on by default. Some sit behind a toggle in camera settings. Some appear only in a particular mode.

Do not assume any of this from the brand on the back of the phone. Behavior varies by model, by OS version and by carrier build, and it changes with updates. The only claim that holds up is that the same physical code can meet several different decoders on Android, and one of them may be weaker than the rest.

So test instead of guessing:

  • Open the stock camera app, point at the code, and wait ten seconds without moving the phone.
  • If nothing happens, look in the camera settings for a scanning or smart-suggestion toggle and turn it on.
  • Try Google Lens, or the quick settings scanner tile if the device has one.
  • Try a dedicated scanner app as a control. If the dedicated app reads the code and the camera app does not, the symbol is marginal rather than broken.

Have the person walk through how to scan a QR code before you conclude the print is at fault. A meaningful share of "Android cannot read it" reports turn out to be a scanning feature that was never switched on.

The scan may have succeeded without the user noticing

Implementations also differ in how they surface a result. Some show a persistent button anchored to the code in the viewfinder. Some show a banner that fades after a couple of seconds. Some need a tap on the detected region before anything opens.

If your tester glanced away at the wrong moment, or a notification was suppressed while the phone sat in a focus mode, the decode happened and the handoff did not. Ask what appeared on screen, not just whether the link opened.

A payload nobody has a handler for

Here the platforms genuinely split. A plain https URL has a handler on every phone. Other payloads do not:

  • Custom app schemes fail when the app is not installed. One platform may show a "cannot open" alert, another may do nothing visible at all.
  • Wi-Fi network payloads are handled by the operating system, and support has varied across OS versions.
  • geo, tel, sms and mailto payloads depend on an app being registered for them. A phone with nothing registered has nowhere to send the user.

Encode a plain https URL and let the landing page do the handoff. A page can offer an app link, a store link and a web fallback in a way the code itself cannot. With a dynamic QR code you can also repoint that destination after the cards are printed, which matters on the day a deep link stops working.

The browser you land in is not always the default browser

Scanning from inside a social or messaging app usually opens that app's built-in browser rather than the user's default. The built-in browser keeps its own cookies and has its own limits, so a session created in the main browser is not there, and some page features may not run.

Two people can decode identical data and see different pages. When the report is "it works on iPhone and shows a broken page on Android", the decode is fine and the problem lives in the destination.

Diagnose in this order

  1. Reproduce with a dedicated scanner app on the failing phone. If that reads it, the symbol is readable and the issue is device software or payload.
  2. Read the decoded string, not just the outcome. Confirm it is the URL you expect and that it starts with https.
  3. Compare the printed size against the distance people actually scan from. A code that only reads at 10 cm on a poster meant for two meters is undersized, not incompatible.
  4. Check the error correction level if the surface gets handled or scuffed. Codes built here always carry the highest of the four, so there is nothing to raise, but a code that came from somewhere else may be sitting at the lowest: error correction levels covers what each one buys.
  5. Only after those four, work through the full troubleshooting list.

Print one test card at the size you plan to use, hand it to three Android phones from three different makers, and send the file to the printer only when all three read it from the distance a customer will be standing at.

Share this article