whats the deal with
CharSequence contentTitle = R.string.value;
Error cannot convert from int to CharSequence. Is there a way around this or am i missing something?
i tried
String s = R.string.value + "";
CharSequence contentTitle = s;
it returns integers values.
Any help?
R.string.value is a call to the static field in the class R, which is auto generated by Eclipse and which does a kind of summary of all your resources. To retrieve the string, you need to use :
CharSequence contentTitle = getString(R.string.value);
If you open the R class you will see that it contains only numbers that are references to the compiled resources of your project.
To retrieve the string, you need to use getString(),
but getString() is a method from Context class.
If you want to use this method outside your Activity class, you should get link to your context first and then call:
String s = mContext.getString(R.string.somestring)
R.string.value returns the reference ID number of the resource 'value'. If you look at your R class it will appear as something like this:
public static final class string {
public static final int value=0x7f040007;
}
I've been experiencing issues with referencing the getString() method. The exact error that Eclipse spits at me is:
The method getString(int) is undefined for the type DatabaseHelper.MainDatabaseHelper
After reading for awhile I've figured out that you must reference your application's context to get access to the getString() method. I was trying to create a private SQLDatabase helper class in a content provider, however, that was not allowing me to reference the getString() method. My solution so far is to do something like this:
private class MainDatabaseHelper extends SQLiteOpenHelper {
MainDatabaseHelper(Context context) {
super(context, context.getString(R.string.createRoutesTable), null, 1);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL((getContext()).getString(R.string.createRoutesTable));
}
}
Notice these two context references:
context.getString()
(getContext()).getString()
I don't know if this is the optimal long-term solution but it seems to work for the moment. Hope this helps.
You could use String s = getResources().getString(R.string.value); also.
Related
I (having mediocre developing skills) actually try to use Sugar as a database wrapper for my android project.
Therefore, I was following along the "Getting-Started-Guide" (http://satyan.github.io/sugar/getting-started.html) to get ready as soon as possible.
I created a class for my entities, called DataSet.java :
import com.orm.SugarRecord;
public class DataSet extends SugarRecord{
int someData;
double evenMoreData;
public DataSet(Context ctx){
super(ctx);
}
public DataSet(Context ctx,
int someData,
long evenMoreData) {
super(ctx);
this.someData = someData;
this.evenMoreData = evenMoreData;
}
}
I call the class in the following way:
someGreatClass something;
someMoreGreatCode somemore;
DataSet dataSet = new DataSet(
ctx, // Here Eclipse throws the error
something.method(),
somemore.anothermethod());
DataSet.save();
When I try to build this and to push it onto my device, Eclipse refuses to compile and throws this error:
ctx cannot be resolved to a variable
Considering the fact that I'm relatively new to Android development, the error may be obvious and I hope to get a tip how to solve this.
P.S.: Furthermore, I don't fully get the developer's statement in the getting-started-Note:
Please retain one constructor with Context argument. (This constraint will be removed in subsequent release.)
Thank you very much!
// Edit: Did edit the class name from LocationDataSet to Data set for clarification
First of all, the getting-started-note tells you that you need a constructor with only a context parameter, you did this here so that's ok
public DataSet(Context ctx){
super(ctx);
}
about
ctx cannot be resolved to a variable
I think you don't have a variable called ctx, I don't know if you're familiar with android context? (basically a context is a service or an activity), if you're using this code in an activity or a service, just use the 'this' keyword and not the ctx variable
The code you provide doesn't really show what you're doing, but you showed us the code from 'DataSet', but the error happens with a LocationDataSet? And you're calling save on DataSet?
The save method must be called on an object, not a class.
Also don't forget that sugar needs the special application class in the manifest
UPDATE with example:
Your dataset class (the sugarrecord) should look like this, that's ok in your code as far as I can see
public class DataSet extends SugarRecord<DataSet>{
private String someData;
public DataSet(Context c){
super(c);
}
public DataSet(Context c, String someData){
super(c);
this.someData = someData;
}
}
An activity that uses the record should look like this
public class SomeActivity extends Activity {
public void someMethodThatUsesDataSet(){
// Create a dataset object with some data you want the save and a context
// The context we use here is 'this', this is the current instance of SomeActivity,
// you absolutely need this, I think this is what you're doing wrong,
// you can't use ctx here because that's not a known variable at this point
DataSet example = new DataSet(this, "data you want to save");
// Tell Sugar to save this record in the database
example.save();
}
}
I am trying to use getString() to get an String from resources to assign it to an String array before my activity is created:
private static final String[] MenuNames = {
Resources.getSystem().getString(R.string.LCMeterMenu),
Resources.getSystem().getString(R.string.FrecMenu),
Resources.getSystem().getString(R.string.LogicAnalyzerMenu),
"Prueba con achartengine",
Resources.getSystem().getString(R.string.BrazoMenu)
};
When I use Resources.getSystem().getString(R.string.LCMeterMenu), Eclipse doesn't complain but I get an error at runtime:
Caused by: android.content.res.Resources$NotFoundException: String Resource ID #0x7f0a000a
But if I put inside onCreate():
Log.i("StringR", "String: " + getString(R.string.LCMeterMenu));
I get the String but I can't assign it to the final String I defined before. If I use only getString() before onCreate() I get and static error message. How can I use resources before onCreate() for global variables?
You cannot initialize a static final field from resources; the field needs to be initialized at the time the class is initialized and that happens before the application resources have been bound at run time. (By the way, the reason you cannot use Resources.getSystem() is that the Resources object you obtain that way contains only system resources, not any application resources.)
If you need those strings available before the application resources are bound, the only practical thing to do is to put the strings into the code directly. However, the "Android way" would be to organize your code so initialization only needs to happen during (or after) onCreate(). Just initialize the string array in onCreate() and don't worry about making the fields static or final.
If you don't want the string array to be associated with a particular activity, then you can subclass Application and read the array from resources inside the application class's onCreate() method. (You also need to declare your custom application class in the manifest.) However, the docs recommend against such an approach. (Since the array is private, I suspect that it is closely tied to a single activity anyway, so the use of an Application subclass doesn't seem warranted.)
An alternative is to declare a singleton class for your array. The singleton accessor function then needs a Context so it can retrieve the resources if necessary:
public class StringArray {
private static String[] theArray;
public static String[] getArray(Context context) {
if (theArray == null) {
theArray = context.getResources().getStringArray(R.array.my_strings);
}
return theArray;
}
}
(This assumes the string data are defined in a <string-array> resource like #JaiSoni suggested in his answer.) Once again, the member field cannot be declared final.
No, you can't use Resources before onCreate(). You can get the instance of Resources in onCreate() by using getResources() where you can get all the Strings. Also the strings are already declared as static by defining them in the strings.xml.
Pseudo code for accessing the Resources,
Resources res = getResources();
String app_name = res.getString(R.string.app_name);
Another approach could be to initialize the static array with resource identifiers (which are already available as opposed to the resources themselves).
private static final int[] MenuNames = {
R.string.LCMeterMenu,
R.string.FrecMenu,
...
};
This way, you can defer the loading of resources to when they are actually available:
String s = getResources().getString(MenuNames[i]);
The following is a working approach to initialize static final variables in android from XML, such as strings.xml.
Subclass application and provide a "static context"
Register the application class in manifest
Use the static context to initialize your constants
1. MyApplication.java
public abstract class MyApplication extends Application {
private static Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
/**
* Returns a "static" application context. Don't try to create dialogs on
* this, it's not gonna work!
*
* #return
*/
public static Context getContext() {
return context;
}
}
2. AndroidManifest.xml
<application
android:name=".android.application.MyApplication"
<!-- ... -->
</application>
3. Your application code, e.g. Activity
private static final String[] MenuNames = {
getContext().getString(R.string.LCMeterMenu),
getContext().getString(R.string.FrecMenu),
getContext().getString(R.string.LogicAnalyzerMenu),
"Prueba con achartengine",
getContext().getString(R.string.BrazoMenu)
};
protected static Context getContext() {
return MyApplication.getContext();
}
For working examples refer to AbstractApplication and PreferencesServiceSharedPreferences.
Note that this approach also has its downsides:
Apart from being opposed to the "Android way" (as #Ted Hopp suggested in his answer),
it makes testing a bit difficult. That is why the call to MyApplication.getContext() is wrapped in another method. As it is a static method, overriding it in testing code is not simple. But you could use a framework such as Powermock for this purpose.
In addition it is a bit prone to NullPointerExceptions. As soon as the context is null (e.g. in your testing code) the application code crashes. One option to overcome this, is to do the initialization in a constructor, where you could react to getContext()returning null (see example).
Whatever you get by the getString(int resId) will already be a constant for your application. Why do you have to keep it in another final static variable. You can read it like that whenever you want, right?
Is there a way to use the getString method from a seperate class?
I have a string stored in my strings xml, I'd like to use that string in an object... but the method isn't even available in the object...
any tips?
getString() is a method of the Context class¹. If you need it inside a seperate class (that does not extend Context), it's usually best to provide it as a seperate argument to the method that needs it.
Example:
public void logString(Context c, int stringId) {
Log.d("TAG", c.getString(stringId));
}
One thing is important: Never store the context inside the separate class.
Provide an argument. Otherwise you will leak memory and disrupt the whole android lifecycle if the object that stores the context lives longer than the object where the context originally belongs to (e.g. an activity).
¹ getString() can also be used from the Resources class - which you can get via Context.getResources()
the solution here is to make sure your object has a reference to the application context
Class Swag{
private Context ctx;
public Swag(Context ctx){
this.ctx = ctx;
}
public void doSomething(){
String something = ctx.getResources().getString(R.string.somestring);
...
}
// or like this
public void makeUpperCase(Context appContext){
appContext.getResources().getString(R.string.super_string_swag_yolo);
}
}
obviously you'd have to supply the context when creating an object or when caling the method
resouce file: values/strings.xml
<resources>
<string name="app_name">App name</string>
<resources>
java
import android.content.res.Resources;
Resources.getSystem().getString(R.string.app_name);//result : App name
edit:
The below will NOT work. I read this on another site and assumed it worked, but I just tried it in my app and kept getting an error. Problem is, it will compile but you will get a runtime exception.
This will work from any java class:
import android.content.res.Resources
Resources.getSystem().getString(R.string.blah);
if you cannot pass a context as parameter, create another class, where you put all your static data.
example :
public class StaticData {
public static String BASE_URL = "https://stackoverflowrocks.com";
}
and get that string from your other class by calling directly
StaticData.BASE_URL
nice and clean.
This works, but for SYSTEM resources only:
import android.content.res.Resources
Resources.getSystem().getString(R.string.blah);
Reference: https://stackoverflow.com/a/40917607/8994882
Try this in your java file:
String myString = getResources().getString(R.string.MY_STRING)
Now use this string object.
i am working on an application where i have to get a value of string resource to a constant. how can i do that? any ideas please.
The String is placed in
Application/res/values/strings.xml
and the name of the resource is let say app_version. now i want to get this app version to a constant string in another file. Any help is appreciated.
Try context.getResources().getString(R.string.app_version) where 'context' is your Activity or Application instance.
If your question is really about getting the version name of your application there is a better way:
String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
This way you retrieve the info directly from the AndroidManifest and you don't have to maintain it twice.
In Java: R.string.string_name
In XML:#string/string_name
R.string.app_version or #string/app_version taken from strings.xml is your constant and will always represent the value you entered into that XML file.
http://developer.android.com/guide/topics/resources/string-resource.html
All responses here aren't up to date. This is the right way to do it.
Better to use
#StringRes
public class AndroidClass{
...
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab1, R.string.tab2, R.string.tab_2};
private final Context mContext;
...
public CharSequence getString(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
}
I wanted to do this as well, but upon reflection, I'm not sure this is possible. We are trying to set a value at compile time that is not available until run time.
Constants are set at compile time. Now, the resource ID is available then, but the value, which Android can change by locale, is not. Therefore, the string value is not available until runtime.
My workaround was to make a public static value, and assign it if it is null, to the string value at create time. I probably should've just used a plain old instance variable, but this works.
Although, you can overwrite the value.
public class MyFragment
...
public static String SHOW_FOO;
...
public View onCreateView(...
if (SHOW_FOO == null) {
SHOW_FOO = getResources().getString(R.string.settings_foo_key);
}
....
I have some information stored as SharedPreferences. I need to access that information from outsite an Activity (in from a domain model class). So I created a static method in an Activity which I only use to get the shared preferences.
This is giving me some problems, since apparently it is not possible to call the method "getSharedPreferences" from a static method.
Here's the message eclipse is giving me:
Cannot make a static reference to the non-static method
getSharedPreferences(String, int) from the type ContextWrapper
I tried to work around this by using an Activity instance, like this:
public static SharedPreferences getSharedPreferences () {
Activity act = new Activity();
return act.getSharedPreferences("FILE", 0);
}
This code gives a null point exception.
Is there a work-around? Am I going into an android-code-smell by trying to do this?
Thanks in advance.
Cristian's answer is good, but if you want to be able to access your shared preferences from everywhere the right way would be:
Create a subclass of Application, e.g. public class MyApp extends Application {...
Set the android:name attribute of your <application> tag in the AndroidManifest.xml to point to your new class, e.g. android:name="MyApp" (so the class is recognized by Android)
In the onCreate() method of your app instance, save your context (e.g. this) to a static field named app and create a static method that returns this field, e.g. getApp(). You then can use this method later to get a context of your application and therefore get your shared preferences. :-)
That's because in this case, act is an object that you just create. You have to let Android do that for you; getSharedPreferences() is a method of Context, (Activity, Service and other classes extends from Context). So, you have to make your choice:
If the method is inside an activity or other kind of context:
getApplicationContext().getSharedPreferences("foo", 0);
If the method is outside an activity or other kind of context:
// you have to pass the context to it. In your case:
// this is inside a public class
public static SharedPreferences getSharedPreferences (Context ctxt) {
return ctxt.getSharedPreferences("FILE", 0);
}
// and, this is in your activity
YourClass.this.getSharedPreferences(YourClass.this.getApplicationContext());
I had a similar problem and I solved it by simply passing the current context to the static function:
public static void LoadData(Context context)
{
SharedPreferences SaveData = context.getSharedPreferences(FILENAME, MODE_PRIVATE);
Variable = SaveData.getInt("Variable", 0);
Variable1 = SaveData.getInt("Variable1", 0);
Variable2 = SaveData.getInt("Variable2", 0);
}
Since you are calling from outside of an activity, you'll need to save the context:
public static Context context;
And inside OnCreate:
context = this;
Storing the context as a static variable, can cause problems because when the class is destroyed so are the static variables. This sometimes happens when the app is interrupted and becomes low on memory. Just make sure that the context is always set before you attempt to use it even when the class setting the context is randomly destroyed.
Here's a better alternative to storing your shared preferences in static fields.
Similar to what has been suggested here, create a class that extends Application
Make the constructor for your class take Context as a parameter.
Use your context to get shared preferences and store them in private variables.
Create public variables to return the retrieved data.
e.g
public class UserInfo extends Application{
private String SAVED_USERID;
private String SAVED_USERNAME;
public UserInfo(Context context) {
SharedPreferences prefs = context.getSharedPreferences(FILE, MODE_PRIVATE);
SAVED_USERNAME = prefs.getString("UserName", null);
SAVED_USERID = prefs.getString("UserID", null);
}
public String getSavedUserName() {
return SAVED_USERNAME;
}
public String getSavedUserID() {
return SAVED_USERID;
}
}
usage in your activity
UserInfo user = new UserInfo(this.getApplicationContext());
String SAVED_USERNAME = user.getSavedUserName();
String SAVED_USERID = user.getSavedUserID();
I had the same need - some of my preferences need to be accessed often, and efficiently. I also imagine that reading and writing a string from SharedPreferences is slightly slower than getting and setting a static variable (but likely to an insignificant degree). I also just kind of got used to using static fields, retrieving Preference values only at startup, and saving them on close.
I didn't love my options for keeping static references to the SharedPreferences/contexts directly, but so far this workaround has sufficed.
My solution:
Create a Settings class with all the static variables you need.
When the application initializes, retrieve SharedPreferences fields and immediately set all Settings fields (I call a "loadSharedPrefs()" method at the end of MainActivity's onCreate method).
In the SettingsActivity's preferenceChangeListener's initialization, set the appropriate static field in the Settings class. (I call a "setAppropriateSetting(key, value)" method at the beginning of SettingsActivity's onPreferenceChange()).
Use your static preferences wherever, whenever!
public static String getPreferenceValue(Context context) {
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
String key = context.getString(R.string.pref_key);
String defaultVal = context.getString(R.string.pref_default);
return sharedPreferences.getString(key,defaulVal);
}