I'm using the following method to delete a key element on the SharedPreferences of my app. I'm calling it from within a fragment. The problem is that the element is never deleted from SharedPreferences and I get no LogCat output. Is there something wrong with this method? Context perhaps? The deleteFromSharedPreferences is located in a class called Utils and the triggering method is located on a fragment called PagerFragment. Any feedback would be greatly appreciated.
public class PagerFragment extends Fragment {
private void deleteCity() {
deleteFromSharedPref(mCityId, getContext());
}
}
public class Utils {
public static void deleteFromSharedPref(String key, Context context) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(key);
editor.apply();
}
}
Related
I am trying to catch and store the file path selected by user using registerForActivityResult. It returns the path, I can print the path but I am not able to store it using SharedPreferences class as it requires an app context which I cannot get using getApplicationContext() in static SettingsFragment.
public class SettingsActivity extends AppCompatActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
protected void onCreate(Bundle savedInstanceState) {...}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {...}
public class SettingsFragment extends PreferenceFragmentCompat {
ActivityResultLauncher<String> mGetContent = registerForActivityResult(
new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
#Override
public void onActivityResult(Uri uri) {
Log.i("MYAPP", "File selected:" + uri.toString());
// the added code is right below.
sharedPreferences = getSharedPreferences( BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE );
editor = sharedPreferences.edit();
editor.putString("audio_filename", uri.toString());
editor.apply();
}
});
#Override
public boolean onPreferenceTreeClick(Preference preference) {
String key = preference.getKey();
if (key.equals("audio_filename")) {
mGetContent.launch("*/*");
return true;
}
return super.onPreferenceTreeClick(preference);
}
}
}
The code I used from documentation but it seems missing integration between SharedPreferences and registerForActivityResult.
UPDATE1 (Clarification): This is a podcast player, actually I try to play audio using MediaPlayer class. The app has MainActivity and SettingActivity. The idea is the SettingActivity is to select an audio file and save its file path (SharedPreferences) then on the next app start (MainActivity retrieves last file path from SharedPreferences) I do not need to select it again but continue listening selected file instead.
UPDATE2: When I define SharePreferences it asks me to remove static from SettingsFragment definition. But when I run the app an error thrown:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.audiotranscriptd/com.example.audiotranscriptd.SettingsActivity}: java.lang.IllegalStateException: Fragment com.example.audiotranscriptd.SettingsActivity.SettingsFragment must be a public static class to be properly recreated from instance state.
Found solution here . It appears in Fragment the getSharedPreferences should be called with getActivity(), like this
sharedPreferences = getActivity().getSharedPreferences(BuildConfig.APPLICATION_ID + "_preferences", Context.MODE_PRIVATE);
Works for me!
I have a class A this class does not extend or implement any other classes. I then have an Class B, this class also does not extend or implement any other classes.
My Class B is solely used to manage SharedPreferences :
private static SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
Here is the problem method in Class B:
public static void setCurrentUsersEmail(String email){
sharedPreferences.edit().putString("userEmail",email).commit();
}
Now class A is a database manager and needs to store the users email in SharedPreferences for later use. I do this with the following code:`
MySharedPrefs.setCurrentUsersEmail(currentUsersEmail);
However, when i try run the code in Class A i get the error:
java.lang.ExceptionInInitializerError
at com.test.Android.MySharedPrefs.setCurrentUsersEmail(MySharedPrefs.java:0)
I am really confused as to why this happens I couldn't find a solution online after searching either, I use my sharedPreferences class in other activities perfectly fine. Is it an activity problem?
Any help is much appreciated.
You can use singleton for your requirement :
public class MyPrefs {
private static MyPrefs myPrefs;
private SharedPreferences sharedPreferences;
private MyPrefs(Context context){
sharedPreferences=context.getSharedPreferences("MyPREFERENCES", Context.MODE_PRIVATE);
}
public static MyPrefs getInstance(Context context){
if(myPrefs==null)
myPrefs=new MyPrefs(context);
return myPrefs;
}
public void setCurrentUsersEmail(String email){
sharedPreferences.edit().putString("userEmail",email).commit();
}
}
You can put email in this way :
MyPrefs.getInstance(context).setCurrentUsersEmail(currentUsersEmail);
You need to pass context at first time for the reference of sharedPreferences in your Class.
or
From Activity call MyPrefs.getInstance(context) at once
Then you can call without context
MyPrefs.getInstance().setCurrentUsersEmail(currentUsersEmail);
getInstance() method :
public static MyPrefs getInstance(){
if(myPrefs==null) throw new AssertionError("MyPrefs cannot be null");
else
return myPrefs;
}
You could do this , in any activity, dont need to create a new method:
To save:
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putString("email", "YOURUSEREMAIL#.email");
editor.commit();
To restore:
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
String restoredText = prefs.getString("email", null);
You cant call MyPrefs.aFunctionYouCreated() !!!
I'm building an android project that contains SharedPreferences.
My SharedPreferences works fine and I tested it in mutiple activity. but in a class that I defined for global variables, defining that SharedPreferences will cause force close (eclipse didn't show any error in codes).
public class Globals extends Application {
final SharedPreferences s = getSharedPreferences("Prefs", MODE_PRIVATE);
}
What is the problem ?
You should pass the Context and use
SharedPreferences prefs = Context.getSharedPreferences(
"Prefs", Context.MODE_PRIVATE);
Create a constructor and pass a Context variable as a parameter. Any activity that want to use this preference then you have to pass the activity. Here's the code given below:
public class Globals extends Application {
private Context context;
public Globals (Context context) {
this.context = context;
}
SharedPreferences myPref = context.getSharedPreferences("Prefs", Context.MODE_PRIVATE);
}
You can't run getSharedPreferences() in the actual class. Everything you do must be in the Application's onCreate method. If you try to run this in the class, it will fail since it has not been initialized yet. Think of it almost as an activity, since both the activity and the application have a lifecycle.
Try the following:
public class Globals extends Application {
#Override
public void onCreate() {
super.onCreate();
final SharedPreferences s = getSharedPreferences("Prefs", MODE_PRIVATE);
}
}
This is the save() method in my app:
public void save() {
Context context;
SharedPreferences sp = context.getSharedPreferences("gameSave",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("X", player.getX());
editor.putInt("Y", player.getY());
editor.putInt("level", player.getLevel());
editor.putFloat("xp", player.getXp());
editor.commit();
}
I have been trying to get this to work for a while now, but the getSharedPreferences (String name, int mode) has not been working for me. It doesn't come up on it's own, context.getSharedPreferences() works, but that yields a NullPointerException, I think because of my context. I have tried save(Context context){} as a constructor, but calling that from another method with context declared inside of that method does not work either. I've looked at many examples, but none of them have worked for me. So how can I get getSharedPreferences() to work?
EDIT: I have a class GameScreen and a class SaveManager. When I save in Gamescreen this is the code I use:
Savemanager savemanager;
savemanager.save();
state = GameState.Running;
And I have my class SaveManager:
package com.package.game;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
public class SaveManager extends Activity {
private Player player = GameScreen.getPlayer();
public void save() {
SharedPreferences sp = getSharedPreferences("gameSave",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("X", player.getX());
editor.putInt("Y", player.getY());
editor.putInt("level", player.getLevel());
editor.putFloat("xp", player.getXp());
}
}
And when I save in GameScreen my app crashes and I get this logcat:
02-20 01:39:31.979: E/AndroidRuntime(1368): FATAL EXCEPTION: Thread-119
02-20 01:39:31.979: E/AndroidRuntime(1368): java.lang.NullPointerException
02-20 01:39:31.979: E/AndroidRuntime(1368): at com.package.game.GameScreen.updateLevelUp(GameScreen.java:364)
Line 364 is the line savemanager.save();. I have no idea why this crashes my app.
getSharedPreferences() is a Context method. If save() is in a class that extends Context, such as Activity, you don't have to do context.getSharedPreferences(), so you can do, as you put it "the method by itself".
However, if save isn't in a class that extends Context, for it to be able to call getSharedPreferences(), it needs to have a Context variable passed off. This means that what you were doing by simply making a context variable isn't enough (and that code shouldn't compile, there would be an error thrown about how the context variable hasn't been initialized). And since Contexts aren't made using a constructor, your method hits a dead end.
However, you are close. For the sake of explanation, you can make a static method that accepts in a Context and does the saving. static since this method really shouldn't need an object instance, it can be self-contained:
public static void save(Context context) {
if (context == null)
throw new RuntimeException ("Context is null, what are you doing?");
SharedPreferences sp = context.getSharedPreferences("gameSave",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("X", player.getX());
editor.putInt("Y", player.getY());
editor.putInt("level", player.getLevel());
editor.putFloat("xp", player.getXp());
editor.commit();
}
Now if this method was part of a class for example named StaticUtils, you can call save:
Through an Activity: StaticUtils.save(YourActivityClass.this); or StaticUtils.save(this); depending on the scope (eg if inside an anonymous inner function, you'd use YourActivityClass.this).
Fragment: StaticUtils.save(getActivity());
BroadcastReceiver: StaticUtils.save(context);
A View (eg the View passed on when onClick() is called: StaticUtils.save(v.getContext());
Just keep in mind that the earilest you can do saving in an Activity is onCreate() anything before will fail and the Exception should clearly indicate that.
A simple demo. No extending anything, no fancy making of Context:
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StaticUtils.save(this);
SharedPreferences prefs = getSharedPreferences ("gameSave", Context.MODE_PRIVATE);
System.out.println ("X is " + prefs.getInt ("X",-1));
}
}
StaticUtils.java
public class StaticUtils {
public static void save(Context context) {
if (context == null)
throw new RuntimeException ("Context is null, what are you doing?");
SharedPreferences sp = context.getSharedPreferences("gameSave",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("X", 11);
editor.putInt("Y", 24);
editor.putInt("level", 3);
editor.putFloat("xp", 100);
editor.commit();
}
}
I have a problem with SharedPrefences and initializations.
My application has a login where you insert an user, and for that user, you have a specific preferences... so, I need to save preferences according to the user to load it later.
I though that SharedPrefences would be the solution, and it really is I think, but I have a problem to initialize they: I have an Activity class called Options. It has static functions that returns the value of the options... but I have a problem, I call that functions before I have create that activity (intent), so I think that the functions are returning the last value that the last user has selected on the options...
How can I load the options before that calls?
I though to use first of all an Intent sending extra data with the user and in onCreate() of the Options, initialize they, but if I make an intent, then the Options will appear (xml will load).
Any help pls?
Try something like this.... adding methods for each variable you want to save.
public class PreferenceManager {
private static PreferenceManager self;
private SharedPreferences preferences = null;
private SharedPreferences.Editor editor = null;
private boolean isInitialised = false;
private static final String MY_PREFERENCE = "mypreferencekey";
private String myPreference = null;
public void initialise(Context context) {
if (!isInitialised) {
preferences = context.getSharedPreferences("MyPreferencePlace", Context.MODE_PRIVATE);
editor = preferences.edit();
loadPreferences();
isInitialised = true;
}
}
public static PreferenceManager getInstance() {
if (self == null) {
self = new PreferenceManager();
}
return self;
}
private PreferenceManager() {
}
public void setPreference(String newPreferenceValue) {
this.myPreference = newPreferenceValue;
savePreferences();
}
public String getPreference(){
return myPreference;
}
private void savePreferences() {
editor.putString(MY_PREFERENCE, myPreference);
editor.commit();
}
private void loadPreferences() {
myPreference = preferences.getString(MY_PREFERENCE, null);
}
}
All the SharedPreferences need is a context and it can be initialized. As your application always opens an Activity to start with, you always have a context to work with.
I would advise you to wrap the SharedPreferences in a Singleton class and just pass a context as parameter at the getInstance method. You should be able to access your shared preferences at all Activities this way.
I work on the dependency injector for android, and content of shared preferences is already injectable into annotated fields ( see: https://github.com/ko5tik/andject , PreferenceInjector). Patches and improvements are welcome. Saving of preferences comes soon