android
string.xml
read values
android development
resource management

how to read value from string.xml in android?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Android externalizes user-facing text into res/values/strings.xml so that strings are easy to translate, reuse, and maintain. The build system generates an R.string class with integer IDs for each entry, and the framework provides several methods to resolve those IDs into actual string values. This article covers basic string definitions, formatted strings, plurals, string arrays, and how to access resources from different Android contexts.

Defining Strings in strings.xml

The resource file lives at res/values/strings.xml. Each <string> element has a name attribute that becomes the generated constant in R.string.

xml
1<resources>
2    <string name="app_name">Codemia</string>
3    <string name="welcome_message">Welcome back!</string>
4    <string name="login_button">Sign In</string>
5</resources>

Names must be valid Java identifiers: lowercase letters, digits, and underscores. Avoid spaces or hyphens.

Reading Strings in an Activity or Fragment

Any class that extends Activity or Fragment has access to getString() through its inherited Context.

kotlin
1// In an Activity
2val appName = getString(R.string.app_name)
3
4// In a Fragment
5val welcome = getString(R.string.welcome_message)

In Java the call is identical:

java
String appName = getString(R.string.app_name);

The returned value is a plain String with all XML escaping resolved.

Using Strings in XML Layouts

Reference string resources directly in layout attributes with the @string/ prefix:

xml
1<TextView
2    android:layout_width="wrap_content"
3    android:layout_height="wrap_content"
4    android:text="@string/welcome_message" />
5
6<Button
7    android:layout_width="match_parent"
8    android:layout_height="wrap_content"
9    android:text="@string/login_button" />

This approach keeps layouts free of hardcoded text and enables the layout preview in Android Studio to display localized strings.

Formatted Strings with Placeholders

Use standard java.util.Formatter placeholders to inject dynamic values:

xml
<string name="greeting">Hello, %1$s! You have %2$d new messages.</string>

Resolve the placeholders with getString():

kotlin
val text = getString(R.string.greeting, "Alice", 5)
// Result: "Hello, Alice! You have 5 new messages."

The %1$s syntax means "first argument, formatted as a string." The %2$d means "second argument, formatted as a decimal integer." Always use positional notation (%1$, %2$) rather than bare %s so that translators can reorder arguments for different languages.

Quantity Strings (Plurals)

Android provides <plurals> for strings that change based on a quantity:

xml
1<plurals name="unread_count">
2    <item quantity="one">%d unread message</item>
3    <item quantity="other">%d unread messages</item>
4</plurals>

Read the plural with resources.getQuantityString():

kotlin
val count = 3
val text = resources.getQuantityString(R.plurals.unread_count, count, count)
// Result: "3 unread messages"

The first count selects the plural form; the second count fills the %d placeholder. The supported quantity values are zero, one, two, few, many, and other. Which forms are used depends on the language: English only uses one and other, while Arabic uses all six.

String Arrays

For lists of related strings, use <string-array>:

xml
1<string-array name="planets">
2    <item>Mercury</item>
3    <item>Venus</item>
4    <item>Earth</item>
5    <item>Mars</item>
6</string-array>

Read the array in code:

kotlin
1val planets: Array<String> = resources.getStringArray(R.array.planets)
2for (planet in planets) {
3    Log.d("Planet", planet)
4}

String arrays are commonly used to populate Spinner and ListView adapters without writing additional code.

Accessing Strings from Non-Activity Classes

Classes that do not extend Activity or Fragment need a Context reference to access resources.

kotlin
1class NotificationHelper(private val context: Context) {
2    fun buildTitle(): String {
3        return context.getString(R.string.app_name)
4    }
5}

In a ViewModel, use AndroidViewModel which receives the application context:

kotlin
class MainViewModel(application: Application) : AndroidViewModel(application) {
    val title: String = getApplication<Application>().getString(R.string.app_name)
}

Avoid passing Activity references into long-lived objects like singletons or ViewModels, because the activity can be destroyed while the reference is still held, causing a memory leak. Always prefer applicationContext for long-lived components.

Accessing Strings from a Service or BroadcastReceiver

Both Service and BroadcastReceiver are subclasses of Context, so getString() is available directly:

kotlin
1class MyService : Service() {
2    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
3        val msg = getString(R.string.welcome_message)
4        // use msg
5        return START_NOT_STICKY
6    }
7}

Common Pitfalls

  • Hardcoding strings instead of using resources. Lint warns about this with the HardcodedText inspection. Hardcoded strings cannot be translated and make refactoring harder.
  • Using bare %s instead of positional %1$s. Translators in some languages need to reorder arguments; bare format specifiers break when arguments are swapped.
  • Editing the wrong locale file. Translated strings live in res/values-<locale>/strings.xml (for example values-es for Spanish). Changes in the wrong folder will not appear for that locale.
  • Holding an Activity context in a long-lived object. This prevents garbage collection of the destroyed activity. Use applicationContext for singletons, repositories, and ViewModels.
  • Expecting resource changes without rebuilding. After renaming or deleting a string resource, the R class must be regenerated by rebuilding the project. Stale references cause compile-time errors.

Summary

  • Define all user-facing text in res/values/strings.xml and reference it through R.string constants.
  • Use getString(R.string.name) in Activity, Fragment, Service, or any class with a Context reference.
  • Use positional format specifiers (%1$s, %2$d) for dynamic values so that translators can reorder arguments.
  • Use <plurals> for quantity-dependent strings and <string-array> for ordered lists of strings.
  • Always pass applicationContext rather than an Activity reference to long-lived components to avoid memory leaks.

Course illustration
Course illustration

All Rights Reserved.