13

I want to display a message to the user depending upon a prompt I receive from another part of the program. There can be a number of prompts & they are stored in an enum.

These are my prompts:

Defs.java

public enum Prompt
{
    PromptA,
    PromptB,
    PromptC,
}

I have the externalized strings stored in resources on these lines:

res/values/strings.xml

<string name="PromptA">Error in execution</string>
<string name="PromptB">Process completed successfully</string>
<string name="PromptC">Please try again</string>

Now in my main Activity screen a method is called by some other part:

public void showPrompt(Prompt prompt) {
    String message = getString(R.string.<**what-do-I-put-here?**>);
    //show a dialog box with message
}

I know this can be done with a huge if-else block (there are tons of prompts in the actual application) or a switch statement. It will be really ugly.

Is there a better way to do this?

OceanBlue
  • 9,142
  • 21
  • 62
  • 84
  • http://stackoverflow.com/questions/3538649/accessing-contents-of-r-string-using-a-variable-to-represent-the-resource-name/7189023#7189023 – ArK Aug 25 '11 at 10:47
  • @OceanBlue: Can't you use a [string array resource](http://developer.android.com/guide/topics/resources/string-resource.html#StringArray) indexed by `prompt.ordinal()`? Using `ordinal` is generally not recommended, as it may be fragile in case you reorder or add an item, but there are many more fragile things when using XML. – maaartinus Sep 16 '12 at 00:30

2 Answers2

24

See Resources.getIdentifier: http://developer.android.com/reference/android/content/res/Resources.html#getIdentifier%28java.lang.String,%20java.lang.String,%20java.lang.String%29 . You can try something like this:

public void showPrompt(Prompt prompt, String label) {
    String message = (String) getResources().getText(getResources().getIdentifier(label, "string", null));
    //show a dialog box with message
}

Try that out and see what that does for you.

EDIT: meh. Try this instead.

public void showPrompt(Prompt prompt, String label) {
    String message = (String) getResources().getText(getResources().getIdentifier(label, "string", "<application package class>"));
    //show a dialog box with message
}

Turns out you have to specify the your package identifier (so if your AndroidManifest.xml has com.blah.blah.blah as the Package put that in the third parameter.

Femi
  • 64,273
  • 8
  • 118
  • 148
  • 1
    Thanks for taking the time to answer. I did notice in the link that you've added: "*Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.*" So are the only choices in this fairly common situation, to write **inefficient** code or **ugly, unmaintainable** code. :-( Wish Google would add this capability to resources. – OceanBlue May 12 '11 at 16:24
  • 1
    It is *discouraged*, but not *deprecated*; driving fast is discouraged as well, but not deprecated :). It is definitely more efficient doing it by resource id, but if you have a few instances where you wish to look up id by string name this is provided for you. **If it was not to be used at all it would not have been provided**. Or you could write your massive switch statement: your choice. – Femi May 12 '11 at 16:35
  • 1
    Fair enough. At least this is an alternative to using the switch statement. – OceanBlue May 12 '11 at 18:38
  • 1
    Use context.getPackageName() for the package parameter. – Greg Sep 15 '17 at 09:19
  • This is a pretty good answer. I don't understand why it doesn't have more upvotes. – Vahid Amiri Dec 12 '18 at 09:12
0

What you could do is just enclose the line in a if/else if/else statement, or a switch.

String message;
switch(prompt) {
case PromptA:
    message = getString(R.string.PromptA);
    break;
case PromptB:
    message = getString(R.string.PromptB);
    break;
case PromptC:
    message = getString(R.string.PromptC);
    break;
default:
    message = "";
}

I'm not on the machine I usually develop on, so there may be some silly syntax error in there, but the logic 'should' work.

Leif Andersen
  • 21,580
  • 20
  • 67
  • 100
  • 2
    Yes this is exactly what I am doing, but as I mentioned in my question.. this is getting pretty big & ugly since there are so many prompts. Also, in future if a prompt is added, I'd rather not change the code, just the xml. – OceanBlue May 12 '11 at 15:58