I am pretty new to the android programming thing so I am sure that there is something simple that I am not doing correctly. I have two activities that are accessing a shared preferences file; one that reads from it and displays the contents to a list, and the other reads the contents and adds a new item to the list based upon user input. The issue that I am having: when I read the contents from the file and attempt to add a new item to the list my original list is being overwritten. Maybe that's not what is actually happening but it seems to me that this is the issue. When I add a new item from the child activity and return to the original activity which displays the list I am only seeing the newest item that I saved and not any other items that I had created previously.
The first activity is the main activity and it simply reads the shared preferences and adds the items in a string, separated by commas and displays them in a listview. I only showed the method for displaying the items in the listview:
public void addItems() {
String strLists="";
SharedPreferences sharedPref = getSharedPreferences("ListNamesFile", MODE_PRIVATE);
strLists = sharedPref.getString(getString(R.string.edit_message), strLists);
listItems.clear();
String[] myLists = strLists.split(",");
for(int r=0;r<myLists.length;r++){
listItems.add(myLists[r].toString());
}
//test adding an extra list item to make sure that the issue isn't from adding
//items to the listview
//listItems.add("test");
adapter.notifyDataSetChanged();
}
The second activity is for getting a new string from an edit text control, adding it to the end of the string with the list items, and committing the changes to the shared preferences file. I have included the method for retrieving the shared preferences and writing the new item to the end of the string:
public void createListOnClick(View view){
//create a file for storing list items
SharedPreferences sharedPref = getSharedPreferences("ListNamesFile", MODE_PRIVATE);
String strMyLists = "";
sharedPref.getString(getString(R.string.edit_message),strMyLists);
String[] lists = strMyLists.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lists.length; i++) {
sb.append(lists[i]);
sb.append(",");
}
SharedPreferences.Editor editor = sharedPref.edit();
EditText txtListName = (EditText)findViewById(R.id.txt_list_name);
sb.append(txtListName.getText().toString());
editor.putString(getString(R.string.edit_message), sb.toString());
editor.commit();
finish();
}
It seems that it must be something simple that I am missing but I haven't been able to figure it out so any help would be greatly appreciated.
you still haven't assigned the sharedPref value in the strMyLists.
In the second activity, you're not actually assigning the read shared preferences:
You should replace
sharedPref.getString(getString(R.string.edit_message),strMyLists);
with
strMyLists = sharedPref.getString(getString(R.string.edit_message),strMyLists);
in getString method
sharedPref.getString(getString(R.string.edit_message),strMyLists);
second argument is default value. So you will have to write.
strMyLists = sharedPref.getString(getString(R.string.edit_message),"");
it will work with this. rest of the code is good.
Related
I'm having doubt and a problem I tried to solve with this Note App I found on Google, which is pretty simple, so I (a beginner) went to try few things on it.
Everytime I save few notes, close app, restart app, it reorganizes the notes alphabetically, which I don't want. I know that Set and ArrayList are different in the sense a Set won't repeat elements, but ArrayList will. Also Set can't guarantee the order when called.
The question is: how is a good way to solve this instrinsecally sorting problem?
I've tried to switch what's HashSet to ArrayList, but the method putStringSet requires a Set in its parameters, which ArrayList isn't.
The following code works (doesn't crash or any other problem) but doesn't work as I want.
I have this part code in the MainActivity
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.tanay.thunderbird.deathnote", Context.MODE_PRIVATE);
HashSet<String> set = (HashSet<String>) sharedPreferences.getStringSet("notes", null);
// a lot of other things here
if (set == null) {
notes.add("Example Note");
} else {
notes = new ArrayList<>(set); // to bring all the already stored data in the set to the notes ArrayList
}
On NoteEditorActivity I have
Intent intent = getIntent();
noteID = intent.getIntExtra("noteID", -1);
if (noteID != -1) {
editText.setText(MainActivity.notes.get(noteID));
} else {
MainActivity.notes.add(""); // as initially, the note is empty
noteID = MainActivity.notes.size() - 1;
MainActivity.arrayAdapter.notifyDataSetChanged();
}
//other things here
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
MainActivity.notes.set(noteID, String.valueOf(s));
MainActivity.arrayAdapter.notifyDataSetChanged();
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.tanay.thunderbird.deathnote", Context.MODE_PRIVATE);
HashSet<String> set = new HashSet<>(MainActivity.notes);
sharedPreferences.edit().putStringSet("notes", set).apply();
}
If you would like to keep the order of the notes, Array or List is truly the better choice than using Set.
To store this into SharedPreferences, you can refer to Put and get String array from shared preferences
This question has answers explaining the followings:
Jsonify the list and parse it back.
Concatenate all the Strings with delimiter and split it back.
I develop one application when user click any recyclerview view item the text color should change and its working fine, but when ever i open again my application the text color not remain change i used shared preference for saving sate but its not working any solution?
code:
ItemClickSupport.addTo(recyclerView).setOnItemClickListener(
new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
alarmDao = alarmDaos.get(position);
alarmDao.setRead(true);
alarmDaos.set(position, alarmDao);
alarmAdapter.notifyDataSetChanged();
Intent intent = new Intent(getContext(), NotificatinActivity.class);
startActivity(intent);
try {
SharedPreferences pref = getActivity().getSharedPreferences("MyPref", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("isRad", alarmDao.isRead());
editor.putString("string", String.valueOf(alarmDao));
editor.apply();
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
This value shouldn't be stored into the SharedPreferences as it's part of the object you want to display.
As it's a DAO it means you have a database somewhere. So when the user selects the item, you update the isRead field and update the database.
Then when you want to display the list again, you just have to check if isRead is true or false to display the item's colour accordingly.
You need to check sharedprefernce value in recyclerview adapter
and set color in bindholder .
ie ,in bindholder if clicked set selected color and not clicked set another color
sharedprefrence will not be a great solution because all position state should be saved clicked or not . if want to use sharedprefernce make it an array of states accoridng to position and save in it.
array of states is needed for every postion or use sqllite
Use SqLite Database , Save list of items in database and include ReadUnRead column in Table. whenever user clicks item set ReadUnRead to 1 and in Recycler Adapter OnBindView any item that has ReadUnRead equal to 1 change its color.
You need to create a database and make a one Boolean variable like true.false for that and set a value in this variable if it's clicked then changed it's value true. or another solution is you need to create a shared preference and set and get a value from this but i recommended to you use a database.
I'm attempting to update and ArrayList with new data - however when I attempt to do so - the previous data is overwritten and the new data is never appended to the list and I'm unsure why.
if (keylist.contains(item) && !value.equals("start") && !value.equals("stop") && !value.equals("done")){
final Integer number = keylist.indexOf(item);
this.runOnUiThread(new Runnable() {
#Override
public void run() {
// GET PREVIOUS VALUES
String previous_key = App.sharedPrefs.getString(LIVE_VIEW_KEY, null);
String previous_value = App.sharedPrefs.getString(LIVE_VIEW_VALUE, null);
// ADD NEW AND OLD VALUES TO LIST
mCallElements.clear();
mCallElements.add(new CallElement(previous_key, previous_value));
mCallElements.add(new CallElement(valuelist.get(number), value));
mAdapter.notifyDataSetChanged();
// SAVE NEW VALUES
final SharedPreferences.Editor editor = App.sharedPrefs.edit();
editor.putString(LIVE_VIEW_KEY, valuelist.get(number));
editor.putString(LIVE_VIEW_VALUE, value);
editor.apply();
}
});
}
P.S.
This is part of a Twilio chat implementation - full source can be seen here: https://pastebin.com/imNQdCJ0
You're clearing the ArrayList with .clear() and then calling .notifyDataSetChanged(). This clears the last set of data, and then forces the Adapter to completely reload.
To make your life as a developer significantly easier, I would recommend using DiffUtil. This calculates the difference between two lists, and deals with the changes for you. A really good tutorial on how to implement this can be found on CodePath: https://guides.codepath.com/android/using-the-recyclerview#diffing-larger-changes
The Android Documentation says:
'rely on notifyDataSetChanged() as a last resort'
But because of DiffUtil you don't have to care anymore.
I think if you just want to add new data to the old data,you do not need to use mCallElements.clear(),if the notifydatachanged still doesn't update the data, I think you need to check if your ArrayList is the same object.I hope my answer will help you
I create a few ArrayLists during one of my activities. When I leave the activity and come back to it, they come up as null. From some research, SharedPreferences is the way to overcome this. How do I go about this; do I have to save it as a HashMap? is SharedPreferences it's own method or do I do it within another specific method?
You have at least three options:
Use a SharedPreferences object as you suggest in your question.
Use a SQLite database.
Use a file with your own format.
For an introduction to each of these options, read Storage Options.
Here, how to write on Shared Preferences:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
//if your codes in your activity class, you dont need getActivity so you should use this
SharedPreferences.Editor editor = sp.edit();
editor.putInt("your_string_key", yourValue);
editor.commit();
Here, how to read from Shared Preferences:
SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
//same here. If your codes in your activity don't write "getActivity." part
int yourSavedValue = sp.getInt("your_string_key", defaultValue);
//defaultValue mean if there is no value with that key, it will return defaultValue.
If you'd like to learn more about it here you can get more information.
Answer to your new updated question:
As you can see my answer there is defaultValue.
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
Set<String> tempSet = settings.getStringSet(FIRST_LIST, "");
Set<String> temp2Set = settings.getStringSet(SECOND_LIST, "");
//if it is first time it will return null. So your app going crash. To avoid that make a default value. Like this.
for (String str : tempSet)
firstList.add(Uri.parse(str));
for (String str : temp2Set)
secondList.add(Uri.parse(str));
** you have convert this array to gson.
** First pass your array in parameter public void saveArrayList(ArrayList list, String key)
** now create object of SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = prefs.edit();
** now convert to gson :
Gson gson = new Gson();
String json = gson.toJson(list);
editor.putString(key, json);
editor.apply(); // This line is IMPORTANT !!!
I have created two EditText objects in the Java code of My android application, as
final EditText et1=(EditText)findViewById(R.id.editText1);
final EditText et2=(EditText)findViewById(R.id.editText2);
then on the onClick() event of a button, called a method with parameters as-
addStringToXmlFile(et1.getText(),et2.getText());
now in the definition of this method below, i have written-
private void addStringToXmlFile(Editable editable1,Editable editable2){
String s1=new String();
s1=editable1.toString();
String s2=new String();
s2=editable2.toString();
}
The problem is that, now i want to use these two String objects s1,s2, to make two entries in the res/values/Strings.xml file of the database, & I don't know how to do it.
please guide me further.
This is not possible - an app's apk (including it's resources) can not be changed at runtime. I'm not entirely sure of all of the reasons why, but one obvious thing I can think of is that R.java needs to contain a reference to your String in order for you to access it, and this file is generated by the compiler when you create the APK.
If you need to persist a String across sessions, you should look into using one of several data storage mechanisms that Android provides, such as SharedPreferences.
Take a look into using SharedPreferences to store your string values instead.
//Saving your strings
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("s1", s1);
editor.putString("s2", s2);
editor.commit();
//retrieving your strings from preferences
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
String s1 = prefs.getString("s1", ""); //empty string is the default value
String s2 = prefs.getString("s2", ""); //empty string is the default value