Android SharedPreferences in Fragment

90

Estou tentando ler SharedPreferences dentro do Fragment. Meu código é o que eu uso para obter preferências em qualquer outra atividade.

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

Eu recebo erro

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

Tentei seguir esses links, mas sem sorte acessando SharedPreferences por meio de métodos estáticos e Static SharedPreferences . Obrigado por qualquer solução.

Marca
fonte

Respostas:

256

O método getSharedPreferencesé um método do Contextobjeto, portanto, apenas chamar getSharedPreferences de um Fragmentnão funcionará ... porque não é um Context! (Activity é uma extensão de Context, então podemos chamar getSharedPreferences a partir dele).

Então você tem que obter o contexto de seus aplicativos por

// this = your fragment
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Jug6ernaut
fonte
1
getSharedPreferences ("pref", 0); zero (0) significa que privado / público?
Kailas,
@Kail como correto, o modo, ou seja, WORLD_READABLE ect. developer.android.com/reference/android/content/… , int)
Jug6ernaut
5
0 é análogo a MODE_PRIVATE (ou Context.MODE_PRIVATE se usado em uma classe que não é uma extensão de Context, como um Fragment). Isso significa que apenas o aplicativo em questão pode acessar as preferências. Você não deve usar WORLD_READABLE ou WORLD_WRITEABLE, pois eles estão obsoletos na API 17+, sem mencionar uma ameaça à segurança.
Ankit Aggarwal
1
esta thispalavra - chave é necessária ao fazer this.getActivity().getShared..?
Subby
2
@Subby não, chamar explicitamente apenas "this" nunca é necessário. Fiz isso por preferência pessoal, pois odeio chamadas de método ambíguas. O único momento em que "isto" é necessário é quando você está tentando acessar um objeto pai não estático quando você está fora de seu escopo em uma classe / interface interna anônima.
Jug6ernaut
14

A resposta marcada não funcionou para mim, eu tive que usar

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

EDITAR:

Ou apenas tente remover this:

SharedPreferences prefs = getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Leon
fonte
8
A resposta marcada não funcionou para você porque você está acessando as preferências compartilhadas padrão. Um design melhor é armazenar suas preferências não como um objeto compartilhado, mas em um espaço separado e privado, que é sobre o que a pergunta e a resposta tratam aqui.
zeeshan de
8

Como observação, esta resposta fornecida pelo usuário acima de mim está correta.

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

No entanto, se você tentar obter qualquer coisa no fragmento antes de onAttach ser chamado de getActivity (), retornará nulo.

ed209
fonte
3

Você pode fazer o método SharedPrefencesin onAttachde fragmento como este:

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

getActivity()e onAttach()não me ajudou na mesma situação
talvez eu tenha feito algo errado
mas! Eu encontrei outra decisão
Eu criei um campo Context thisContextdentro do meu Fragment
e peguei um contexto atual do método onCreateView
e agora posso trabalhar com pref compartilhada do fragmento

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

Para definir a preferência em Fragment: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Para chamar outra atividade ou fragmentar os dados de preferência: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...

user11809346
fonte
0

É possível obter um contexto de dentro de um Fragment

Apenas faça

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;
    }
}

Você também pode anexar um AndroidViewModelno onCreateViewmétodo que implementa um método que retorna o contexto do aplicativo

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
fonte
0

Talvez isso seja útil para alguém depois de alguns anos. Uma nova maneira, no Androidx, de obter SharedPreferences()fragmentos internos é implementar emgradle dependencies

implementation "androidx.preference:preference:1.1.1"

e então, dentro da chamada do fragmento

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

use a atividade necessária no fragmento kotlin

 val sharedPreferences = requireActivity().getSharedPreferences(loginmasuk.LOGIN_DATA, Context.MODE_PRIVATE)
reza rahmad
fonte