尝试使用sharedPreferences,但应用程序崩溃了

时间:2018-04-06 15:56:03

标签: android datepicker sharedpreferences

我正在尝试使用sharedPreferences来了解它们的工作原理。我有一个日期选择器,并希望以下内容: 当应用程序第一次打开时,日期选择器会显示,有人会选择日期。之后,将存储日期,然后每次打开应用程序时textView都会显示日期,而不会再次显示日期选择器。此外,我希望存储日期以供将来参考。

这是我的代码:

主要课程

private TextView mDisplayDate;
DialogFragment bday = new BdayPick();
public static final String TAG = "main_date";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mDisplayDate = findViewById(R.id.tvDate);
    }

@SuppressLint({"SetTextI18n", "ApplySharedPref"})
@Override
protected void onResume() {
    super.onResume();
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    boolean previouslyStarted = prefs.getBoolean(getString(R.string.pref_previously_started), false);
    if (!previouslyStarted) {
        SharedPreferences.Editor edit = prefs.edit();
        edit.putBoolean(getString(R.string.pref_previously_started), Boolean.TRUE);
        edit.commit();
        bday.show(getSupportFragmentManager(), "datePicker");
    } else setDateChosen();
}

@SuppressLint("SetTextI18n")
private void setDateChosen() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        int day = prefs.getInt(String.valueOf(selected_day), 0);
        int year = prefs.getInt(String.valueOf(selected_year), 0);
        String month = prefs.getString(String.valueOf(selected_month), "0");
        Log.d(TAG, day + " / " + month + " / " + year);
        mDisplayDate.setText("The Selected date is: " + day + "-" + month + "-" + year);
}

选择器类

public class BdayPick extends DialogFragment
                            implements DatePickerDialog.OnDateSetListener {

   // Context context = getActivity();
    SharedPreferences sharedPrefs = getActivity().getPreferences(Context.MODE_PRIVATE);
@NonNull
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public Dialog onCreateDialog (Bundle savedInstanceState) {
    final Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    int month = cal.get(Calendar.MONTH);
    int day = cal.get(Calendar.DAY_OF_MONTH);

    return new DatePickerDialog(Objects.requireNonNull(getActivity()),
            android.R.style.Theme_Holo_Dialog,
            this,
            year, month, day);
}

@SuppressLint("StringFormatInvalid")
public void onDateSet(DatePicker view, int year, int month, int day) {
    //TODO calculate and show required textl
    month = month + 1;
    String date = day + "-" + month + "-" + year;

    SharedPreferences.Editor editor = sharedPrefs.edit();
    editor.putInt(getString(R.string.selected_day), day);
    editor.putString(getString(R.string.selected_month), String.valueOf(month));
    editor.putInt(getString(R.string.selected_year), year);
    editor.apply();

    Toast.makeText(getActivity(), date, Toast.LENGTH_LONG).show();
}
}

我没有构建或编译错误,但是当我尝试打开应用程序时,它只是崩溃,我不明白为什么。

**编辑: 用这解决了Logcat。我根据答案进行了编辑:

public void onDateSet(DatePicker view, int year, int month, int day) {
        month = month + 1;
        String date = day + "-" + month + "-" + year;

        SharedPreferences.Editor editor = sharedPrefs.edit();
        /*editor.putInt(getContext().getResources().getString(R.string.selected_day), day);
        editor.putString(getContext().getResources().getString(R.string.selected_month), String.valueOf(month));
        editor.putInt(getContext().getResources().getString(R.string.selected_year), year);
        editor.apply();
        */

    Calendar cal;
    cal= Calendar.getInstance().set(view.getYear(), view.getMonth(), view.getDayOfMonth());
    Date d = cal.getTime();
    PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString("pref_date", new SimpleDateFormat("ddMMyyyy").format(d));
    //editor.putString("date", new SimpleDateFormat("ddMMyyyy").format(c.getTime()));
        editor.apply();

    Toast.makeText(getActivity(), date, Toast.LENGTH_LONG).show();
    }

但现在我有以下错误:

incompatible types: void cannot be converted to Calendar

3 个答案:

答案 0 :(得分:1)

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.support.v4.app.FragmentActivity.getPreferences(int)' on a null object reference
  at com.example.zodiac.zodiac.BdayPick.<init>(BdayPick.java:23)

您在此处调用空getPreferences()

SharedPreferences sharedPrefs = getActivity().getPreferences(Context.MODE_PRIVATE);

其中<init>表示正在初始化对象,在这种情况下使用字段init。对于<init> getActivity()以外的其他任何内容,nullContext太早了 - 该片段尚未附加到任何活动。

您需要将需要onAttach()的代码移至fragment lifecycle中的$arr[substr($row, 0, $posOfFirstColon)][] = trim(substr($row, $posOfFirstColon+1)); 或更晚的阶段。

答案 1 :(得分:0)

在主课程中将edit.commit();更改为edit.apply();

并使用putBoolean(..., true)代替putBoolean(..., Boolean.TRUE)

**编辑: 不要在SharedPrefernece中使用字符串资源。请改用常量字符串。 您可以尝试使用日期格式,例如:

f.e。:

Calendar c = Calendar.getInstance().set(view.getYear(), view.getMonth(), view.getDayOfMonth());
Date d = c.getTime();
PreferenceManager.getDefaultSharedPreferences(getAppliactionContext()).edit().putString("pref_date", new SimpleDateFormat("ddMMyyyy").format(d));

并使用以下方式读取值:

try {
    Date d = new SimpleDateFormat("ddMMyyyy").parse(PreferenceManager.getDefaultSharedPreferences(getAppliactionContext()).getString("pref_date", ""));

    //DO SOMETHING WITH THE VALUE
}
catch (ParseException e){
    Log.e("PreferenceRead ", e.getMessage());
}

答案 2 :(得分:0)

你的问题在那里:

SharedPreferences sharedPrefs = getActivity().getPreferences(Context.MODE_PRIVATE);

您可以使用:SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());代替。

如果您不想使用默认的SharedPreferences,可以使用getActivity().getPreferences("name", Context.MODE_PRIVATE);,但我建议您使用默认值。