25

I really don't know why but I can't retrieve the Id of a String.

This is my code:

int resId = getApplicationContext().getResources()
           .getIdentifier("About_EmailPrompt", "string", "com.yoki.android.cat");

But it works perfectly for all other classes of R file:

int resId = getApplicationContext().getResources()
           .getIdentifier("arrow","drawable", "com.yoki.android.cat");

So I really don't understand what's going on here, any ideas ?

David Snabel-Caunt
  • 57,804
  • 13
  • 114
  • 132
tchoupi
  • 251
  • 1
  • 3
  • 3

5 Answers5

19

This code looks like correct code:

int resId = getApplicationContext().getResources().getIdentifier("About_EmailPrompt", "string", "com.yoki.android.cat");

and it should work, but if not I advise you do not try to get around this and try to understand Why it doesn't work:

1) First of all try to find next declarated field in your project/projects:

About_EmailPrompt

if you are using eclips you should press Ctrl+H and open Java Search tab Java Search Dialog

If you get results for searching go to step 2 otherwise go to step 3

2) You should get result as hierarchy

<YOUR_PACKAGE_NAME>
    -- R
     -- string
         -- About_EmailPrompt

2.1) check you write correct package name in your code

.getIdentifier("About_EmailPrompt", "string", <YOUR_PACKAGE_NAME>);

2.2) check you use just latin symbols in your literal strings:

"About_EmailPrompt"

and

"string"

2.3) check you use just latin symbols in name attribute in strings.xml

<string name="About_EmailPrompt">SOME_VALUE</string>

3) If you have no search result

3.1) check you use just latin symbols in your literal string:

"About_EmailPrompt"

3.2) check you use just latin symbols in name attribute in strings.xml

<string name="About_EmailPrompt">SOME_VALUE</string>

3.3) Do clean and build for all projects you have

P.S. If this does not help you, try to restart your IDE (sometimes eclipse generate R.java incorrectly until restarting)

Igor Tyulkanov
  • 5,487
  • 2
  • 32
  • 49
  • Thank god i finally found someone who is able to do this. I could cry right now. THANKS – glace Apr 26 '16 at 08:41
9

As an alternative approach, you can use reflection:

R.string.class.getField("string_name").getInt(null);

Which essentially does the trick by getting a field of the class by name and then getting the integer value.

We pass null as the object because all the resources generated field are static and therefore not part of an object.

You may need to handle a few exceptions (NoSuchFieldException, etc) in case you made a typo, but it does work.

shalafi
  • 3,926
  • 2
  • 23
  • 27
5

I've managed to get a working solution in my app. So, based on the original question, you would need to change it as the following:

int resId = getApplicationContext().getResources()
           .getIdentifier("com.yoki.android.cat:string/About_EmailPrompt", null, null);

This is another way of writing the getIdentifier() method but it seems to work this way.

Kailas
  • 7,350
  • 3
  • 47
  • 63
Apqu
  • 4,880
  • 8
  • 42
  • 68
  • 1
    getIdentifier takes 3 arguments. The resource name, resource type and resource package. The last two arguments are optional. If the last two are not provided then the first argument has to include a full resource path. This means the following two are the same: `int resId = getApplicationContext().getResources() .getIdentifier("com.yoki.android.cat:string/About_EmailPrompt", null, null);` same as: `int resId = getApplicationContext().getResources() .getIdentifier("About_EmailPrompt", "string", "com.yoki.android.cat");` – LanDenLabs Apr 07 '17 at 15:06
0

You could create a method to replace all the getIdentifier-calls. Else you have to mix two different approaches, which makes the code a little bit unclear.

This approach is similar to @shalafi's solution and uses reflection.

public static int getResId(String variableName, Class<?> c) {

    try {
        Field idField = c.getDeclaredField(variableName);
        return idField.getInt(idField);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    } 
}

and use it like this:

getResId("About_EmailPrompt", R.string.class); //or for other things
getResId("icon", R.drawable.class);


If you use
public static int getResStringId(String variableName) {
    try {
        Field idField = R.string.getDeclaredField(variableName);
        return idField.getInt(idField);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    } 
}

it is even faster than getIdentifier() or the above solution. Source

Community
  • 1
  • 1
Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
-3

I've this functions:

public static int getDrawable(Context context, String name)
    {
        Assert.assertNotNull(context);
        Assert.assertNotNull(name);

        return context.getResources().getIdentifier(name,
                "drawable", context.getPackageName());
    }

    public static int getString(Context context, String name)
    {
        Assert.assertNotNull(context);
        Assert.assertNotNull(name);

        return context.getResources().getIdentifier(name,
                "strings", context.getPackageName());
    }

I think you should use strings instead of string

Pedro Rainho
  • 4,234
  • 1
  • 19
  • 21
  • 4
    No, "string" should be fine. This is what works for me: `int id = getResources().getIdentifier(key, "string", getPackageName());` – Twilite Feb 29 '12 at 11:31
  • 1
    Note that the identifier should be the same as how we refer to it. If it is `R.string.some_string`, then the second argument should be `"string"`, not `"strings"`. – Andrew T. May 28 '14 at 15:49
  • It actually has to be "string" not "strings". – AlBirdie Jun 26 '15 at 07:58