i am working on a project where i have to test some wifi rssi values that i am calculating in parent activity.... but for testing i have created a new activity which is launched by pressing of a button..what i want is to get the 5-6 different values from the wifi scan results and use them in test activity instead of one??
i have tried getting values in 5 different arrays and passing them to test activity but there were some complications with this method in my code.
can anybody give me some suggestions how to achieve this?
You can use a Hashmap and SharedPreferences.
1 - Set your values
Map<String, String> values = new HashMap<>();
values.put("key0", "value0");
values.put("key1", "value1");
values.put("key2", "value2");
SharedPreferences keyValues = this.getSharedPreferences("myPrefs", Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();
for (String s : values.keySet()) {
keyValuesEditor.putString(s, values.get(s));
}
keyValuesEditor.apply();
2 - Retrieve a value
SharedPreferences prefs = getSharedPreferences("myPrefs", MODE_PRIVATE);
String myValue = prefs.getString("key0", null);
Related
Good morning! I am trying to make a toDo list and I want to do this through the sharedPreferences. The problem is that once I get the contents of the location and then add it to the contents of the list and try to push it back to sharedPreferences, I get a strange error. It does not make sense to me because the taskSet Set is defined by the items in the sharedPreferences, so how could it be the incorrect type?
public void putInSharedPreferences(View view){
Intent i = getIntent();
SharedPreferences sp = getSharedPreferences("storage", Context.MODE_PRIVATE);
Set<String> taskSet = sp.getStringSet("taskSet", new HashSet<String>());
String task = i.getStringExtra("taskText");
taskSet.add(task);
sp.edit().putStringSet(taskSet).apply();
int minutes = i.getIntExtra("chosenMinutes", 0);
}
The error I receive:
putStringSet (java.lang.String, Set) in Editor cannot be applied to (java.util.Set)
putSetString() takes two parameters: A key, which is aString, along with a Set<String>. So you'd put the set like this:
sp.edit().putStringSet("taskSet", taskSet).apply();
See the method definition here for more info.
My App: has two activities, one to create two strings (name and message), which are saved into a hashmap, transferred into JSON and saved in a SharedPreference.
The other activity fetches this SharedPreference, transfers it into a hashmap again. Then the map is "read out" by an Iterator.
Supposed to be: My Idea is, that if I do this process several times, the iterator "reads out" all the entries to the hashmap.
Problem: However, only the last input gets displayed.
Question: Why is only the last input displayed? Am I overriding the hashmap or parts of it? And if so, how can I avoid it? Or what else am I doing wrong?
Activity 1:
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put(message, name);
Gson gson = new Gson();
String hashMapString = gson.toJson(map);
SharedPreferences prefs = getSharedPreferences("SP", MODE_PRIVATE);
prefs.edit().putString("hashString", hashMapString).apply();
Activity 2:
Gson gson = new Gson();
SharedPreferences prefs = getSharedPreferences("SP", MODE_PRIVATE);
String storedHashMapString = prefs.getString("hashString", "Error");
java.lang.reflect.Type type = new TypeToken<LinkedHashMap<String, String>>(){}.getType();
LinkedHashMap<String, String> map = gson.fromJson(storedHashMapString, type);
Iterator myIterator = map.keySet().iterator();
while(myIterator.hasNext()) {
String key=(String)myIterator.next();
String value=(String)map.get(key);
Toast.makeText(getApplicationContext(), "Key: "+key+" Value: "+value, Toast.LENGTH_LONG).show();
}
while doing this
prefs.edit().putString("hashString", hashMapString).apply();
you are just saving values of newly created hashmap but old losing values which were saved previously using hashString key
Solution: fetch the old value and save it along with new values
Option one : fetch previous string , convert it to jsonobject then add the values to map
Reference : creating Hashmap from a JSON String
Option two : if you have only string key-value pair then
remove { and } from both new and old map strings then simply combine them and add { and } boundary symbols
String allValues ="{"+((prefs.getString("hashString", "")+hashMapString)
.replace("{","").replace("}",""))+"}";
then later save it
prefs.edit().putString("hashString", allValues).apply();
you are seeing the last input because putString overwrites whatever was there in the first place
https://developer.android.com/reference/android/content/SharedPreferences.Editor.html
I am developing an app that generates passwords randomly. I am adding a "save" feature so that the user can save their passwords in SharedPreferences. (which is not what you are supposed to do with your passwords)
I have an activity called PasswordActivity and in that activity I display the saved passwords.
This is how I save a password: I prompt the user to enter a name/key thingy for the password so that he/she can identify it later. And then I save the key and the password in the SharedPreferences using the following method in a utility class:
public static int savePassword (Context c, String passwordKey, String passwordValue) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
SharedPreferences.Editor editor = prefs.edit ();
boolean duplicateKey = !keys.add (passwordKey);
boolean duplicateValue = !values.add (passwordValue);
if (duplicateKey)
return KEY_DUPLICATE;
if (duplicateValue)
return VALUE_DUPLICATE;
editor.putStringSet (PASSWORD_KEYS, keys).
putStringSet (PASSWORD_VALUES, values).apply ();
return SUCCESS;
}
And I wrote another method to get the passwords and their names. The method returns a HashMap<String, String> as you might have guessed.
public static HashMap<String, String> getPasswords (Context c) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
ArrayList<String> keysList = new ArrayList<> ();
ArrayList<String> valuesList = new ArrayList<> ();
for (String key : keys) {
keysList.add (key);
}
for (String value : values) {
valuesList.add (value);
}
HashMap<String, String> map = new HashMap<> ();
for (int i = 0 ; i < keys.size () ; i++) {
map.put (keysList.get (i), valuesList.get (i));
}
return map;
}
I admit that the code is pretty messy. I first get the things in the two sets and turn them into ArrayLists and add the stuff in the array list to the map and return.
Phew! That was a lot of work!
Now when the user generates a password and saves it, the two sets contain the right things: (These are fake data)
keys:
key1
values:
value1
That's all good. But when I generate another password and save it, the two sets become messy:
keys:
key1
key2
values:
value2
value1
Now when I call the getPasswords method, it will return
{key1, value2}, {key2, value1}
which is incorrect. After looking at the docs, I found out that:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
which I guess is the reason that makes the incorrect results.
So I was wondering is there an alternative way to store these passwords and their names?
As you're storing multiple names & passwords, i would suggest a local SQLite database. SharedPreferences are meant for single values, not sets of values.
If you can't be bothered setting up the entire SQLiteOpenHelper and all that raw SQL code, you could take a look at some ORM helpers such as SugarOrm (i currently use this, its EXTREMELY easy to set up and use)
I would recommend a database, such as SQLCipher for Android, so the user can provide a master passphrase for the app, and all the data is stored encrypted on the device.
But, let's pretend that, in order to successfully repel an alien invasion and prevent the wholesale slaughter of countless humans, you have to implement this using SharedPreferences. After that, you will need to fly with a wise-cracking companion in a commandeered alien spacecraft and successfully upload your app into the computer systems of one of the alien mother ships (which, fortunately, happen to be running Android, as Android has remarkable market share across the galaxy).
Either:
Have each key and value be separate entries in the SharedPreferences. After all, SharedPreferences is a key-value store. Use a dedicated preference file for your keys and values (so as not to collide with anything else you might want to store), then you know that all the keys are ones from the user.
Marshal the HashMap into JSON or XML or something and save that as a string, unmarshalling it as needed.
I want to store the last X values that a user input into a form. I have a list of 20 values and every time the user enters a new one, the oldest value is pushed out of the list and the newest value goes in. I want this list to persist between app launches, but sharedpreferences doesn't support an ordered set, so the results will end up jumbled every time. How can I store the list in an ordered form that I can then retrieve?
Set<String> previousValues = sharedPreferences.getStringSet(getString(R.string.LAST_VALUES), null);
You can do this in several ways:
Create a SQLite database and store them in a table
Have a unique key in the sharedpreferences and use JSON to serialize them. You don't need to use the any external library, Android includes its own JSON classes,
Have multiple keys in the SharedPreference, one for each value, and an additional, numerical, for storing the index of the last one, something like:
int index = ... // number of entries
List<String> values = ... // the values you want to store
SharedPreferences prefs = ...
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("index", index);
for (int i = 0 ; i < index ; i++) {
editor.putString("value." + i, values.get(i)); // assuming your values are in a String collection called 'values'
}
Of course, this snippet should give you the general idea, you would probably only add the last one every time and not all at once. When reading, you read first the index value, and then only index number of strings.
Using SharedPreferences it's easy, after API 11 the SharedPreferences Editor accept Sets as argument, so just create a Set with size of 20 and store it in shared preferences. When retrieved use it like any other java set to store only 20 values.
Set<String> lastValues = new HashSet<String>(20);
Get shared prefs
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE);
Set shared prefs
Editor editor = prefs.edit();
try {
editor.putString(TASKS, ObjectSerializer.serialize(lastValues));
} catch (IOException e) {
e.printStackTrace();
}
editor.commit();
Examples here and here
My code here will be simplified for readability.
Methods for getting the Set and adding a password to it:
public void addPass(String pass)
{
// Get the current list.
SharedPreferences sp = getSharedPreferences("passes", 0);
SharedPreferences.Editor editor = getSharedPreferences("passes", 0).edit();
Set<String> passes = sp.getStringSet("myStrings", new HashSet<String>());
// Add the new value.
passes.add(pass);
// Save the list.
editor.putStringSet("myStrings", passes);
editor.commit();
}
public Set<String> getPasses()
{
SharedPreferences sp = getSharedPreferences("passes", 0);
return sp.getStringSet("myStrings", new HashSet<String>());
}
Reading from the Set
Set<String> x = getPasses();
String[] passes = x.toArray(new String[0]); // convert the set to array
toast(Arrays.toString(passes)); // test what the set looks like
I converted the set to an array because it was easier to test conditions with an array for me.
Adding to the Set
EditText password1 = new EditText(this);
String p1 = password1.getText().toString();
addPass(p1.trim()); // add it to the set
toast("Account successfully created.");
Problem
When I first ran this code, I added three String values: "a", "b", "c" (in that order).
All the value were added to the Set correctly and it was confirmed with this line of code from above:
toast(Arrays.toString(passes)); // test what the set looks like
It outputted [b, c, a] after the "c" was added to the set.
The problem is that when I closed the app and reopened it, the Set only contained "a".
I could add the "b" and "c" values again, but the cycle would just continue where the Set only kept the first value added to it after the activity was recreated.
I've troubleshooted for a while and cannot fix it. I can provide more detail on how and when I'm using this code if necessary. I'm hoping I don't need to and someone can point out a problem in the code as shown.
Was searching for a solution for the same issue, a solution to this would be
// Get the current list.
SharedPreferences sp = getSharedPreferences("passes", 0);
SharedPreferences.Editor editor = getSharedPreferences("passes", 0).edit();
Set<String> passes = sp.getStringSet("myStrings", new HashSet<String>());
//Make a copy, update it and save it
Set<String> newPasses = new HashSet<String>();
newPasses.add(pass);
newPasses.addAll(passes);
editor.putStringSet("myStrings", newPasses); editor.commit();
It might be that your issue stems from using getStringSet(), have a look at the docs:
public abstract Set<String> getStringSet (String key, Set<String> defValues)
Retrieve a set of String values from the preferences.
Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.
Based on this doc , and this SO Post about the exact same problem as yours, it seems you should create a new copy of the returned instance of the HashSet, and you seem to have done that, at least from what code you've pasted here. Maybe there's something else that's being missed.
However, check out the answer on this post . What the guy did was:
Add the first value to SharedPreferences as a String Set.
To add subsequent values, first read the existing pref into a new String Set.
Remove the old String Set key.
Modify the new string set to add the new values you want to store.
Add the new String Set to preferences.
While that is a long and silly way to do things, it seems like the last option. So basically, store all the values you want to store, in one go (not in instalments). If you want to add new values, remove the old key, create a new key with the old + new values, then store the new key.
Hope that helps.