Reading SharedPreferences stored by Activity in a Service? - android

I am using a class to create a background service which runs all the time. When using the Android app the user can enter data which are stored via SharedPreferences. The storing works well and the stored data are available in the activity which stores it. I am using SharedPreferences like this:
SharedPreferences mPrefs = getSharedPreferences("Identifier",Context.MODE_PRIVATE);
In the service I am trying to access to this values that are stored in the activity. Therefore I am using the SharedPreferences the same way:
SharedPreferences mPrefs = getSharedPreferences("Identifier",Context.MODE_PRIVATE);
I am storing an object this way in the activity:
Gson gson = new Gson();
SharedPreferences.Editor prefsEditor = mPrefs.edit();
String json = gson.toJson(myObject);
prefsEditor.putString("value",json);
prefsEditor.commit();
And try to read it this way, but json returns null:
Gson gson = new Gson();
String json = mPrefs.getString("value",null);
Any idea what might be wrong? Is the context wrong? But how should it be?

Try to use a default shared preferences instance, which is shared across all your Activity and Service classes, use below method.
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this/*context*/);
This is the best way for storing primitives datatype(like booleans) or serializable objects. However, if you're capturing a lot of JSON data, you might consider using an SQLite database instead.

The problem was that the service is running in a different process. Therefore I used tray which works perfectly for multiple processes: https://github.com/grandcentrix/tray.

Related

How to send object/state to whole application/all fragments?

I am making an app, where there is a searchbox in Main Activity and bottom navigation. In searchbox, the user choose te location, then sends the query to the weather API. I want to pass the object, which is the response from the API, to all fragments in my app. What is the easiest way to do that?
You can use a ViewModel to store your data. Also, using MutableLiveData you can dynamically update your UI to the changes of the model.
Use RxJava to create an EventBus object, which can hold an BehaviorSubject with the latest published data. Again, you can subscribe to this data and update your UI automatically.
Use a Room or Realm to store data, if you need the location between multiple app sessions.
You need to send whole object through this in your application and access it anywhere you want to
Step 1:
Store your data in list you want to like:
ArrayList<FeaturedProductDataModel> featuredProductsDataModelArrayList;
///////////get data and store in ArrayList///////////////////
featuredProductsDataModelArrayList = new ArrayList<(listofhome.getFeaturedProducts());
Step 2:
Declare Shared Preference and put data in it to further use in all application
featuretopprefernce = getActivity().getSharedPreferences("homelist", Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = featuretopprefernce.edit();
//Set the values
Gson gson = new Gson();
String listofbusiness = gson.toJson(featuredProductsDataModelArrayList);
prefsEditor.putString("featuredProductsDataModelArrayList", listofbusiness);
prefsEditor.apply();
Step 3:
In recieving activity or fragment create a list and put data in it
ArrayList<FeaturedProductDataModel> dataModelArrayList;
SharedPreferences featuredprefernce;
featuredprefernce = getActivity().getSharedPreferences("homelist", Context.MODE_PRIVATE);
featuredlist = featuredprefernce.getString("featuredProductsDataModelArrayList",null);
Gson gson = new Gson();
Type type = new TypeToken<List<FeaturedProductDataModel>>(){}.getType();
dataModelArrayList = gson.fromJson(featuredlist, type);
You'll get your data in dataModelArrayList now use it as you like.
Actually, you have several options:
To save received data into the local database (you can use Room from Jetpack). And then to load the data from the database to the screen you need separately.
Or you can save the data into memory: it can be something like a DI container.
Also, you can use RxJava caching or Retrofit caching.
The second solution is the simplest for you.

Shared Preferences is read as the wrong type

I'm reading SharedPreferences in my app at startup, and after a few runs it will crash and tell me that I'm trying to cast from a String to a Boolean. Below is the code that I use to read and write this value.
// Checks if the realm has been copied to the device, and copies it if it hasn't.
private void copyRealm() {
final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if (!sharedPreferences.getBoolean(getString(R.string.pref_copied), false)) {
// Copy the realm to device.
final String path = copyBundledRealmFile(getResources().openRawResource(R.raw.realm), getString(R.string.realm_name));
// Save the path of the realm, and that the realm has been copied.
sharedPreferences.edit()
.putBoolean(getString(R.string.pref_copied), true)
.putString(getString(R.string.pref_path), path)
.apply();
}
}
The two strange things are that it doesn't start happening for a few builds, and so far it has only happened on a simulator. I haven't been able to check a physical device yet, but I've also been running this code without change for several months and had no trouble.
Why would I be getting this message?
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
at android.app.SharedPreferencesImpl.getBoolean(SharedPreferencesImpl.java:293)?
Take a look at this question Android getDefaultSharedPreferences.
It seems it's a better idea to just use
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
or
SharedPreferences references1=getSharedPreferences("some_name",MODE_PRIVATE);
instead of using
SharedPreferences preferences= getDefaultSharedPreferences(this);
From the documentation:
getPreferences(MODE_PRIVATE) retrieves a SharedPreferences object for
accessing preferences that are private to this activity. This simply
calls the underlying getSharedPreferences(String, int) method by
passing in this activity's class name as the preferences name.
I regularly use one of these two approaches and had no problem of any kind so far.

What are things to keep in mind while using Shared Preferences android?

I am working on a simple android application.
The application has the functionality of user login which is connected to php.
I am successful in getting login functionality done well. What I want now is to save the username so that I can use it anywhere and anytime in my application. After going through some SO threads I came to know that this is doable using android sharedPreferences.
But prior to implementing them I want to know some stuff that I should keep in mind while using sharedPreferences like
what is basic task of shared preferences?
what things to keep in mind while actually using them?
what is proper way to programatically implement them in code?
and finally how to remove them after they are used?
what is basic task of shared preferences?
SharedPreferences are essentially used when you need your application to store persistent data. I consider using it when a Database is (for the sheer purposes of size / data to be stored) isn't really required.
what things to keep in mind while actually using them?
You can save just about anything that you typically require for your application to perform it's task. For example, in a gaming application, you could store the user's scores. However, since the SharedPreferences file/s can be accessed by anyone on a rooted device, you wouldn't want to store passwords. If you absolutely must store them anyway, you should implement your own algorithm to encrypt it. In an app of mine, I store URL's to a user's profile picture on Facebook and Twitter. That is already in the public domain.
what is proper way to programatically implement them in code?
If you are going to use SharedPreference in say, just one or two Activities, you use something like this to add values to the SharedPreference file:
// THE SHAREDPREFERENCE INSTANCE
SharedPreferences sharedPrefs;
// THE EDITOR INSTANCE
Editor editor;
// A CONSTANT STRING TO PROVIDE A NAME TO THE SHAREDPREFERENCE FILE
private static final String PRIVATE_PREF = "some_file_name";
// INSTANTIATE THE SHAREDPREFERENCE INSTANCE
sharedPrefs = getApplicationContext().getSharedPreferences(PRIVATE_PREF, Context.MODE_PRIVATE);
// INSTANTIATE THE EDITOR INSTANCE
editor = sharedPrefs.edit();
// ADD VALUES TO THE PREFERENCES FILE
editor.putLong(UNIQUE_KEY_NAME, VALUE);
editor.putString(UNIQUE_KEY_NAME, VALUE);
editor.putString(UNIQUE_KEY_NAME, VALUE);
editor.putString(UNIQUE_KEY_NAME, VALUE);
// THIS STEP IS VERY IMPORTANT. THIS ENSURES THAT THE VALUES ADDED TO THE FILE WILL ACTUALLY PERSIST
// COMMIT THE ABOVE DATA TO THE PREFERENCE FILE
editor.commit();
To fetch the values out of the file:
String someString = sharedPrefs.getString(UNIQUE_KEY_NAME, null);
long someLong = sharedPrefs.getLong(UNIQUE_KEY_NAME, 0);
If you need to reuse the contents / values from the SharedPreference file, this here is a nice tutorial on creating a helper class that will let any number of Activites to access the values instead of coding the above in every single one of them: http://megasnippets.com/source-codes/java/sharedpreferences_helper_class_android
and finally how to remove them after they are used?
// INSTANTIATE THE EDITOR INSTANCE
editor = sharedPrefs.edit();
// TO CLEAR A SELECT FEW OF THE VALUES:
editor.remove(KEY_FOR_THE_VALUE_TO_BE_REMOVED);
// ALTERNATIVELY, TO CLEAR ALL VALUES IN THE FILE:
editor.clear();
Note: Any SharedPreferences file/s you may create will be removed when the user manually clears the app data from the device's Settings.
Links For Further Reading:
http://www.vogella.com/articles/AndroidFileBasedPersistence/article.html
http://saigeethamn.blogspot.in/2009/10/shared-preferences-android-developer.html
http://www.mybringback.com/tutorial-series/12260/android-sharedpreferences-example/
http://www.androidhive.info/2012/08/android-session-management-using-shared-preferences/
How to Save/Read 'username' from SharedPreferences Persistent Storage
Basic Task:
Persistent storage.
Keep In Mind:
Is there so much data that you might be better off using a database or flat file storage?
Proper Way to Save and Read "username":
String key = "username";
String value = "John Doe";
// Save
SharedPreferences.Editor editor = context.getSharedPreferences(MY_PREFS_NAME, Context.MODE_PRIVATE).edit();
editor.putString(key, value);
editor.commit();
// Read
String def = "";
SharedPreferences settings = context.getSharedPreferences(MY_PREFS_NAME, Context.MODE_PRIVATE);
if(!settings.contains(key)) {
// Warn user that there is nothing to read and/or return a default value: "def"
}
String value = settings.getString(key, def);
About the basic task : you can read on Storage Options at developer.android.com.
About the keep in mind : try to avoid saving sensetive data to your application in shared preferences,because user can easily access the data.
You can find your shared preferences xml file in /data/data/your_application.package.name/shared_prefs/shared_prefs_name.xml
Implementation :
Usualy I am creating class with static methods like this :
public class MySharedPreferences {
private static final String APP_SHARED_PREFS = "my_prefs";
private static final String KEY_LOGIN = "username";
public static void setUsername(Context context, String username) {
SharedPreferences sharedPreferences = context.getSharedPreferences(APP_SHARED_PREFS, Activity.MODE_PRIVATE);
Editor editor = sharedPreferences.edit();
editor.putString(KEY_USERNAME, login);
editor.commit();
}
public static String getUsername(Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(APP_SHARED_PREFS, Activity.MODE_PRIVATE);
return sharedPreferences.getString(KEY_USERNAME, null);
}
}

Can I get data from shared preferences inside a service?

I'm developing an android application. I'm using android 2.2
In my application I am capturing GPS data and sending it to service with the 1 hour time interval. If user exits from application it's also working (it is required).
I'm using 2 services (User defined), one for capturing GPS data and other for sending to the server.
Here my doubt
In service, can we use shared preferences.
If we store any data in shared preferences in any activity of the application, will we be able to use that data in service with the help of shared preferences?
You can access the default shared preferences instance, which is shared across all your Activity and Service classes, by calling PreferenceManager.getDefaultSharedPreferences(Context context):
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
This is great for storing simple primitives (like booleans) or serializable objects. However, if you're capturing a lot of location data, you might consider using a SQLite database instead.
I find the solution.
Inside a service we call the following method to get the shared preferences
myapp.bmodel.getApplicationContext().getSharedPreferences("myPrefs_capture_gps_per_hour", Context.MODE_PRIVATE);
In the above code myapp is a object of the application class which is derived from Application
You need a context to get access to shared preferences. The best way is to create MyApplication as a descendant of Application class, instantiate there the preferences and use them in the rest of your application as MyApplication.preferences:
public class MyApplication extends Application {
public static SharedPreferences preferences;
#Override
public void onCreate() {
super.onCreate();
preferences = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);
For example, if you need access to your preferences somewhere else, you may call this to read preferences:
String str = MyApplication.preferences.getString( KEY, DEFAULT );
Or you may call this to save something to the preferences:
MyApplication.preferences.edit().putString( KEY, VALUE ).commit();
(don't forget to call commit() after adding or changing preferences!)
Yes Shivkumar, you can use your share preferences in any kind of services as normal as you are using in your Activity.
same like
SharedPreferences preferences = getSharedPreferences("<PrefName>",
MODE_PRIVATE);
There are two ways to create instance of SharedPreference:
Case 1:
SharedPreferences preferences = activity.getSharedPreferences("<PrefName>", MODE_PRIVATE);
Case 2:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Notice if you create a preference with the same name (case 1) or same context (case 2) even at different places, it's still the same, and can share data, obviously.

Saving an entire Bundle to SharedPreferences

Assuming a method of mine was passed a Bundle already filled with data to be saved, is there a way to save it to SharedPreferences without taking it apart to ints, floats, Strings, etc.?
I prefer the convenience of writing/committing it all in "one fell swoop", so if this isn't possible using SharedPreferences, what other persistent storage approach would you recommend?
SharedPreferences are serialized to XML, which is why you can only use simple types. You'll either have to do your own conversion of the bundle to individual SharePreferences properties or serialize the bundle some other way to disk.
Here's a good reference document discussing the various possibilities of storing data in Android: http://developer.android.com/guide/topics/data/data-storage.html
as far as I know, you can save only primitive data (and their wrappers) to SharedPreferences
why don't you create your own helper method which will iterate through Bundle and save all values from it to SharedPreferences?
Note: If you are using Gson in your project then I think this is a better solution.
I simply used Gson from Google to serialize the specified object into its equivalent JSON representation:
Use this dependency
implementation 'com.google.code.gson:gson:2.8.6'
Code:
Gson gson = new Gson();
String dataToJson = gson.toJson(modelObj);
Then I stored dataToJson as a string in SharedPreferences.Simple!
At the time of string extraction:
String myStoredVal = Value stored in SharedPreference.
GsonBuilder builder = new GsonBuilder();
builder.setPrettyPrinting();
Gson gson = builder.create();
MyModel modelObj = gson.fromJson(prodDataStr, MyModel.class);

Categories

Resources