Skip to content
StringLane

ANDROID STRINGS.XML

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.

Download for macOS

For macOS, Windows and Linux14-day trial, no email · $49 once

StringLane with a sample Android strings.xml project open: the cart_item_count plurals in six languages side by side, the Spanish card missing the many form and the Ukrainian card missing few and many, each marked CLDR-required

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 with zero, 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 &amp;
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.xml path
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 default values/ 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 as values-fr-rCA/ or values-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 to values-zh/.

    missing_key

  • Plural quantity coverage

    Each <plurals> element is checked against the categories its language actually requires, taken from CLDR. Ukrainian needs one, few, many and other. 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 with b+, such as values-b+sr+Latn/, owe the same forms as their language.

    missing_key

  • Format argument mismatch

    Arguments are compared by count and by the type each one is read as. A default string with %1$s and %2$d against a translation carrying one argument is flagged, and so is %d items against %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_mismatch

  • Same 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 &amp; and &lt; 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?
Yes. Each <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?
Your entities stay escaped, and CDATA content survives, though a block that is the whole value comes back escaped rather than re-wrapped, which Android resolves to the same string. <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?
Any path matching 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?
It is not a Gradle plugin, and your build is untouched. The desktop app reads and writes the files on disk. The free 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?
No account. The 14-day trial does not ask for an email address, but it checks with StringLane’s licence server at every launch, so it needs a connection. A licensed copy works offline. AI fill needs a connection only if you use it with your own API key.

Check your locales tonight.

Download for macOS

For macOS, Windows and Linux14-day trial, no email · The agent setup is free