ChatGPT解决这个技术问题 Extra ChatGPT

Android: How do I get string from resources using its name?

I would like to have 2 languages for the UI and separate string values for them in my resource file res\values\strings.xml:

<string name="tab_Books_en">Books</string>
<string name="tab_Quotes_en">Quotes</string>
<string name="tab_Questions_en">Questions</string>
<string name="tab_Notes_en">Notes</string>
<string name="tab_Bookmarks_en">Bookmarks</string>

<string name="tab_Books_ru">Книги</string>
<string name="tab_Quotes_ru">Цитаты</string>
<string name="tab_Questions_ru">Вопросы</string>
<string name="tab_Notes_ru">Заметки</string>
<string name="tab_Bookmarks_ru">Закладки</string>

Now I need to retrieve these values dynamically in my app:

spec.setContent(R.id.tabPage1);
String pack = getPackageName();
String id = "tab_Books_" + Central.lang;
int i = Central.Res.getIdentifier(id, "string", pack);
String str = Central.Res.getString(i);

My problem is that i = 0.

Why does not it work in my case?

Are you certain that Central.lang is either en or ru?
More info is needed to inspect your code. what is the state of each var before getting i? Anyways, you should use the default localization support in Android to keep things simple.

佚名

The link you are referring to seems to work with strings generated at runtime. The strings from strings.xml are not created at runtime. You can get them via

String mystring = getResources().getString(R.string.mystring);

getResources() is a method of the Context class. If you are inside a Activity or a Service (which extend Context) you can use it like in this snippet.

Also note that the whole language dependency can be taken care of by the android framework. Simply create different folders for each language. If english is your default language, just put the english strings into res/values/strings.xml. Then create a new folder values-ru and put the russian strings with identical names into res/values-ru/strings.xml. From this point on android selects the correct one depending on the device locale for you, either when you call getString() or when referencing strings in XML via @string/mystring. The ones from res/values/strings.xml are the fallback ones, if you don't have a folder covering the users locale, this one will be used as default values.

See Localization and Providing Resources for more information.


If you're in an android.support.v4.app.Fragment, you can just call getString(R.string.mystring) directly.
I was just wodering. Why is it done (by google) in such a complicated way? First get numeric ID of mystring (from R object) and then getting the string by that ID? And where the pair "ID-of-mystring => actualValue" actually resides? As far as I know mystring=>ID-of-mystring is in R.java, but that is it :)
make sure that "R" is your project's R not the default android R.
This may be the answer that was needed but it wasn't the one that was asked for! For dynamically accessing a string resource by name, see the answer from @leonvian ... which should be the accepted one IMO
A
Andreas detests censorship

Verify if your packageName is correct. You have to refer for the root package of your Android application.

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }

In case someone has a good reason to do this (for example, data files contain a custom string that decides which resource string should be displayed, or if this string is fetched from the Internet) -- then I'd like to point out that this solution is the correct one. Especially correct the part where the resource type is string and not strings. Because that's logical (like the rest of the Android). So, thanks for that (and more), @leonvian. :-)
@Sameer to get a array by Strings just use: res.getStringArray(R.array.planets_array); Take a look at this oficial link: developer.android.com/guide/topics/resources/…
Cool. To get rid of a separate method declaration, this can be "simplified" in such a way: String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
Thanks! This is great solution when strings fetched from Internet. I'm implementing a chat, which can deliver system messages between devices. Devices may have different language and the message must me displayed in the receiving device language.
Don't forget to handle "Resources.NotFoundException" or you might run into problems later on.
g
ggorlen

Not from activities only:

public static String getStringByIdName(Context context, String idName) {
    Resources res = context.getResources();
    return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
}

T
TOUDIdel
getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))

M
Miguel Rivero

I would add something to the solution of leonvian, so if by any chance the string is not found among the resources (return value 0, that is not a valid resource code), the function might return something :

private String getStringResourceByName(String aString) {
    String packageName = getPackageName();
    int resId = getResources()
            .getIdentifier(aString, "string", packageName);
    if (resId == 0) {
        return aString;
    } else {
        return getString(resId);
    }
}

C
Community

Best Approach

App.getRes().getString(R.string.some_id)

Will work Everywhere (Utils, Models also).

I have read all the answers, all answers can make your work done.

You can use getString(R.string.some_string_id) in both Activity or Fragment.

You can use Context.getString(R.string.some_string_id) where you don't have direct access to getString() method. Like Dialog.

Problem

When you don't have Context access, like a method in your Util class.

Assume below method without Context.

public void someMethod(){
    ...
    // can't use getResource() or getString() without Context.
}

Now you will pass Context as a parameter in this method and use getString().

public void someMethod(Context context){
    ...
    context.getString(R.string.some_id);
}

What i do is

public void someMethod(){
    ...
    App.getAppResources().getString(R.string.some_id)
}

What? It is very simple to use anywhere in your app!

So here is a solution by which you can access resources from anywhere like Util class .

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static Resources resources;

    @Override
    public void onCreate() {
        super.onCreate();

        resources = getResources();
    }

    public static Resources getAppResources() {
        return resources;
    }

}

Add name field to your manifest.xml <application tag.

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Now you are good to go. Use App.getAppResources().getString(R.string.some_id) anywhere in app.


+1 simple & clean solution. Notice bad spelling getResourses, the getResources would cause override. Also the singleton pattern seems unnecessary, possibly could be skipped. Any memory leaks problems with this solution?
@Xarvalus Does this make memory leak?
in my app all fine :) just wondering if anyone had any problem with it. I will let know If I encounter any pitfall.
@Xarvalus Memory Leak usually occur at place where an variable is being used even parent class is destroyed. Like in Activities, Fragments. I don't think it will occur in this case.
E
Eren Yilmaz

Easier way is to use the getString() function within the activity.

String myString = getString(R.string.mystring);

Reference: http://developer.android.com/guide/topics/resources/string-resource.html

I think this feature is added in a recent Android version, anyone who knows the history can comment on this.


O
OneCricketeer

A simple way to getting resource string from string into a TextView. Here resourceName is the name of resource

int resID = getResources().getIdentifier(resourceName, "string", getPackageName());
textview.setText(resID);

H
Harshit Jain

getResources() works only when you're in Activity or Fragment class.

to get access to strings resource everywhere,

use:

Resources.getSystem().getString(android.R.string.somecommonstuff)

N
Nammen8

If you don't have an Activity reference, you can use your context in this way:

getContext().getString(R.string.your_string_name);

J
JCarlosR

In case you are using Kotlin, you can define an extension function as follows:

fun Context.getStringResourceByName(stringName: String): String? {
    val resId = resources.getIdentifier(stringName, "string", packageName)
    return getString(resId)
}

And then simply use it. For example, in a Puzzles app I set the Activity title according to the image file name:

val stringName = "${folderName}_${assetName.substringBefore(".")}"
title = getStringResourceByName(stringName)

In this example I am reading string resources based on dynamic names.


M
M.Muzammil

In Kotlin, Leverage Extension functions 😎

fun Context.getStringByName(name: String): String {
    return getString(resources.getIdentifier(name, "string", packageName))
}

f
forsberg

There is also a set of predefined Android strings such as "Ok", "Cancel" and many others - so you don't have to declare all. They're available simply by:

getString(android.R.string.ok)

(In this case, "Ok" string). BTW there are also other Android resources available like for example icons images etc.


A
Avinash

String myString = getString(R.string.mystring);

easy way


r
rohegde7

If you wannt get it inside an activity or fragmnet, then:

getContext().getResources().getString(R.string.string_name);

If you want to get it from a class outside of activity or fragment where you don't have the activity context then use application context:

getApplicationContext().getResources().getString(R.string.string_name);

M
M Shafaei N

You can try this in an Activity:

getResources().getString(R.string.your string name);

In other situations like fragments,... use

getContext().getResources().getString(R.string.your string name);

O
O Thạnh Ldt

To safe, you should add: mContext.getResources().getString(R.string.your_string);

mContext can be: context in onAttach() of Fragment or this of Activity.


O
Owais Yosuf
R.string.<string_name>

Use that line directly in your java file. Keep it simple.


This wouldn't work all the time. The String could end up being displayed as the address number.