Preferencias compartidas de Android en fragmentos

90

Estoy tratando de leer SharedPreferences dentro de Fragment. Mi código es lo que utilizo para obtener preferencias en cualquier otra actividad.

     SharedPreferences preferences = getSharedPreferences("pref", 0);

Me sale un error

    Cannot make a static reference to the non-static method getSharedPreferences(String, int) from the type ContextWrapper    

Intenté seguir estos enlaces pero no tuve suerte Accediendo a SharedPreferences a través de métodos estáticos y Static SharedPreferences . Gracias por cualquier solución.

marca
fuente

Respuestas:

254

El método getSharedPreferenceses un método del Contextobjeto, por lo que simplemente llamar a getSharedPreferences desde a Fragmentno funcionará ... ¡porque no es un Context! (La actividad es una extensión de Context, por lo que podemos llamar a getSharedPreferences desde ella).

Por lo tanto, debe obtener el contexto de sus aplicaciones

// this = your fragment
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Jug6ernaut
fuente
1
getSharedPreferences ("pref", 0); cero (0) significa qué privado / público?
Kailas
@Kailas correcto, el modo, es decir, WORLD_READABLE ect. developer.android.com/reference/android/content/… , int)
Jug6ernaut
5
0 es análogo a MODE_PRIVATE (o Context.MODE_PRIVATE si se usa dentro de una clase que no es una extensión de Context, como un Fragmento). Significa que solo la aplicación en cuestión puede acceder a las preferencias. No debe usar WORLD_READABLE o WORLD_WRITEABLE ya que están obsoletos en API 17+, sin mencionar una amenaza de seguridad.
Ankit Aggarwal
1
¿Es esta thispalabra clave necesaria al hacer this.getActivity().getShared..?
Subby
2
@Subby no, llamar explícitamente solo "esto" nunca es necesario. Lo hice por preferencia personal, ya que detesto las llamadas a métodos ambiguos. La única vez que se requiere "esto" es cuando está intentando acceder a un objeto principal no estático cuando está fuera de su alcance en una clase / interfaz interna anónima.
Jug6ernaut
13

La respuesta marcada no funcionó para mí, tuve que usar

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());

EDITAR:

O simplemente intente eliminar this:

SharedPreferences prefs = getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
León
fuente
8
La respuesta marcada no funcionó para usted porque está accediendo a las preferencias compartidas predeterminadas. Un mejor diseño es almacenar sus preferencias no como un objeto compartido sino en un espacio separado y privado, que es de lo que trata la pregunta y la respuesta aquí.
zeeshan
8

Como nota de precaución, esta respuesta proporcionada por el usuario que está arriba de mí es correcta.

SharedPreferences preferences = this.getActivity().getSharedPreferences("pref",0);

Sin embargo, si intenta obtener algo en el fragmento antes de que onAttach se llame getActivity () devolverá nulo.

ed209
fuente
3

Puede hacer que el SharedPrefencesen onAttachforma de fragmento de esta manera:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    SharedPreferences preferences = context.getSharedPreferences("pref", 0);
}
misbahm3
fuente
1

getActivity()y no onAttach()me ayudó en la misma situación
tal vez hice algo mal
pero! Encontré otra decisión Creé
un campo Context thisContextdentro de mi Fragmento
Y obtuve un contexto actual del método onCreateView
y ahora puedo trabajar con preferencias compartidas desde el fragmento

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {   
...   
thisContext = container.getContext();   
...   
}
Kirguduck
fuente
1

Para definir la preferencia en Fragmento: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Para llamar a otra actividad o fragmentar los datos de preferencia: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...

usuario11809346
fuente
0

Es posible obtener un contexto desde dentro de un Fragment

Solo haz

public class YourFragment extends Fragment {

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        final View root = inflater.inflate(R.layout.yout_fragment_layout, container, false);
        // get context here
        Context context = getContext();
        // do as you please with the context


        // if you decide to go with second option
        SomeViewModel someViewModel = ViewModelProviders.of(this).get(SomeViewModel.class);
        Context context = homeViewModel.getContext();
        // do as you please with the context
        return root;
    }
}

También puede adjuntar un AndroidViewModelen el onCreateViewmétodo que implementa un método que devuelve el contexto de la aplicación

public class SomeViewModel extends AndroidViewModel {

    private MutableLiveData<ArrayList<String>> someMutableData;
    Context context;

    public SomeViewModel(Application application) {
        super(application);
        context = getApplication().getApplicationContext();
        someMutableData = new MutableLiveData<>();
        .
        .
     }

     public Context getContext() {
         return context
     }
  }
davejoem
fuente
0

Quizás esto sea útil para alguien después de algunos años. Una nueva forma, en Androidx, de ingresar al SharedPreferences()fragmento es implementar engradle dependencies

implementation "androidx.preference:preference:1.1.1"

y luego, dentro de la llamada de fragmento

SharedPreferences preferences;
preferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(getActivity());
Stanojkovic
fuente