In my Android application I have to use common string value for all activities. "commonValue" is the common string value that I want to use in all activities. Relevant code of the main activity like this :
public class TestActivity extends Activity {
public String commonValue;//THE COMMON STRING FOR ALL ACTIVITIES
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
commonValue = "DemoValue";
}
}
In my next activity I created an object of "TestActivity" class and tried to assign "testValue" string to another string named "str"
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testlist);
TestActivity obj = new TestActivity();//OBJECT OF MAIN ACTIVITY
String str = obj.commonValue;
}
but the "str" value in second activity does not equal to the value assigned in my first activity. Why is that & How can I do this?
Thanks!
Put your value in string.xml
<string name="common_value">DemoValue</string>
and use in any activity like this..
String common_value = getApplicationContext().getString(R.string.common_value);
Start using SharedPreferences in your app.
In your first activity you would do
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("commonValue", "DemoValue");
editor.commit();
In your second activity
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String str = settings.getString("commonValue", null);
Try this -
TestActivity.java
public class TestActivity extends Activity {
public static String commonValue;//THE COMMON STRING FOR ALL ACTIVITIES
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
commonValue = "DemoValue";
}
}
another activity
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.testlist);
String str = TestActivity.commonValue;
}
If the value is always the same you can create a public static final variable and access it via TestActivity.COMMON_VALUE.
If you want to pass around a value between to Activities you should use Intents and add an extra with the value you want to pass.
As Sana has suggested, use SharedPreferences.
Alternatively, use a global constant class. If you want to stick with what you have, then you could try:
String str = TestActivity.this.commonValue;
Your existing code is creating a new instance of the activity, so it's not going to have the value you had set.
To pass data between activities use Bundle. and methods,
intent.putExtra()
and If you want to set data to be global to your app, then create an application class, and save the data there.
We have an Application file for each app you can declare the variable there and as the Application file can get from any activity so using the public getter setter and can get/set that
there are vaious oter metjod you can sue as mention on developer.android http://developer.android.com/resources/faq/framework.html
Singleton class
A public static field/method
A HashMap of WeakReferences to Objects (almost same as my above solution )
Persistent Objects
take a look on them as well
The reason why commonValue doesn't equal what you set in TestActivity onCreate method is because that function hasn't been called yet.
The solution for this is already mentioned by others. Like putting the value in a bundle.
Related
I have this class where I save the data and where the method loadUsername() is.
public class Settings extends AppCompatActivity {
EditText username;
static String string_username;
static SharedPreferences string_savepoint;
SharedPreferences.Editor string_editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
username = (EditText) this.findViewById(R.id.username);
//Speicher und Savepoint initialisieren
string_savepoint = getSharedPreferences("Data", Context.MODE_PRIVATE);
string_editor = string_savepoint.edit();
//Username laden
username.setText(loadUsername());
}
#Override
protected void onPause() {
super.onPause();
// Username speichern
string_editor.putString("username", username.getText().toString());
string_editor.commit();
}
protected static String loadUsername() {
// Aus dem Speicher
string_username = string_savepoint.getString("username", "Spieler");
return string_username;
}
Then I want to load the username in a another class.
Settings.loadUsername();
Actually this works but only if I have been in this class. If I start the app and go directly to the Activty where I wanna load the username I get this error:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String android.content.SharedPreferences.getString(java.lang.String, java.lang.String)' on a null object reference
at com.example.stefano.mathgame.Settings.loadUsername(Settings.java:43)
at com.example.stefano.mathgame.Game.gameSuccess(Game.java:151)
at com.example.stefano.mathgame.Game.onClick(Game.java:102)
Do you have any ideas?
I think that the best way to avoid those kind of problem in future is to use this library.
compile 'com.pixplicity.easyprefs:library:1.4'
All you need to do is to add a class to your project which extends Applications like this one below:
public class PrefsApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize the Prefs class
new Prefs.Builder()
.setContext(this)
.setMode(ContextWrapper.MODE_PRIVATE)
.setPrefsName(getPackageName())
.setUseDefaultSharedPreference(true)
.build();
}
}
and then you can simply read and write any value from the shared preferences without taking care of initialise it at the right moment (which caused your null point exception).
For read value from the shared preferences just do this:
Prefs.getString(key, default value)
and for saving values:
Prefs.putString(key, string)
You can not use this static method like this. Your string_savepoint will be initialized only when your activity Settings starts. If you try to use this static method without starting your activity you will get this Null pointer exception.
If you need to load the username from other code sections it will be best practice to create a some helper class to work with shared preferences, initialize it by passing it application context and than call its methods to save and load the username. This way the functionality of handling the persistence of the username will not be bind to an activity, which should be responsible for UI.
Add these two lines
static SharedPreferences string_savepoint;
string_savepoint = getSharedPreferences("Data", Context.MODE_PRIVATE);
in those activities from where you wish to call Settings.loadUsername();
I am new to Android and I am trying to handle the settings according to the instructions in
http://developer.android.com/guide/topics/ui/settings.html
I used the fragment based solution as the one directly in the activity was deprecated:
public class SettingFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
}
public class SettingsActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingFragment())
.commit();
}
}
The settings are correctly displayed in the app, yet when I try to retrieve their values with:
sharedPref= PreferenceManager.getDefaultSharedPreferences(Dashboard.dashboard);
startDayTime=sharedPref.getString(SettingsActivity.day_switch_start, "");
startNightTime=sharedPref.getString(SettingsActivity.night_switch_start, "");
it complaints that values day_switch_start and night_switch_start might not be resolved. In fact, when I explode the values recognized by SettingActivity, I get a long list of capitalized strings part of the standard settings, but not my own strings.
Those were in fact just entered in the xml file and linked from the SettingFragment, so I doubt context Dashboard.dashboard I passed has any reference to it. Yet there are no instructions on how to pass the settings references to a specific context and moreover they say that the settings should be available from anywhere. I am stuck, any solution?
Thanks,
Please check the reference you linked again, especially the Reading Preferences section. When you set the preference key to, e.g., day_switch_start then you must use the same String when reading the preference, e.g.,
startDayTime=sharedPref.getString("day_switch_start", "");
You can also store the preference key to a constant like in the linked example:
public class SettingsActivity extends PreferenceActivity {
public static final String KEY_PREF_DAY_SWITCH_START = "day_switch_start";
// ...
and then access it when reading the preference:
startDayTime=sharedPref.getString(SettingsActivity.KEY_PREF_DAY_SWITCH_START, "");
Edit: I'm not sure what Dashboard.dashboard should represent but this should work:
sharedPref= PreferenceManager.getDefaultSharedPreferences(this);
I'm writing a simple photo gallery app. I want people to scroll through the images and have the ability to add them to a 'favorites' list.
I have constructed a Favorite class that's global (put the class in a cGlobal class that defines it as static).
Now I have this working and I want to be able to save the state of the favorite -- the idea is as follows:
When the app first starts up, it will load the favorites list from the preferences in the main activity.
In the gallery activity it will save the favorite state in the preferences.
It seems like when I load the preferences form the main activity it comes up as null. But I can read what I write to it in the gallery activity. I have the following test code:
In main Activity, when the app starts:
//////////////////////////////////////////////////////////////////////////////////
public class MainActivity extends cBaseView implements OnClickListener {
/** Called when the activity is first created. */
String tr;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// load in favrets from prefences
SharedPreferences pre=getPreferences(MODE_PRIVATE);
// This does not work and tr is equal to no value.
tr=pre.getString("label","no value");
// add listeners
///////////////////////////////////////////////////////////////////////////////
Gallery Activity
public void onCreate(Bundle savedInstanceState) {
// test code
SharedPreferences pre=getPreferences(MODE_PRIVATE);
pre.edit().putString("label","ted").commit();
// tr is set to ted, got the data
tr=pre.getString("label","no value");
}
When you use getPreferences, here is what you get, according to the javadoc of activity :
Retrieve a SharedPreferences object for accessing preferences that are
private to this activity. This simply calls the underlying
getSharedPreferences(String, int) method by passing in this activity's
class name as the preferences name.
You should getSharedPreferences with the same name, to get preferences shared by different activities.
I have application with an activity and a service, I need to save some value in the activity and retrieve in the service.
i could save the value using SharedPreferences in the activity, however, when I try to retrieve the value in the BroadcastReceiver, it says getPreferences is undefined for service.
how could I retrieve my value in BroadcastReceiver?
EDITED to reflect change of the original question from Service to BroadcastReceiver.
Instead of using getPreferences(int mode) in the Activity use...
getSharedPreferences(String name, int mode).
The getPreferences(int mode) method is a convenience method for the above and simply passes the Activity class name as the name parameter. This implies it should really only be used for a given Activity to store its own internal preferences and not preferences that need to be global to other app components.
In the case of a BroadcastReceiver the onReceive(...) method is passed a Context parameter so you can use context.getSharePreferences(<some_name>, <mode>) to get the SharedPreferences saved by the Activity.
public class AndroidWalkthroughApp4 extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onResume() {
// get EditText object
EditText editText = (EditText)this.findViewById(R.id.edit_text);
// get preferences object
SharedPreferences prefs = this.getPreferences(MODE_PRIVATE);
// set text to our saved value
editText.setText(String.valueOf(prefs.getInt("chars", 0)));
// don't forget to do this, or your app will crash!
super.onResume();
}
#Override
public void onPause() {
// get EditText object
EditText editText = (EditText)this.findViewById(R.id.edit_text);
// get preferences object
SharedPreferences prefs = this.getPreferences(MODE_PRIVATE);
// create editor from preferences object
SharedPreferences.Editor editor = prefs.edit();
// save and write length of EditText
editor.putInt("chars", editText.getText().length());
editor.commit();
// don't forget this either!
super.onPause();
}
}
I want to have an "option" set before the Activity is created or at least before it starts. If there is a way to do this via the AndroidManifest? Consider this example where we have a global config class that is used in onCreate to instantiate an object (not fully OO for brevity)
public class Global {
public static boolean visible = false;
}
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
MyObject obj = new MyObject(Global.visible);
}
}
Obviously in this case "visible" would be "false". If this were some sort of API library, we would like to provide the option for users to set "visible" to "true".
Update 1
The objective is to have the global class in a pre-compiled library and have its value set by a developer utilizing the library. I am looking for easiest way for the developer to do this when they create their application; I think the manifest is the probably the way to go but I don't know how to inject the value for "visible" via the xml. The answers below using preferences are good but only cover the users point-of-view.
Update 2
IMHO using resources works best here.
<bool name="visible">true</bool>
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
Resource res = getResource();
MyObject obj = new MyObject(res.getBoolean(R.bool.visible));
}
}
I think using SharedPreferences would do what you are looking for, using Global.visible as the default value. Then if the user changes it to true, it will use that value.
boolean makeVisible = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
"MyVisiblePreference",
Global.visible);
MyObject obj = new MyObject(makeVisible);
To allow the preference to be updatable without re-compiling or setting (through a Preferences activity), you can load the default preference from resources:
<bool name="MyVisiblePreference">true</bool>
And reference it similarly with:
boolean makeVisible = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
"MyVisiblePreference",
getResources().getBoolean(R.bool.MyVisiblePreference));
If the developer does not set the preference to false, it will default to true (based upon the resources value).
For simple objects you can create them like this: (Based off of your code example)
public static boolean visible = false;
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
MyObject obj = new MyObject(Global.visible);
}
}
For a more complex object you can initialize it with a static initializer like this:
public static boolean visible;
static {
visible = false;
}
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
MyObject obj = new MyObject(Global.visible);
}
}
You can subclass android.app.Application, this class has method onCreate that you can override. Your subclass have to be defined in AndroidManifest.xml in <application name="YourApplication">. onCreate of application is called before all other components in your application are created (before any Activity or Service).