Android XML (strings.xml): Complete Guide to Android Localization
Updated: December 05, 2025
What Are Android XML Files (strings.xml)?
Android XML strings files (strings.xml) are the standard localization format for Android applications. These XML files store all user-facing text in your app, allowing Android to automatically load the appropriate translations based on the user’s device language settings.
Android’s resource system uses a folder-based structure where each language has its own values directory containing localized string resources, making it straightforward to support multiple languages in your app.
Why AZbox Supports Android XML Format
At AZbox, we understand that Android is the world’s most popular mobile platform. That’s why AZbox fully supports Android XML file import and export, allowing you to:
- Import existing strings.xml files directly into your AZbox project
- Export translations back to Android XML format for use in your app
- Handle plurals and arrays with full plurals.xml support
- Manage translations with our powerful cloud-based platform
- Collaborate with translators who can work without Android Studio
- Update over-the-air without Google Play Store approval
Android Resource File Structure
Android uses a specific folder structure for localized resources:
app/
└── src/
└── main/
└── res/
├── values/ # Default (English)
│ ├── strings.xml
│ └── plurals.xml
├── values-es/ # Spanish
│ ├── strings.xml
│ └── plurals.xml
├── values-fr/ # French
│ ├── strings.xml
│ └── plurals.xml
├── values-de/ # German
│ ├── strings.xml
│ └── plurals.xml
├── values-pt-rBR/ # Brazilian Portuguese
│ ├── strings.xml
│ └── plurals.xml
└── values-zh-rCN/ # Simplified Chinese
├── strings.xml
└── plurals.xml
Folder Naming Convention
| Folder | Language/Region |
|---|---|
values | Default (fallback) |
values-es | Spanish |
values-fr | French |
values-de | German |
values-ja | Japanese |
values-zh-rCN | Chinese (Simplified, China) |
values-zh-rTW | Chinese (Traditional, Taiwan) |
values-pt-rBR | Portuguese (Brazil) |
values-en-rGB | English (United Kingdom) |
Basic strings.xml Structure
A typical Android strings.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- App name and basic strings -->
<string name="app_name">My Android App</string>
<string name="welcome_title">Welcome</string>
<string name="welcome_message">Welcome to our application!</string>
<!-- Action buttons -->
<string name="button_save">Save</string>
<string name="button_cancel">Cancel</string>
<string name="button_delete">Delete</string>
<!-- Error messages -->
<string name="error_network">Network error. Please try again.</string>
<string name="error_invalid_email">Please enter a valid email address.</string>
</resources>
XML Elements
| Element | Description |
|---|---|
<resources> | Root element containing all string resources |
<string> | Single string resource |
name attribute | Unique identifier for the string |
XML comments <!-- --> | Comments for translators (optional) |
String Formatting and Placeholders
Android strings support various formatting options for dynamic content:
Basic Placeholders
<resources>
<!-- String placeholder -->
<string name="greeting">Hello, %1$s!</string>
<!-- Integer placeholder -->
<string name="items_in_cart">You have %1$d items in your cart</string>
<!-- Multiple placeholders -->
<string name="order_summary">Order #%1$s: %2$d items, total: $%3$.2f</string>
<!-- Reordering placeholders for different languages -->
<string name="welcome_user">Welcome, %1$s! You have %2$d new messages.</string>
</resources>
Format Specifiers
| Specifier | Type | Example |
|---|---|---|
%s | String | "Hello, %s!" |
%d | Integer | "%d items" |
%f | Float/Double | "$%.2f" |
%1$s | Positional string | "Hello, %1$s!" |
%1$d | Positional integer | "%1$d items" |
%% | Literal percent | "%d%% complete" |
Usage in Kotlin/Java
// Kotlin
val greeting = getString(R.string.greeting, userName)
val summary = getString(R.string.order_summary, orderId, itemCount, total)
// Java
String greeting = getString(R.string.greeting, userName);
String summary = getString(R.string.order_summary, orderId, itemCount, total);
Pluralization with plurals.xml
Android handles pluralization through <plurals> elements:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="items_count">
<item quantity="zero">No items</item>
<item quantity="one">%d item</item>
<item quantity="two">%d items</item>
<item quantity="few">%d items</item>
<item quantity="many">%d items</item>
<item quantity="other">%d items</item>
</plurals>
<plurals name="days_remaining">
<item quantity="zero">Expires today</item>
<item quantity="one">%d day remaining</item>
<item quantity="other">%d days remaining</item>
</plurals>
<plurals name="messages">
<item quantity="one">You have %d new message</item>
<item quantity="other">You have %d new messages</item>
</plurals>
</resources>
Quantity Values
| Quantity | Description | Languages |
|---|---|---|
zero | Zero items | Arabic, Latvian, Welsh |
one | Singular | English, Spanish, German |
two | Dual form | Arabic, Welsh, Slovenian |
few | Few items | Russian, Polish, Czech |
many | Many items | Russian, Arabic, Polish |
other | Default (required) | All languages |
Usage in Kotlin/Java
// Kotlin
val itemsText = resources.getQuantityString(R.plurals.items_count, count, count)
val daysText = resources.getQuantityString(R.plurals.days_remaining, days, days)
// Java
String itemsText = getResources().getQuantityString(R.plurals.items_count, count, count);
String Arrays
For lists of related strings, use <string-array>:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="countries">
<item>United States</item>
<item>Canada</item>
<item>United Kingdom</item>
<item>Germany</item>
<item>France</item>
<item>Spain</item>
</string-array>
<string-array name="sort_options">
<item>Name (A-Z)</item>
<item>Name (Z-A)</item>
<item>Date (Newest)</item>
<item>Date (Oldest)</item>
<item>Price (Low to High)</item>
<item>Price (High to Low)</item>
</string-array>
</resources>
Usage in Kotlin/Java
// Kotlin
val countries = resources.getStringArray(R.array.countries)
val sortOptions = resources.getStringArray(R.array.sort_options)
// Java
String[] countries = getResources().getStringArray(R.array.countries);
Special Characters and HTML
Escaping Special Characters
<resources>
<!-- Apostrophe (escape with backslash or use HTML entity) -->
<string name="dont">Don\'t worry</string>
<string name="dont_alt">Don't worry</string>
<!-- Quotation marks -->
<string name="quote">He said \"Hello\"</string>
<string name="quote_alt">He said "Hello"</string>
<!-- Ampersand -->
<string name="terms">Terms & Conditions</string>
<!-- Less than / Greater than -->
<string name="comparison">5 < 10 > 3</string>
<!-- Newline -->
<string name="multiline">First line\nSecond line</string>
<!-- Tab -->
<string name="tabbed">Column1\tColumn2</string>
</resources>
HTML Formatting
<resources>
<!-- Basic HTML formatting -->
<string name="styled_text"><b>Bold</b>, <i>Italic</i>, <u>Underline</u></string>
<!-- Complex HTML (use CDATA for complex markup) -->
<string name="rich_content"><![CDATA[
<p>Welcome to <b>Our App</b>!</p>
<p>Click <a href="https://example.com">here</a> for more info.</p>
]]></string>
</resources>
Usage with HTML in Kotlin
// For simple HTML tags (b, i, u)
val styledText = getString(R.string.styled_text)
textView.text = Html.fromHtml(styledText, Html.FROM_HTML_MODE_COMPACT)
// In Jetpack Compose
Text(
text = AnnotatedString.fromHtml(getString(R.string.styled_text))
)
Translatable and Non-Translatable Strings
Mark strings that shouldn’t be translated:
<resources>
<!-- Translatable strings (default) -->
<string name="welcome">Welcome</string>
<!-- Non-translatable strings -->
<string name="app_id" translatable="false">com.example.myapp</string>
<string name="api_endpoint" translatable="false">https://api.example.com</string>
<string name="brand_name" translatable="false">AZbox</string>
<!-- Technical strings that shouldn't be translated -->
<string name="date_format" translatable="false">yyyy-MM-dd</string>
<string name="currency_format" translatable="false">$#,##0.00</string>
</resources>
Importing Android XML to AZbox
Step 1: Prepare Your Files
Organize your Android resource files:
res/
├── values/
│ ├── strings.xml
│ └── plurals.xml
├── values-es/
│ ├── strings.xml
│ └── plurals.xml
└── values-fr/
├── strings.xml
└── plurals.xml
Step 2: Import via AZbox Dashboard
- Log in to your AZbox dashboard
- Navigate to your project
- Go to Import/Export section
- Select Import and choose Android XML (strings.xml)
- Upload your XML files (you can upload multiple at once)
- AZbox will detect the language from the folder structure
Step 3: Review and Manage
After importing:
- View all strings organized by key
- See plurals with all quantity variants
- Edit translations with context awareness
- Add new languages instantly
- Use machine translation for missing strings
- Track completion percentage per language
Exporting Android XML from AZbox
When ready to use translations in your Android project:
- Go to Import/Export in your project
- Select Export and choose Android XML (strings.xml)
- Select target languages
- Choose whether to include plurals separately
- Download the generated files
- Copy to your app’s
res/values-XX/directories
Using Strings in Android
In XML Layouts
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/welcome_title" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_save" />
In Kotlin
// Activity/Fragment
val title = getString(R.string.welcome_title)
val greeting = getString(R.string.greeting, userName)
val items = resources.getQuantityString(R.plurals.items_count, count, count)
// With View Binding
binding.titleText.text = getString(R.string.welcome_title)
In Java
// Activity/Fragment
String title = getString(R.string.welcome_title);
String greeting = getString(R.string.greeting, userName);
String items = getResources().getQuantityString(R.plurals.items_count, count, count);
In Jetpack Compose
@Composable
fun WelcomeScreen() {
Column {
Text(text = stringResource(R.string.welcome_title))
Text(text = stringResource(R.string.greeting, userName))
Text(text = pluralStringResource(R.plurals.items_count, count, count))
}
}
Best Practices for Android XML
1. Use Descriptive Resource Names
Bad:
<string name="s1">Submit</string>
<string name="msg">Error occurred</string>
Good:
<string name="button_submit_form">Submit</string>
<string name="error_generic_message">An error occurred</string>
2. Organize with Prefixes
<resources>
<!-- Navigation -->
<string name="nav_home">Home</string>
<string name="nav_settings">Settings</string>
<string name="nav_profile">Profile</string>
<!-- Buttons -->
<string name="button_save">Save</string>
<string name="button_cancel">Cancel</string>
<string name="button_delete">Delete</string>
<!-- Errors -->
<string name="error_network">Network error</string>
<string name="error_server">Server error</string>
<!-- Labels -->
<string name="label_email">Email</string>
<string name="label_password">Password</string>
</resources>
3. Add Comments for Context
<resources>
<!-- Shown on the login screen, above the email input field -->
<string name="login_email_hint">Enter your email</string>
<!-- Button text for submitting the login form -->
<string name="login_button">Sign In</string>
<!-- Error shown when email format is invalid -->
<string name="error_invalid_email">Please enter a valid email address</string>
</resources>
4. Use Positional Parameters
Always use positional parameters (%1$s) instead of simple placeholders (%s) for better translation flexibility:
<!-- Bad: Translators can't reorder -->
<string name="file_info">%s - %s - %s bytes</string>
<!-- Good: Translators can reorder for their language -->
<string name="file_info">%1$s - %2$s - %3$s bytes</string>
5. Handle All Plural Forms
Different languages need different plural forms:
<!-- English (values/plurals.xml) -->
<plurals name="photos">
<item quantity="one">%d photo</item>
<item quantity="other">%d photos</item>
</plurals>
<!-- Russian (values-ru/plurals.xml) -->
<plurals name="photos">
<item quantity="one">%d фотография</item>
<item quantity="few">%d фотографии</item>
<item quantity="many">%d фотографий</item>
<item quantity="other">%d фотографий</item>
</plurals>
<!-- Arabic (values-ar/plurals.xml) -->
<plurals name="photos">
<item quantity="zero">لا صور</item>
<item quantity="one">صورة واحدة</item>
<item quantity="two">صورتان</item>
<item quantity="few">%d صور</item>
<item quantity="many">%d صورة</item>
<item quantity="other">%d صورة</item>
</plurals>
6. Keep Default Values Complete
Always have complete translations in your default values/strings.xml:
<!-- values/strings.xml (English - default) -->
<resources>
<string name="welcome">Welcome</string>
<string name="goodbye">Goodbye</string>
</resources>
<!-- values-es/strings.xml (Spanish) -->
<!-- If a string is missing, Android falls back to default -->
<resources>
<string name="welcome">Bienvenido</string>
<!-- "goodbye" will use English fallback -->
</resources>
Common Issues and Solutions
Issue: String Not Found
Problem: App crashes with Resources.NotFoundException.
Solution: Ensure the string exists in your default values/strings.xml file.
Issue: Placeholder Mismatch
Problem: App crashes when formatting string with wrong number of arguments.
Solution: Match the number of placeholders with arguments:
// strings.xml: <string name="info">%1$s has %2$d items</string>
// Wrong - missing second argument
getString(R.string.info, userName)
// Correct
getString(R.string.info, userName, itemCount)
Issue: Special Characters Breaking XML
Problem: XML parsing error due to unescaped characters.
Solution: Escape special characters or use CDATA:
<!-- Escape apostrophe -->
<string name="message">It\'s working!</string>
<!-- Use CDATA for complex content -->
<string name="html_content"><![CDATA[<b>Bold</b> & <i>Italic</i>]]></string>
Issue: RTL Language Layout Issues
Problem: Right-to-left languages (Arabic, Hebrew) display incorrectly.
Solution: Use start/end instead of left/right in layouts:
<!-- Bad -->
<TextView android:layout_marginLeft="16dp" />
<!-- Good - works with RTL -->
<TextView android:layout_marginStart="16dp" />
AZbox Android XML Features
When you import Android XML to AZbox, you benefit from:
- Automatic language detection - Detects locale from folder structure
- Plural form validation - Ensures all required quantities are present
- String array support - Manage arrays alongside regular strings
- Comment preservation - XML comments imported as context
- Placeholder highlighting - Visual markers for %s, %d, etc.
- Format validation - Ensures placeholders match across translations
- Translation memory - Leverage previous translations
- Machine translation - Fill gaps with AI-powered translation
- Over-the-air updates - Update without Google Play approval
- Team collaboration - Translators don’t need Android Studio
Conclusion
Android XML (strings.xml) is the foundational format for Android app localization, offering robust features for handling translations, pluralization, and dynamic content. With AZbox’s full Android XML support, you can:
- Import existing strings.xml files with all resources preserved
- Manage plurals and arrays alongside regular strings
- Support complex pluralization for all languages
- Export Android XML files ready for your Android project
- Update translations over-the-air without Play Store approval
Ready to streamline your Android localization workflow?
Start Your Free Trial | View Pricing
AZbox provides comprehensive support for Android XML format (strings.xml), making it the ideal localization platform for Android developers. Import, manage, and export your translations with ease.
Start Global Growth Today
Join hundreds of successful companies already using AZbox to reach customers worldwide. Start with a free trial, no credit card required.
Get Started - It's Free