Android SharedPreferences во фрагменте


90

Я пытаюсь прочитать SharedPreferences внутри фрагмента. Мой код - это то, что я использую для получения предпочтений в любом другом действии.

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

Я получаю ошибку

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

Я попытался перейти по этим ссылкам, но безуспешно. Доступ к SharedPreferences с помощью статических методов и Static SharedPreferences . Спасибо за любое решение.

Ответы:


256

Метод getSharedPreferencesявляется методом Contextобъекта, поэтому простой вызов getSharedPreferences из a Fragmentне будет работать ... потому что это не контекст! (Activity является расширением Context, поэтому мы можем вызывать из него getSharedPreferences).

Итак, вы должны получить контекст своих приложений

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

1
getSharedPreferences ("pref", 0); ноль (0) что означает частное / публичное?
Кайлас

@Kailas правильный, режим, т.е. WORLD_READABLE ect. developer.android.com/reference/android/content/… , int)
Jug6ernaut,

5
0 аналогичен MODE_PRIVATE (или Context.MODE_PRIVATE, если используется в классе, который не является расширением контекста, например фрагментом). Это означает, что только соответствующее приложение может получить доступ к настройкам. Вы не должны использовать WORLD_READABLE или WORLD_WRITEABLE, поскольку они устарели в API 17+, не говоря уже об угрозе безопасности.
Анкит Аггарвал

1
это thisключевое слово необходимо при выполнении this.getActivity().getShared..?
Subby

2
@Subby нет, в явном вызове просто "this" нет необходимости. Я сделал это из личных предпочтений, так как ненавижу неоднозначные вызовы методов. Единственный раз, когда требуется "this", - это когда вы пытаетесь получить доступ к родительскому нестатическому объекту, когда вы находитесь за пределами его области действия, находясь в анонимном внутреннем классе / интерфейсе.
Jug6ernaut

14

Отмеченный ответ у меня не сработал, пришлось использовать

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

РЕДАКТИРОВАТЬ:

Или просто попробуйте удалить this:

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

8
Отмеченный ответ не сработал для вас, потому что вы получаете доступ к общим настройкам по умолчанию. Лучше всего хранить ваши предпочтения не как общий объект, а в отдельном частном пространстве, о чем здесь идет речь.
zeeshan

8

В качестве предостережения этот ответ, предоставленный указанным мной пользователем, является правильным.

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

Однако, если вы попытаетесь получить что-либо во фрагменте до вызова onAttach, getActivity () вернет значение null.


3

Вы можете сделать SharedPrefencesв onAttachметоде фрагмента , как это:

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


1

getActivity()и onAttach()не помог мне в той же ситуации,
возможно, я сделал что-то не так,
но! Я нашел другое решение,
я создал поле Context thisContextвнутри своего фрагмента
и получил текущий контекст из метода onCreateView,
и теперь я могу работать с общим префиксом из фрагмента

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

1

Чтобы определить предпочтение во фрагменте: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR",Context.MODE_PRIVATE); editor.putString("credi_credito",cre); editor.commit();

Чтобы вызвать другое действие или фрагментировать данные предпочтений: SharedPreferences pref = getActivity().getSharedPreferences("CargaDatosCR", Context.MODE_PRIVATE); credit=pref.getString("credi_credito",""); if(credit.isNotEmpty)...


0

Можно получить контекст из Fragment

Просто делать

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

Вы также можете добавить AndroidViewModelв onCreateViewметод, который реализует метод, который возвращает контекст приложения.

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

Может быть, это поможет кому-то через несколько лет. Новый способ проникновения SharedPreferences()внутрь фрагмента на Androidx - реализовать вgradle dependencies

implementation "androidx.preference:preference:1.1.1"

а затем внутри вызова фрагмента

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

0

использовать requiredactivity во фрагменте kotlin

 val sharedPreferences = requireActivity().getSharedPreferences(loginmasuk.LOGIN_DATA, Context.MODE_PRIVATE)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.