I have my settings.java and my fragment.java.
In the fragment (that exists in my settings.java) I have a randomized number to set a view. Which works perfectly. I'm trying to change it from a random int to something pulled out of shared prefs. In my settings.java I have a method:
public int getHour() {
SharedPreferences settings = getSharedPreferences("My_Prefs",
MODE_PRIVATE);
int timeout = settings.getInt("timeout_hour", 8);
return timeout;
}
and I call this in my fragment.java by saying
...settings.getHour();
But this causes it to crash. If I simply replace it with a random int (any int) ...8 the program runs perfectly. Why does my app run when I just have the number 8, but when getHour() returns a number (8 in this case) it fails. Is this some kind of limitation with fragments?
Because settings is a local variable to getHour() function. If you want to access it inside your fragment make it a field and provide a public getter function getSettings(). Then get activity instance in fragment by
activity = (Settings) getActivity();
Now access settings by
activity.getHour()
inside fragment.
Related
Yes I'm really new to android and I'm wokring on a very simple app.
On my mainActivity I'm creating and array, and want to access the array from a different activity.
public class Activity extends {
MyAreas[] myArea;
#Override
protected void onCreate(Bundle savedInstanceState) {
myArea= new MyAreas[2];
myArea[0] = new MyAreas(33, 44, "Location ", "active");
myArea[1] = new MyAreas(32, 434, "Location 2", "active");
Class
public class MyAreas{
public double val;
public double val2;
public String name;
public String status;
public MyAreas(double val, double val2, String name, String status) {
this.val= val;
this.val2= val2;
this.name = name;
this.status = status;
}
I'm trying to access myarea array from my activity2.java, I tried this but didn't work.
private ArrayList<MyAreas> mMyAreasList;
Using Parcelable to pass data between Activity
Here is answer which should help.
In regular Java you can use getters to obtain objects or any variable from a different class. Here is a good article on encapsulation.
In Android, there is a class called Intent that lets you start one activity from another and pass any necessary information to it. Take a look at the developer docs and this other answer which should help you.
For your begginer level, rather than using intents, just set the array object public and static, like that:
public static MyAreas[] myArea;
By that way you can access it from any activity in your app..
Then, go to the activity2.java wherever you want to access it.
MyAreas area = Activity.myArea[0];
The problem with this approach is that you do not have complete control when and in what order the activities are created or destroyed. Activities are sometimes destroyed and automatically restarted in response to some events. So it may happen that the second activity is started before the first activity, and the data is not initialized. For this reason it is not a good idea to use static variables initialized by another activity.
The best approach is to pass the data via the intent. The intents are preserved across activity restarts, so the data will be preserved as well.
Another approach is to have a static field to keep the data, and initialize the data in an Application instance.
I'm making a quiz app, there is main activity and it contains fragments which are questions like (Radio Button, Checkbox, Drag and drop questions) . How to collect the Score from all the fragments.
Hold the score variable in the Main Activity
private int score=0;
write public functions to get and set the score in the activity
public void setScore(int score){
this.score=score;
}
public int getScore(){
return this.score
}
Now in the fragments you can get and set score using
score=((MainActivity)getContext()).getScore()
((MainActivity)getContext()).setScore(score)
There are multiple ways to do that.
You can add Set/Get method in Your activity and fetch that from
fragment when you need them.
Create static variable in Activity class and you can access with 'ActivityClassName'.
Use Shared Preference and get access of that data anywhere. You can reset when you need and update from any class.
You can use as your app requires.
Just keep the variable static in which your are storing your score .
for eg : public static int score=0
by writing static it will have reference in memory and will be available until the
activity is running .
Create a Java class and name it as DataHolder. Define score variable as a global variable. Create getter & setter method as static. When you get score, set the values using set method. when you want to get score, use get method. Its simple java. Best thing is you can get and set score from any activity or any fragment using this method. Try below code.
DataHolder.java
public class DataHolder {
private static String Score="";
public static void set_Score(String s){
DataHolder.Score = s;
}
public static String get_Score(){
return DataHolder.Score;
}
}
To set score in DataHolder class, use below code from any fragment or activity.
String Score = ""; //get Score to this variable
DataHolder.set_Score(Score);
try using public static final key word if your value is not going to be changed through out the app else use public static before the var type that will remain accessible in all files with out instantiation and value could be initialized at any instance .
Example:
public static int score;
public static final int score=5;
Second way is by using sharedprefrences , you can get help from here .
I am developing an android app which includes Google maps api. Camera is moved to my current location whenever I start the activity. Even after going to some other activity on return it agains starts to point to my current location. I want to move camera only on the first time when I start the application. I want not to move camera after returning from some other activity. How can it be implemented?
Currently, I declared a boolean var shouldMove on top and in the onCreate method, set its value to true. And after that onLocationChanged method, I put an if statement i.e. if(shouldMove) tk check the variable value. If it's true then move the camera otherwise not. So in case of true, first move the camera and then I set its value to false. But whenever I switch to another activity and return back to mapsActivity, its value is again set tk true, which I don't want to.
Keep the variable 'shouldMove' not in the activity class. In some other static class (for example, Application).
There, and change the value of the variable, then it will not depend on the Activity.
Example:
Create Application class:
public class MyApplication extends Application {
private boolean shouldMove;
public boolean isShouldMove() {
return this.shouldMove;
}
}
in your Activity:
public class YourActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
MyApplication myApp=(MyApplication)this.getApplication();
if(myApp.isShouldMove()) {
...
}
}
}
I have a boolean variable public static boolean isInDarkTheme but when I try to change the value in my settings activity it only gets changed tempolarily.
I did it so:
if (on) {
//Do something when Switch button is on/checked
MainActivity.isInDarkTheme = true;
} else {
//Do something when Switch is off/unchecked
MainActivity.isInDarkTheme = false;
}
Log.d("DarkTheme", "SETTINGS " + MainActivity.isInDarkTheme);
in my settings the variable is changed but when I go back to my main with the
arrow I created with this:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
picture with this button
it is still the same in the main
but! when I use my software key to get back to the MainActivity it get saved
picture with software back key
Any idea what I can do that it get saved with the other button?
your variable will not be saved and will be collected by garbage collector once the activity is destroyed.
you have to use something like SharedPreferences.
to save the variable
SharedPreferences sharedPrefrences = getSharedPreferences("pref_name", MODE_PRIVATE);
sharedPrefrences.edit().putBoolean("isDarkTheme", true).apply();
to load
SharedPreferences sharedPrefrences = getSharedPreferences("pref_name", MODE_PRIVATE);
// key , default value
boolean isDark= sharedPrefrences.getBoolean("isDarkThem", false);
read about SharedPreferences here
The most likely reason is that both activities are loaded by different class loaders with the effect that the MainActivity you "see" in your Settings activity is a different one than the one you "see" in your other activity. You can find that out by logging the classloader "attached" to the MainActivity by calling MainActivity.class.getClassLoader()
I'm trying to get familiar with using SharedPreferences, by building a simple test app where I store and retrieve user preferences by using a class that extends 'PreferenceActivity'.
The problem is that every time I shut down the app and start it again I'm unable to load the SharedPreferences values that I earlier selected.
In the MainActivity's onCreate method I am first calling a method 'loadPreferences', then creating an ImageView and a button.
I assigned onclick listener to the button that creates and starts a new intent.
...onClick(View v){
Intent intent = new Intent(MainActivity.this, MyPrefsActivity.class);
startActivity(intent);
}
In MyPrefsActivity class I have a ListPreference that has a 'Preference.OnPreferenceChangeListener'.
... {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
imageNumber = Integer.parseInt(newValue.toString());
return true;
}
};
Upon return from MyPrefsActivity to MainActivity in the 'onResume':
protected void onResume() {
super.onResume();
savePreferences();
loadPreferences();
}
private void savePreferences(){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("imageNumber", MyPrefsActivity.imageNumber);
editor.apply();
}
private void loadPreferences (){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
int imageNumb = prefs.getInt("imageNumber", 0);
switch (imageNumb){
case 0:
imageView.setImageResource(R.mipmap.image1);
break;
case 1:
imageView.setImageResource(R.mipmap.image2);
break;
case 2:
imageView.setImageResource(R.mipmap.image3);
break;
default:
imageView.setImageResource(R.mipmap.image4);
}
}
When 'loadPreferences' is called for the first time upon startup, 'imageNumb' allways has a value 0, instaed of the value that I assigned to on previous run in method 'savePreferences'.
I noticed that after startup when I enter 'MyPreferencesAction' for the first time and open the ListPreferences, the checkbox that I selected on the last run is already selected for me. It seems like my selection is saved but when I try to load SharedPreferences am I messing up something???
You have to save your preferences in onPause event. Right now you are saving it in onResume when values you want are no longer there.
#Override
protected void onPause(){
super.onPause();
savePreferences();
}
#Override
protected void onResume() {
super.onResume();
loadPreferences();
}
There is another issue with your code. You are saving preferences in MainActivity, but you are changing them in MyPrefsActivity. That will not work. You have to save changes to the preferences in MyPrefsActivity, use above load/save pattern in there too. If you don't have any preference changes happening in MainActivity, you can safely omit calling savePreferences from it.
Depending on MyPrefsActivity declaration calling MyPrefsActivity.imageNumber from MainActivity may not be safe, you will have to change that code too. Like I said, most likely you don't need it at all in MainActivity (if you saving are only preferences values that are set in MyPrefsActivity) and that should be part of MyPrefsActivity.
Also Preference.OnPreferenceChangeListener is probably redundant since it's main usage is to be invoked when the value of this Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value.
I realized there was a lot of needless complexity in my code. So I got completely rid of the method savePreferences(). Instead i simplified the PreferenceChangeListeners method onPreferenceChange(...):
This seems to me to be the most simplest way to update SharedPreferences when using PreferenceActivity.
public boolean onPreferenceChange(Preference preference, Object newValue) {
preference.getEditor().
putInt("imageNumber", Integer.parseInt(newValue.toString())).apply();
return true;
}
Now I save the SharedPreferences manually, only when 'onPreferenceChange' is called. Not on 'onResume', 'onStop', 'onRestart' or on 'onPause'.
Please inform me if this is a bad way to change SharedPreferences.
Quoting Dalija Prasnikar: "reference.OnPreferenceChangeListener is probably redundant since it's main usage is to be invoked when the value of this Preference has been changed by the user and is about to be set and/or persisted. This gives the client a chance to prevent setting and/or persisting the value."
If you understood you correctly Dalija, there is a 'onPreferenceChange(...)' like method that does the job but does not have a boolean return value but void? I was not able to find any examples, could you please show or point to an examle?