Change value of R.string programmatically

I had a situation like this, where one of my strings.xml values had some dynamic piece of it. I set up the strings.xml with a "replacement text" (something like %%REPLACEMENT_EMAIL%%), and when I wanted to use that string programatically, I retrieved the string value of the resource, and replaced instances of that replacement text with the dynamic value (e.g. input by the user).

To be honest, my app has not been localized yet, but I'm still attempting to follow best practices w.r.t. not hardcoding any strings.


One thing what you have to understand here is that, when you provide a data as a Resource, it can't be modified during run time. For example, the drawables what you have in your drawable folder can't be modified at run time. To be precise, the "res" folder can't be modified programatically.

This applies to Strings.xml also, i.e "Values" folder. If at all you want a String which has to be modified at runtime, create a separate class and have your strings placed in this Class and access during run time. This is the best solution what I have found.


example howto:

how? by changing one variable reference to other reference

usage:

setRColor(pl.mylib.R.class,"endColor",pl.myapp.R.color.startColor);
// override app_name in lib R class  
setRString(pl.mylib.R.class,"app_name",pl.myapp.R.string.app_name);

base methods:

public static void setRColor(Class rClass, String rFieldName, Object newValue) {
    setR(rClass, "color", rFieldName, newValue);
}

public static void setRString(Class rClass, String rFieldName, Object newValue) {
    setR(rClass, "string", rFieldName, newValue);
}

// AsciiStrings.STRING_DOLAR = "$";
public static void setR(Class rClass, String innerClassName, String rFieldName, Object newValue) {
    setStatic(rClass.getName() + AsciiStrings.STRING_DOLAR  + innerClassName, rFieldName, newValue);
}

helper methods :

public static boolean setStatic(String aClassName, String staticFieldName, Object toSet) {
    try {
        return setStatic(Class.forName(aClassName), staticFieldName, toSet);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}

public static boolean setStatic(Class<?> aClass, String staticFieldName, Object toSet) {
    try {
        Field declaredField = aClass.getDeclaredField(staticFieldName);
        declaredField.setAccessible(true);
        declaredField.set(null, toSet);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

@bradenV2 My app is supporting many languages , so I wanted to take a string from my strings.xml that's currently in use and change that , and then use that one – atuljangra Mar 12 '12 at 22:04

ps the above solution is good for example when u want to inject some data in already compiled lib/jar. But if u want localize strings just make folder under res per LANG CODE like values-CC where cc is lang code (values-de,values-cs) etc

then u have 2 choices:

  1. "build in" system dependent language selection - based on device selected lang
  2. via create resources for configuration - you decide which lang show

like this:

configuration = new Configuration(resources.getConfiguration());
configuration.setLocale(targetLocale);
String localized = Context.createConfigurationContext(configuration)
    .getResources()
    .getString(resourceId);

enter image description here


I don't think you can programmatically customize the R class as it is built by ADT automatically.