Android SharedPreferences we fragmentach


90

Próbuję odczytać SharedPreferences wewnątrz fragmentu. Mój kod jest tym, czego używam do uzyskiwania preferencji w innych działaniach.

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

Otrzymuję błąd

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

Próbowałem skorzystać z tych linków, ale bez powodzenia Dostęp do SharedPreferences za pomocą metod statycznych i Static SharedPreferences . Dziękuję za rozwiązanie.

Odpowiedzi:


254

Metoda getSharedPreferencesjest metodą Contextobiektu, więc samo wywołanie getSharedPreferences z a Fragmentnie zadziała ... ponieważ nie jest to Context! (Aktywność jest rozszerzeniem Context, więc możemy wywołać z niej getSharedPreferences).

Musisz więc uzyskać kontekst aplikacji przez

// this = your fragment
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);

1
getSharedPreferences ("pref", 0); zero (0) oznacza co prywatne / publiczne?
Kailas

@Kailas poprawne, tryb, tj. WORLD_READABLE ect. developer.android.com/reference/android/content/… , int)
Jug6ernaut

5
0 jest analogiczne do MODE_PRIVATE (lub Context.MODE_PRIVATE, jeśli jest używane w klasie, która nie jest rozszerzeniem Context, na przykład fragmentem). Oznacza to, że tylko dana aplikacja ma dostęp do preferencji. Nie należy używać WORLD_READABLE ani WORLD_WRITEABLE, ponieważ są one przestarzałe w API 17+, nie wspominając o zagrożeniu bezpieczeństwa.
Ankit Aggarwal,

1
czy to thissłowo kluczowe jest potrzebne podczas wykonywania this.getActivity().getShared..?
Subby

2
@Subby nie, jawne wywołanie po prostu „tego” nigdy nie jest konieczne. Zrobiłem to z osobistych preferencji, ponieważ nienawidzę niejednoznacznych wywołań metod. Jedynym momentem, w którym „this” jest wymagane, jest próba uzyskania dostępu do nadrzędnego niestatycznego obiektu, gdy znajdujesz się poza jego zakresem, będąc w anonimowej klasie wewnętrznej / interfejsie.
Jug6ernaut

14

Zaznaczona odpowiedź nie zadziałała dla mnie, musiałem użyć

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

EDYTOWAĆ:

Lub po prostu spróbuj usunąć this:

SharedPreferences prefs = getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);

8
Zaznaczona odpowiedź nie działa, ponieważ uzyskujesz dostęp do domyślnych wspólnych preferencji. Lepszym projektem jest przechowywanie twoich preferencji nie jako wspólnego obiektu, ale w oddzielnej i prywatnej przestrzeni, o co tutaj chodzi w pytaniu i odpowiedzi.
zeeshan

8

Uwaga: ta odpowiedź udzielona przez mojego użytkownika jest poprawna.

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

Jeśli jednak spróbujesz pobrać cokolwiek z fragmentu przed wywołaniem metody onAttach getActivity (), zwróci wartość null.


3

Możesz sprawić, że SharedPrefencesw onAttachmetodzie fragment tak:

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


1

getActivity()i onAttach()nie pomogło mi w tej samej sytuacji,
może zrobiłem coś złego,
ale! Znalazłem inną decyzję
Utworzyłem pole Context thisContextw moim fragmencie
I otrzymałem bieżący kontekst z metody onCreateView
i teraz mogę pracować z udostępnionym pref z fragmentu

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

1

Aby zdefiniować preferencje we fragmencie: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Aby wywołać inną czynność lub podzielić dane preferencji: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...


0

Możliwe jest pobranie kontekstu z pliku Fragment

Po prostu zrób

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

Możesz również dołączyć AndroidViewModelw onCreateViewmetodzie, która implementuje metodę, która zwraca kontekst aplikacji

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

0

Może to komuś przyda się po kilku latach. Nowym sposobem dostania się do SharedPreferences()wnętrza fragmentu na Androidx jest implementacja dogradle dependencies

implementation "androidx.preference:preference:1.1.1"

a następnie wewnętrzne wywołanie fragmentu

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

0

użyj wymaganej aktywności we fragmencie kotlin

 val sharedPreferences = requireActivity().getSharedPreferences(loginmasuk.LOGIN_DATA, Context.MODE_PRIVATE)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.