I ran into a situation where I wanted to be able to programmatically pull a
string from strings.xml
using a string for a key rather than an id.
In particular, I was creating my own abstraction of analytics tracking and I wanted to be able to programmatically translate the current Activity’s “screen name” for a Screen View event (in Google Analytics terminology) based on its class name.
Now granted if this were GA, GA has its own XML file for that for use with automatic screen tracking, but since I’m trying to abstract that functionality (for compatibility with other analytics packages) I’ve essentially written my own implementation for auto screen tracking.
In any case, what we need to do here is first translate a string into an id, then use the id to fetch the value of that string from the xml file back:
int id = getResource().getIdentifier("name", "string", getPackageName());
This will give us the id key for a string, "name"
in the strings.xml
file.
We can pass this id
into getString()
and return the value we’re looking for:
public String getStringByString(String key) {
String retString = key;
int id = getResource().getIdentifier(key, "string", getPackageName());
if (id != 0) {
retString = getString(id);
}
return retString;
}
I’d also like to point out a caveat in working with this. It is
documented that there are performance implications with
the getIdentifier()
method:
Return a resource identifier for the given resource name. A fully qualified resource name is of the form “package:type/entry”. The first two components (package and type) are optional if defType and defPackage, respectively, are specified here.
Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name
So I just want to be clear that although I am using it right now and I don’t see any visible performance issues, use of this method is discouraged.
On a side note, I have an idea in my head where I’d like to revise this technique to use a custom XML file where I can do lookups purely by string, or use some other format (JSON, YAML) that might be easier to parse. Not sure if that would be any better or worse, however.