What you are seeing
The code works on an iPhone yet fails on Android phones, or works on some Android phones and not others. This split almost always comes from differences in how the code is decoded: the built-in camera app, the decoding library, the payload format, or the way the phone handles the action the code requests. Android is not one identical camera, so test on more than one Android device before you conclude anything. The fix is to make the payload use the most standard, widely supported format rather than a format that only one platform tolerates.
Likely causes
1.
Non-standard payload format — Some payloads use a format variant that one platform parses leniently and another rejects, such as an unusual WiFi, contact, or calendar encoding. Test: decode the payload and check it against the standard field layout for that payload type.
2.
Android camera app lacks built-in scanning — Some Android camera apps do not scan QR codes natively, so the phone appears to fail when it simply never tried. Test: open a dedicated scanner app on the same Android phone; if that scans it, the camera app is the gap.
3.
Payload action handled differently on Android — An action such as joining WiFi, saving a contact, or opening an app can be supported on one platform and blocked or handled differently on the other. Test: note what happens after the banner appears; if Android shows the banner but the action fails, the action handling differs.
4.
Encoding problem with special characters — Accented characters, symbols, or a wrong character encoding can decode cleanly on one platform and garble on another. Test: decode the payload on both platforms and compare the text character by character.
5.
Camera focus or lens behaviour on that Android model — Some Android models struggle with close focus or with glare in a way that looks like a code failure. Test: try the same Android phone on other codes and try a different distance.
Step-by-step fix
1. Decode the payload and write down exactly what it contains, including every field and separator.
2. Rebuild the payload in the standard format for its type, using the generator for that type rather than hand-typing the format.
3. Test on two different Android phones, using both the built-in camera and a scanner app.
4. Simplify any special characters in the payload and retest.
5. Confirm the action the code requests works on Android, and offer a typed fallback next to the code.
6. Retest on iPhone to confirm you did not break the platform that worked.
Putting this into practice
In practice, the reliable cure is to stop hand-crafting payloads and use the purpose-built generator for each type. Hand-typed WiFi, contact, and calendar payloads are where the cross-platform differences hide. A generator produces the standard layout that both platforms expect, and a two-phone test catches anything it misses. Keep a short note of what you tested, what failed, and what you changed, so the next person starts from evidence rather than guesswork. A fix that is written down survives staff changes and reprints; a fix that lives only in memory gets repeated.
Common mistakes to avoid
- Testing on a single Android phone and concluding that all Android phones behave the same way.
- Reprinting the full run before a single proof passes, which turns one failure into many.
- Testing on one phone in ideal conditions instead of two phones in the real conditions where a code that scans on iPhone but not Android will be used.
- Changing the artwork and the placement at the same time, so you cannot tell which change fixed a code that scans on iPhone but not Android.- Skipping the proof test because the change looked small, when small changes cause most repeat failures.
Quick checklist
- The payload uses the standard format for its type
- The code scans on two different Android phones
- The action after the scan works on Android, not just the preview
- The corrected proof passes on two phones in the real conditions
- The fix is recorded in the job file so the next reprint starts from a proven setup
- Every printed copy is checked against the approved proof
- The proof is retested after any later change to the link, design, or placement
Related tools and guides
- [QR payload inspector](/qr-payload-inspector)
- [QR offline verifier](/qr-offline-verifier)
- [QR scanner](/qr-scanner)
- [QR size calculator](/qr-size-calculator)
- [QR safety checker](/qr-safety-checker)
- [blog](/blog)