ANDROID STRINGS.XML · macOS, WINDOWS, LINUX
An Android strings.xml editor for every values folder
StringLane loads values/, values-de/ and every other resource folder side by side, and checks each <plurals> against the quantities its language actually requires, while you are editing and not at build time.
For macOS, Windows and Linux14-day trial, no email · $49 once

Spanish needs many, Ukrainian few and many
THE FORMAT
What StringLane opens
Android keeps each language in its own resource folder, and the qualifier on the folder name is what selects it at run time. Plurals are a separate XML element with one entry per quantity, and the set of quantities a language needs is decided by CLDR rather than by you. StringLane reads the whole tree and shows every folder side by side.
- File layout
- One folder per language,
res/values-de/strings.xml - Plurals
<plurals>elements withzero,one,two,few,many,other- Placeholders
%s,%d, and positional forms such as%1$s- Preserved
- Key order,
<plurals>structure, and XML entities such as& - Position not preserved
- A
<string-array>is kept verbatim, but re-emitted below the strings and plurals, so it moves to the end of the file - Detected by
- Any
res/values*/strings.xmlpath - Project chip
XML
WHAT GETS FLAGGED
What gets flagged in an Android project
Validation runs when the project loads and again after every edit. These are the checks that apply to Android XML. The same checks run from the terminal with stringlane check, and over MCP for a coding agent.
Missing or empty per language
The
<string name="...">exists in your defaultvalues/folder and is absent or blank in another. Android falls back to the default resource, so the string still renders, in the wrong language. A regional folder such asvalues-fr-rCA/orvalues-b+es+419/owes only the strings it defines, because Android shows the parent language’s folder for the rest. The parent must be the same language in the same script:values-zh-rTW/does not fall back tovalues-zh/.missing_keyPlural quantity coverage
Each
<plurals>element is checked against the categories its language actually requires, taken from CLDR. Ukrainian needsone,few,manyandother. English needs two. A Ukrainian block carrying only the English pair is flagged as an error, and that is a structural defect you can act on without reading Ukrainian. Folders named withb+, such asvalues-b+sr+Latn/, owe the same forms as their language.missing_keyFormat argument mismatch
Arguments are compared by count and by the type each one is read as. A default string with
%1$sand%2$dagainst a translation carrying one argument is flagged, and so is%d itemsagainst%s Elemente, which crashes on Android in that language. This is checked per quantity inside a<plurals>block, as well as on flat strings.format_placeholder_mismatchSame as default, and guarded words
A value identical to the default
values/folder usually means it was copied and never translated. Terms you mark as guarded are flagged the other way, when a language changes something meant to stay fixed.untranslatedguarded_word_violation
What it will not do
ICU MessageFormat validation does not apply to Android XML and is switched off for it. Android expresses plurals through the <plurals> element rather than through ICU strings, so the ICU checks you would get on an ARB or i18next project are not run here. Plural coverage is still checked, through CLDR.
YOUR FILES
What survives a save, and what does not
StringLane edits your resource files in place. There is no export step and no intermediate spreadsheet. It rewrites a strings.xml from the <string> and <plurals> elements it read, transcribing everything else in the file verbatim, so it is worth knowing what that covers.
- Key order is preserved as it appears in the file.
<plurals>blocks keep their element structure, with one entry per quantity.- XML entities such as
&and<are kept escaped. <![CDATA[...]]>content survives, re-emitted escaped rather than re-wrapped. Android resolves both spellings to the same string.translatable="false"strings load as locked keys: visible in the list, excluded from the Issues panel and from AI, and written back with the attribute and the position they had.- Comments are kept. The one directly above a key is that key's description, editable in StringLane. Every other comment, a file header or a note above a
<string-array>, is written back as it was. <string-array>and any other element StringLane does not model are transcribed byte for byte and written back. They are re-emitted after every<string>and<plurals>, so on the first save they move to the end of the file.
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Shown on the cart icon badge. -->
<plurals name="cart_item_count">
<item quantity="one">%1$d item in your cart</item>
<item quantity="other">%1$d items in your cart</item>
</plurals>
<!-- Running total at the bottom of the cart. -->
<string name="cart_total">Total: %1$s</string>
</resources>YOUR TOOLCHAIN
Where it sits in an Android project
StringLane edits the XML files your Gradle build already merges. It is not a Gradle plugin, it does not run in your build, and it does not need to know about your module layout or your flavors. Resource merging behaves exactly as it did.
What it adds is timing. Your build reports on translation problems at build time and your release process reports them later still, or not at all. A <plurals> block short two categories for Ukrainian shows up here while you are editing the file, next to the other five languages that have the same gap.
Let your coding agent check the same files.
The free CLI reads the same values*/strings.xml files.
Read https://stringlane.app/docs/cli/agent-setup.md and set up StringLane for this project.Pay once for the app. The CLI is free.
Desktop app
$49once
- 14-day trial, no email, no card
- macOS, Windows and Linux
- 3 machines, updates in the major version
- Your own AI key, or a local model
Early-adopter price, $79 after launch.
CLI & agents
$0free
- Terminal, CI and MCP
- Claude Code, Cursor, Codex and 5 more
- No key, no activation
- Separate from the app licence
Lokalise starts at $144 a month (checked July 2026). StringLane sells no AI credits.
Android XML questions
Does it handle <plurals> properly?
<plurals> element loads as a multi-value entry with one row per quantity, and every language is checked against the quantities CLDR says it needs rather than against whatever the default folder happens to have.Will it strip my CDATA blocks or unescape my entities?
<string-array> elements, comments and anything else StringLane does not model are transcribed verbatim and written back; the one thing that changes is where they sit, since unmodelled elements are re-emitted after the strings and plurals.Which values folders does it find?
res/values*/strings.xml, so values/, values-de/, values-fr/ and the rest load side by side in one project. The unnamed values/ folder is read as English unless defaultFileLocale: in stringlane.yaml names another language.Is this a Gradle plugin or something that runs in CI?
stringlane CLI runs the same checks in CI: stringlane check . exits 1 when a locale is broken, so a pull request can fail on it. Nothing about your project changes if you stop using either.Do I need an account or an internet connection?
Read before you download
Android strings.xml format
Plurals, numbered format arguments and escaping, and what builds broken.
Format-specific editing
What changes per format, including Android
strings.xml.Reading validation badges
What each badge means and how to clear it.
Fixing placeholder mismatches
Reading the badge tooltip and restoring a dropped
%1$s.Adding a language
Adding a new
values-*folder from a preset.Key descriptions and limits
Writing the
<!-- -->above a key from inside the editor.
Shipping an Android app and a web front end from one repo is common. Both formats open in the same window, with the same missing-key view across them.
i18next JSON editorCheck your locales tonight.
For macOS, Windows and Linux14-day trial, no email · The agent setup is free