0

I know there are several similar questions asked previously but despite having everything as per the solutions suggested, My sharedPreferences still return a null value. Below is my code:

I declared 2 static methods in the MainActivity for accessing sharedPrefences from the entire application shown below.

  public static void saveToPreferences(Context context, int i,String key) {
        mSharedPreferences = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putInt(key , i);
        //used in place of commit as it is faster. This does the task asynchronously
        editor.commit();
    }

    public static int readFromPreferences(Context context, int i, String key) {
        mSharedPreferences = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        int fed_value = mSharedPreferences.getInt(key, i);
        return fed_value;
    }

I am accessing those values from another method as shown below

      static PendingIntent pendingIntent;
      static Intent alarmIntent;
      int mMinute;
      final Calendar calendar = Calendar.getInstance();
      int mCurrentHour = calendar.get(calendar.HOUR_OF_DAY);
      int mCurrentMinute = calendar.get(calendar.MINUTE);
      int minuteDifference;
        int mHour;
// Create the TimePicker
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return new TimePickerDialog(getActivity(), this, mCurrentHour, mCurrentMinute,
                    DateFormat.is24HourFormat(getActivity()));
        }

        @Override
        public void onTimeSet(android.widget.TimePicker view, int hourOfDay, int minute) {
            mHour = hourOfDay;
            minuteDifference = Math.abs(mCurrentMinute - mMinute);
            MainActivity.saveToPreferences(getActivity(),minuteDifference,"set_minute");
            mMinute = minute;
            MainActivity.saveToPreferences(getActivity(), Math.abs(mCurrentHour - mHour), "set_hour");


        public int minuteDifference(){
            Log.d("tag", String.valueOf(mHour) + " " + String.valueOf(mMinute));
            return  MainActivity.readFromPreferences(getActivity(),minuteDifference,"set_minute");
        }
        public int HourDifference(){
            return MainActivity.readFromPreferences(getActivity(),Math.abs(mCurrentHour - mHour),"set_hour");
        }

The method minuteDifference is returning null. It is being called from a separate fragment as shown below in the onStart method. Here is how the flow works:

The click of a button(setTime.setOnclickListener(..) in the below code block) shows the timePicker which then calls the onTimeSet method where the data is saved to preferences.

The click of second button(setAlarm.setOnClickListener(..) in the below code block) calls method minuteDifference method which is defined in a separate fragment shown above.

This should read the required value from sharedPreferences and return it. But it returns null

@Override
    public void onStart() {
        super.onStart();
        final Button setTime = (Button) getActivity().findViewById(R.id.set_time);
        final Button setAlarm = (Button) getActivity().findViewById(R.id.set_alarm);
        alarmIntent = new Intent(getActivity(), AlarmReciever.class);
        pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, alarmIntent, 0);
        setAlarm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlarmManager manager;
                TimePickerFragment tfSchedule = new TimePickerFragment();
                int mDifferenceMinute = tfSchedule.minuteDifference();
                manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                int interval = mDifferenceMinute*60000;
                Log.d("minuteDifference",String.valueOf(mDifferenceMinute));
//                manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
                manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        SystemClock.elapsedRealtime() +
                                interval, pendingIntent);

            }
        });

        setTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TimePickerFragment tfViewTimer = new TimePickerFragment();
                tfViewTimer.show(getFragmentManager(), "Tag");

                }

        });
    } 

Below is the error log

08-17 10:05:47.525 25850-25850/com.rs.rishitshah.feedingnemo E/AndroidRuntime: FATAL EXCEPTION: main Process: com.rs.rishitshah.feedingnemo, PID: 25850 java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference at com.rs.rishitshah.feedingnemo.MainActivity.readFromPreferences(MainActivity.java:265) at com.rs.rishitshah.feedingnemo.TimePickerFragment.minuteDifference(TimePickerFragment.java:63) at com.rs.rishitshah.feedingnemo.ScheduleFeed$1.onClick(ScheduleFeed.java:51) at android.view.View.performClick(View.java:5204) at android.view.View$PerformClick.run(View.java:21155) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5422) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

PS: Before marking this as duplicate or downvoting this question note that I followed the below links and already have my code as per the solution mentioned in them. Despite of all this my code is not working.

android - sharedpreferences return null value

SharedPreferences getString returns null though set by editor in AsyncTask

SharedPreferences returns null values

Sharedpreferences in Android returns null when called from another activity

Community
  • 1
  • 1
Rishit Shah
  • 355
  • 5
  • 20

2 Answers2

3

Your shared preference isn't returning null. Your context is null. This is because you create a fragment with new, do not add it to any layout, then call a method on it. It doesn't have an Activity because it hasn't been added to any layout via Transaction. It looks like you're abusing fragments. Those functions shouldn't exist on a Fragment, they should be elsewhere. Probably on the activity you're calling it from or in a helper class. If you aren't going to add the fragment to a layout, you shouldn't be using a Fragment to access a helper function.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
3

The problem is that the fragment at these lines;

            TimePickerFragment tfSchedule = new TimePickerFragment();
            int mDifferenceMinute = tfSchedule.minuteDifference();

has no Context (it's not attached to an Activity). More specifically, the Context is has is null.

You should know that Fragments do not have Context until attached, and (maybe more important) you should avoid static methods like this in them. You should create a time object or, since you are using SharedPreferences simply create a helper object where you pass in the Context when you make calls to "set" or "get" data from it.

Jim
  • 10,172
  • 1
  • 27
  • 36
  • Thank you for the answer. I have a question though. If that is the case shouldn't it throw the same exception when calling saveToPreferences? – Rishit Shah Aug 17 '16 at 21:47
  • since you don't have your full code posted, I would assume because that call is not made until after the fragment attaches (save sounds like something that happens after display - which means the frag is attached) – Jim Aug 18 '16 at 17:30
  • Using Application context solved the problem. Thanks – Rishit Shah Aug 18 '16 at 19:39