Which Preference Class for an Integer? - android

To store an integer in an Android preference, I would intuitively go for EditTextPreference and do the usual String-int-String conversions.
But then I came across a piece of code that stores an integer in a <ListPreference> instead:
<ListPreference
android:key="#string/total_score"
android:defaultValue="0" />
and retrieves it using preferences.getInt(getString(R.string.total_score), 0);
Does this really work? If so, how?
Is it considered acceptable practice?
UPDATE: Thanks to the answers below, I have been able to find the implementation source code for getInt(). I am posting it here for easy reference:
jint android::content::SharedPreferences::getInt(local_ref< java::lang::String > const &a0, jint a1)
{
return call_method<
android::content::SharedPreferences::J2CPP_CLASS_NAME,
android::content::SharedPreferences::J2CPP_METHOD_NAME(2),
android::content::SharedPreferences::J2CPP_METHOD_SIGNATURE(2),
jint
>(get_jobject(), a0, a1);
}

In theory, yes you can store an integer with a ListPreference. After all it's a UI-preference that maps a user displayed label/key (android:entries) to an internal value (android:entryValues) and displays all those mapping options in a listview. That internal value might as well be an integer. You could use a <integer-array>-resource for the entryValues.
In practice, I've never seen that work - it's bugged.
Of course, you can set a int value to the preference key of the ListPreference in your code, since it's a normal preference internally. But that would defeat the whole purpose of predefined resource arrays and ability to select from a list. As a workaround, if a int-array would be handy, I recommend using a <string-array> for the values and convert them an integer in code, as you would with your EditTextPreference
Check this question for a non-working example. ;)
To answer your title question which one to choose for an integer: Depends.
You can use either one with the workarounds.
If the user should be able to enter any value (or just a lot of values), the EditTextPreference is the way to go. A ListPreference would just be too long.
If you have a small set of predefined ints, use a ListPreference. Thats way more comfortable to use and might be displayed with useful labels. Example: If the user is supposed to select a timing interval, you could map the seconds in the value and display a different label, e.g. an hour [value 3600; label "Hour"].
Edit: Also got an idea where your code snippet may be related to. Since this ListPreference does neither specify android:entries nor android:entryValues, it might just be part of a default preference file. You can use PreferenceManager.setDefaultValues() with an XML file to reset/initalize all your preference keys. In this case it's completely random which preference you choose, because all fields that count are android:key and android:defaultValue. You might use any other type in this case, does not matter.

I think what's going on is that the ListPreference is storing the entry values as an array of chars, or in other words an array of bytes (I'm inferring this from the setEntryValues(CharSequence[] entryValues) method). This could be why storing a number works, because the value is stored into the byte array, so using the preferences.getInt(...) method will still work. This could be dangerous, however, as discrepancies with signing could occur, so I wouldn't recommend it, and would parse the int from a string preference instead.

Related

String Array in SharedPreferences

I need to work with a persistent String Array (n Rows, 1 column).
* On first running the app, the String Array needs to be created empty.
* On subsequent app executions the Array will be populated from a File and the contents need to be available throughout the rest of the app.
* As the app is executed, the Array needs to be able to 'grow' in row count
* As the app is executed, the Array rows need to be able to grow in length
* The user will have the option to Clear the Array of previous entries.
* At the end, the String Array contents will be written back to a File.
I find a lot of references to Putting and Getting from an existing SharedPreferences String[] but, in the newness of my Android development, I am struggling with how to proceed.
EDIT Follows...
The data itself suggests using an Array
Example:
MAIN ST. F55 63 KY08:57 12142015--------KY11:24 12142015345TMH KY13:57 12142015
MAIN ST. F56 WYE123 IN08:57 12142015--------KY11:24 12142015--------KY13:57 12142015
1ST ST. F57 --------KY08:57 12142015--------KY11:24 12142015789FPF KY13:57 12142015
1ST ST. F58 456FPF KY08:57 12142015998FPF KY11:24 12142015--------KY13:57 12142015
1ST ST. F59 789TTM KY08:57 12142015--------KY11:24 121420151234DG KY13:57 12142015
I first need to have this data in a File
Then in one GUI I check for the existence of the file.
If one exists, fine
If none exists, I create one.
Then, in subsequent GUI's, I must check for the existence of parameters
If they do not already exist, add them to the existing data lines.
If they already exist, notify the user
And so on and on.
Then when all of the current 'pass' data has been collected via multiple, separate GUI's, I have to write out the whole data-set into the file.
My reason for thinking that I need a SharedPreference approach is the need to find and check data from GUI to GUI as the user progresses through the app.
If that 'belief' is wrong, I am open to better approach suggestions.
EDIT 2 follows....
On further study of web references, I am beginning to think that perhaps the best approach for this data and how the data needs to change might be to use a SQLite approach. Any ideas about this?
Any assistance/suggestions you might have would be greatly appreciated.
i would discourage you from using sharedpreferences for anything else than preferences. means things that change rarely - really rarely and are really lightweight. do not put much data in there. less is better. the data structures underlying sharedpreferences are not a database.
another note. it is not a string list, but it would be a string set. sets are not necessarily ordered, nor do they necessarily keep their order. means - it is not rows. its a collection of strings that can come back in any fun order (usually there is some, but that depends on the implementation which i do not know)
now you could go and make your own list, your own data structure, save it into a string and read it out, use json to do exactly that or something similar, or better - use a database, which would exactly do that.
http://developer.android.com/training/basics/data-storage/databases.html
explains it, but as you'll see its something that might take some time.
now dont get me wrong, but i have to warn you about the following approach. it is valid, but has many problems and is far from thread safe. it will not be a problem as long as you only open it from the ui thread and do not keep anything in memory to cache - if you do it will create lots of problems.
your problem of adding a line and clearing can be solved by using a file. just a simple file
look here
http://developer.android.com/training/basics/data-storage/files.html#WriteInternalStorage
the change is to append when writing:
openFileOutput("filename", Context.MODE_APPEND);
see the context mode? now you can basically just write one line and append every time.
if you wanna clear the file, just deleteFile("filename")
this is as said not threadsafe, but can be a viable option if used carefully.
Please follow this step to achieve what you want with sharedPreference
create the class Parent for SharePreference
Create your empty Array
Convert Your empty array to String and put it on SharedPreference
to call your empty array from sharedPreference
Call your sharedPreference using your key
Convert the String to array
You get your array from the sharePreference
Hope it helps, and maybe this link will help you :
http://www.androidhive.info/2012/08/android-session-management-using-shared-preferences/
You can use my open-source library called prefser, which solves this problem and uses SharedPreferences and Gson under the hood. It's basically wrapper for default Android mechanism.
You can use it in the following way:
Prefser prefser = new Prefser(context); // create Prefser object
prefser.put("key", Arrays.asList("one", "two", "three")); // save array of Strings
String[] value = prefser.get("key", String[].class, new String[]{}); // read array of Strings
For more information check repository of the project, tests and README.md file.
Link: https://github.com/pwittchen/prefser
Please note, SharedPreferences have some limitations and shouldn't be used for storing large amount of data. If you expect a lot of data, consider using SQLite database or another type of database (e.g. with NoSQL or similar approach if you strive for simplicity).
OK, based on the data, how it needs to be manipulated and the pros and cons of using a SharedPreferences approach, I have decided to go with a SQLite approach.
With that approach I should be able to readily check:
* if the necessary table exists (if not create it)
* if the necessary Field1 + Field2 exists (if not create a new record)
* and I will be able to modify the record's Field3 contents as needed
Then when the user's actions are complete I can convert the SQLite table 'records' into strings and write them out as a File and then either DROP or PURGE the associated SQLite table (until needed next time).
I sincerely appreciate all of your suggestions.
Thank you.

Playing raw file based on String

I have a simple program where I generate random numbers, and use these to return an element from an array. Based on this array element, I want to play a sound file. For example: The random element that was returned was "Am". I now want to play the file "am.ogg". But you cant just throw a string in for the resourceId. Any ideas?
This seems to be duplicate of this thread (which by the way is also duplicate). Except for using this method you can also use reflection on the R class (second also not good option). The best option is the one in which the list of ids you will be interested in can be determined in the code. Basically you define map mapping every string to the corresponding R.id variable (int). However, I am not quite sure this will be your case.

Maximum Size of SharedPreferences class

I want to save a lot of strings with SharedPreferences class .
These strings are quit long.
I really want to know the maximum length of a string that can be save in shared preferences in android.And Also How much size of data i can store in This SharedPrefernces class.
As per android architecture there is no such limit to store data in SharedPreference. Better way is to database (SQLite) when you have to deal with huge amount of data
I read somewhere that there is no hard limit other than Integer.MAX_VALUE ( maximal string length). But it is not advisable to store that much on shared preferences, as this is XML file which must be parsed and you will have a problems while parsing it.
I used to store about 50-100KBytes there. It worked.
The exact answer obtained manually is: maximum Unicode symbol's size is 5657632 symbols (or from [0 to 5657631]) in my case. It's some about 2.7MB for SharedPReference.Editor .
Rather large storage.
You ca use this size twice:
PreferenceManager.getDefaultSharedPreferences(c)
context.getSharedPreferences("<key>", <Mode>);
Of course is't limit for SharedPreferences but if system won't have enough memory it is one first stuff what DELETE it, you remember it.

Android: Can I save more than one SharedPreference entry to a file?

This is the problem:
I have a form for inputting names, then saves it, then displays it in another activity. But once I try to enter another name, the previous name is overwritten by the new name.
Is there a way to set these names up to list themselves one after another without overwriting each other in SharedPreferences?
You can as long as they have distinct names. Ig you need multiple values for same name, you can store JSON array or use some form of prefix / suffix solution to provide unique names
Either do it like Konstantin Pribluda suggested, or you might think of using the SQLite, if you have a lot of names you want to store (e.g. if creating a history of typed in names). That way you can store unlimited values for the same key and retrieve them as a list/cursor.
But of course that's overkill if you only have 2-3 names…
you can also save a Set of Strings in the SharedPreferences.

Dictionary sort?

hey,
i have a dictionnary like
"key2","value2"
"key3","value3"
"key1","value1"
is it possible to sort it on value ?
If not, any other object can do same thing? (sort value on key/value pair)
Well, clearly you're talking about a Map.
It really depends on what Map you're using, You don't need to sort a TreeMap, coz it is already sorted.
For any other, You can get the keys using map.keySet() and use Collections.sort() to sort them. (Note, the map will remain the same, you'll get a Set containing all the key values)
Hope it helped.

Categories

Resources