I'm working on building out a settings page for my Android app. For this I am using the PreferenceActivity and its functionality. The saving/editing of the settings is the simple part but I'm wondering what the best way to access the settings through the app is? I could of course access the SharedPrefs every time I need to, however, this seems inefficient to me...especially if since some of the settings could be access fairly frequently.
I'm wondering if it is worth creating a class that loads all of the settings when the app is opened and is then accessible through out the app via the Application class. This class would then be updated every time the settings are changed.
Is it worth taking this approach or is there a better way? Or is it not worth keeping the settings in memory throughout the lifetime of the app?
Thanks
The entire purpose for SharedPreference is what this is designed for. They are efficient to save/change the settings of your app, by just retrieveing it through your context. I dont see WHY you would keep it in memory, but you'd keep it in the XML key/value pairs that are SharedPrefereces.
Just use it, its what the android engineers would want you to do.
Just a snippet from the SDK:
The SharedPreferences class provides a general framework that allows
you to save and retrieve persistent key-value pairs of primitive data
types. You can use SharedPreferences to save any primitive data:
booleans, floats, ints, longs, and strings. This data will persist
across user sessions (even if your application is killed).
By primitives, it means lightweight variables that can be stored/committed.
Related
Is there a better architecture that we can follow other that making these fields static(bad for performance) or storing in Shared Preference.
Either use Shared prefs or a database. Both are optimized for quick and (more or less) safe access. It might be worth your while to read about Architecture Components, Room (or others such as ObjectBox, Realm, etc) and repository pattern.
Android Jetpack would be your best option. Check out the documentation on Data Binding, it would allow you to access fields like user_id without writing tons of boilerplate java/kotlin code, by injecting the data directly into you xml code. Here's the link: Android Jetpack Data Binding
There is nothing wrong in saving two/three Strings as static variables, In fact it is the fastest way to get repeatedly used variables. I prefer Application class to do so(static variables of Application class), but the issue is if your app happens to crash for some reason, application class is recreated and app starts from the previous activity, alas your static variables are long gone, be aware of this pitfall
Depends on how/when you are using these static elements.
A few application global variables like userSession object might make sense to store in the MyApplication file itself and made exposed throughout the app so you confirm it is valid when app returns from background each time for example.
SharedPreference is not a great place to store secure elements as it is on file storage in unencrypted xml format which rooted phones and others may have access to get to.
Database is a fine option, but it requires more code bloat and requires a database connection and query everytime you want to use the token if you don't plan to store it in RAM.
Another option is a singleton class that is meant to store your necessary application elements like FirebaseHelper for example that could populate into RAM on app startup and utilize your variables throughout the application life.
So really depends on your app needs. You can also use a SecureSharedPreference tool. There are a few open source options out there for this that you can just include in your project that encrypt the xml elements for you if you prefer to use the xml for storing these items.
If it was me, I would either you a secureSharedPref if it was simple things like userId, Token, or things like that that are fairly harmless. Of course it will encrypt them, but worst case if they got your token, they could make a few API calls if they knew what they were doing, unlikely. Now storing things like password, bank info, medical records, or anything else sensitive definitely should be in a Database. In fact, I would go one step further and layer it with SQLCipher.
So long story short is it depends on what you are storing and the risk assessment of it's content being accessed and each app will be different.
Absolutely nothing wrong with storing some static variables or singletons. Anyone building an enterprise level application will have a fair amount of statics in their application if it is architected in a good way.
Im saving datas from my db/user into a gson formated ArrayList in SharedPreferences. Now my question :
Is it safe to save these datas (or data in general) into Sharedpreferences. Are users able to read these gson Arraylists out ? Maybe from SD card ,in a folder or somewhere else.
Thank you !
They are stored as xml files in your app directory, with permissions that allow only your app to access them. But on rooted device they are easily accessible. If you are concerned with security then you may use encryption, those projects might be usefull to you:
https://github.com/rtoshiro/SecureSharedPreferences
https://github.com/sveinungkb/encrypted-userprefs
still those projects does not give you 100% guarantee, hacker may decompile your apk and find keys used to encrypt shared preferences. So if your data is of use only for short time then remember to remove it from your device once user has finished using it. You may for example keep data on server and download it only when needed, caching locally only for short time - when its needed.
SharedPreferences is just a file located in phone private memory. So user can't access it but root can. Root can everything and many users have root's nowadays. You shouldn't store fragile data there
Android SharedPreference security
You can read all shared preferences Data
The SharedPreferences class provides a general framework that allows
you to save and retrieve persistent key-value pairs of primitive data
types.
To see the information in the store you need to know the important thing from the data. This will make reading through the information super easy. But as simple as it's to keep a tiny bit of data as difficult it's to keep and browse large structured data since you need to define key for every data, in addition you can't really search inside the data except you've got a certain concept for naming the secrets.
Please read Android SharedPreference security
I'm creating an app that will need, at the most, probably 16 account's basic information. This includes several items per account such as name, password, and some basic settings. This information will be used periodically throughout the app to access information on the web, and display it to the user as needed. I will probably also be storing other information, per account, in a SQL file so it can be searched, categorized and displayed when requestedd.
I am going to use a Pref Fragment to add/edit each of these account's main information for simplicity (they are all identical in format, just different values) but as I started reading on the differences between shared preferences and SQL, there are alot of pros and cons for using each.
Where would the best place be to store this basic information?
Is this information, including passwords more secure in one vs the other from outside prying eyes?
Some people say that shared preferences can sometimes get corrupted... is that something I need to worry about?
I've never had problems with corrupted shared prefs. If you're only ever going to have around 16 account entries, I think shared prefs would be fine (and easier to implement than a Sqllite db). If you do use shared prefs, just make sure to hash or otherwise avoid saving passwords in plain text. Pref files, although normally restricted (if you specify MODE_PRIVATE) still can be accessed when a phone is rooted.
After reading the documention it seems that onSaveInstanceStaate works per instance (as the name suggests). I am just wondering what the preffered method of storing data is so that it is available for all instances of that activity?
As MaciejGorski mentioned in his comment, there are different levels of data storage available in Android:
Shared preferences
Internal storage
External storage
SQLite database
Network
From personal experience, the lower you go down this list, the more complicated your implementation will become. Thus, if you are simply trying to save simple data for your app to be shared among different instances of an activity (or of multiple activities), shared preferences are certainly the way to go. You can even create private shared preferences, which only your app can access.
In any case, check out this SO answer for how to implement them: How to use SharedPreferences in Android to store, fetch and edit values
my application consists of < 10 activities, which cover the wizard part. Each of these activities should collect user data and save the current status, which should be resumed, if the application is unexpectedly terminated.
Now, as the collected data seems to be 'private', the Dev Guide suggests three possibilities to save data:
Shared PreferencesSeems appropriate for my purpose; key/value would be perfectly fine for my kind of data
Internal StorageImo an I/O on every intent is an overkill
SQLite DatabaseFine, too
The thing I'm curious about now, is this the right approach to choose a home for my data? Are there any guidelines or best practices concerning storage on Android devices?
Shared Preferences uses IO - as it just an xml file in data folder of your application. Choose the one which simplier for you to implement. I would use Shared Preferences.
As for "home for data" - it is ok. The storage possibilities are already well-designed for you, so you shouldn't be worry about it. Just use the one which fits your purposes the best.