Android getIdentifier doesn't work for string?
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 ?
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
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)
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.
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.
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
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
精彩评论