-1

I'm trying to pass some values from an activity to a non-activity receiver class in order to create a notification. I can't see why I'm getting an error on this one. I mean, I passed the context, retrieved it, and used it accordingly. I read some threads about this issue and did my best to solve it, but this is how far I could come. I'm getting an eror on this line:

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);

DailyForecastActivity.java

public class DailyForecastActivity extends AppCompatActivity {

    private Daily[] mDays;
    public static Context contextOfApplication;
    @Bind(android.R.id.list)
    ListView mListView;
    @Bind(android.R.id.empty)
    TextView mEmptyTextView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_daily_forecast);
        ButterKnife.bind(this);
        contextOfApplication = getApplicationContext();

        GPSTracker gpsTracker = new GPSTracker(this);
        TextView mLocationLabel = (TextView) findViewById(R.id.locationLabel);
        Intent intent = getIntent();

        Parcelable[] parcelables = intent.getParcelableArrayExtra(MainActivity.DAILY_FORECAST);
        mDays = Arrays.copyOf(parcelables, parcelables.length, Daily[].class);
        DayAdapter adapter = new DayAdapter(this, mDays);
        mListView.setAdapter(adapter);
        mListView.setEmptyView(mEmptyTextView);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String dayOfTheWeek = mDays[position].getDayOfTheWeek();
                String condition = mDays[position].getSummary();
                String tempMin = mDays[position].getTempMin() + "";
                String tempMax = mDays[position].getTempMax() + "";
                int icon = mDays[position].getIconId();

                String message = String.format("%s Summary: %s", dayOfTheWeek, condition);
                Toast.makeText(DailyForecastActivity.this, message, Toast.LENGTH_SHORT).show();
                SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
                editor.putString("summary", condition);
                editor.putString("tempMin", tempMin);
                editor.putString("tempMax", tempMax);
                editor.putString("dayOfTheWeek", dayOfTheWeek);
                editor.putInt("icon", icon);
                editor.apply();
            }
        });

        String area = gpsTracker.getSubLocality(this);
        String city = gpsTracker.getAdminArea(this);
        String country = gpsTracker.getCountryName(this);
        mLocationLabel.setText(area + ", " + city + ", " + country);
    }
    public static Context getContextOfApplication(){
    return contextOfApplication;
    }
}

Receiver.java

public class Receiver extends BroadcastReceiver{

    Context applicationContext = DailyForecastActivity.getContextOfApplication();
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);
    String summary = preferences.getString("summary", null);
    String tempMin = preferences.getString("tempMin", null);
    String tempMax = preferences.getString("tempMax", null);
    String dayOfTheWeek = preferences.getString("dayOfTheWeek", null);
    int icon = preferences.getInt("icon", 0);

    @Override
    public void onReceive(Context context, Intent intent) {
        this.applicationContext = context;
        PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
            .setSmallIcon(icon)
            .setContentTitle(dayOfTheWeek + " Weather")
            .setContentText(summary + "Temperature: " + tempMax + "/" + tempMin)
            .setTicker("Daily Weather");

        mBuilder.setContentIntent(pi);
        mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
        mBuilder.setAutoCancel(true);

        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());


    }
}

logcat

java.lang.RuntimeException: Unable to instantiate receiver com.theoc.stormy.Receiver: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                                at android.app.ActivityThread.handleReceiver(ActivityThread.java:2565)
                                                                at android.app.ActivityThread.access$1700(ActivityThread.java:148)
                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1360)
                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                at android.os.Looper.loop(Looper.java:135)
                                                                at android.app.ActivityThread.main(ActivityThread.java:5272)
                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                at java.lang.reflect.Method.invoke(Method.java:372)
                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
                                                             Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                                at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:374)
                                                                at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:369)
                                                                at com.theoc.stormy.Receiver.<init>(Receiver.java:42)
                                                                at java.lang.reflect.Constructor.newInstance(Native Method)
                                                                at java.lang.Class.newInstance(Class.java:1572)
                                                                at android.app.ActivityThread.handleReceiver(ActivityThread.java:2560)
                                                                at android.app.ActivityThread.access$1700(ActivityThread.java:148) 
                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1360) 
                                                                at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                at android.os.Looper.loop(Looper.java:135) 
                                                                at android.app.ActivityThread.main(ActivityThread.java:5272) 
                                                                at java.lang.reflect.Method.invoke(Native Method) 
                                                                at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 

EDIT

I solved the NPE error, but now I'm getting "null" for my SharedPreferences values. I ran a debug in DailyForecastActivity, where I'm putting the values, and there seems to be no problem there. I'm able to put all the values I want. Looks like I'm unable to retrieve the SharedPreferences in Receive.java. Also as a side note, I'm getting the notification sound for some reason, but not getting any notification at all.

Onur Çevik
  • 1,560
  • 13
  • 21
  • what is there at line 42 in `Receiver.java` – Ravi Jan 08 '16 at 12:51
  • I think your context is null – Malek Hijazi Jan 08 '16 at 12:54
  • debug line by line and check on which line code is breaking – koutuk Jan 08 '16 at 12:56
  • 1
    Possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – Rami Jan 08 '16 at 12:57
  • @RRR I already wrote the line that's giving the error. – Onur Çevik Jan 08 '16 at 12:58
  • With all due respect, no other question should be asked here containing Null Pointer Exception if that's the case. I know how to solve NPE's, yet I don't see why it's giving null in this one. To me, my context shouldn't be null. That's why I'm asking for help. – Onur Çevik Jan 08 '16 at 13:00

4 Answers4

0

initialize SharedPreference in onReceive

preferences = PreferenceManager.getDefaultSharedPreferences(context);

It might be possible when your BroadcastReceiver is called your activity is null

Ravi
  • 34,851
  • 21
  • 122
  • 183
  • this solved the error, yet now I'm getting "null" for all my SharedPreference values. Do you have any clue on that? – Onur Çevik Jan 08 '16 at 13:16
0

Try to do this:

First, instatiate your application in the manifest by linking to a class

<application
    android:name = ".App"
    android:allowBackup="true"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

Then implement the following method whitin your application class

public class App extends Application {
private static final String TAG = ".App";
private static Context context = null;

public void onCreate(){
    super.onCreate();
    context = getApplicationContext();
}

@SuppressWarnings("unused")
public static Context getContext() {
    if (context != null) {
        return context;
    } else {
        Log.e(TAG, "App was not successfully created");
        throw new Error("App was not successfully created");
    }
}

}

Chus Muñoz
  • 120
  • 8
0

I always get my shared preferences by using:

context.getSharedPreferences(PREFERENCE_FILENAME, Context.MODE_PRIVATE);

You can also verify whether the preference file is created or not in your application data/ directory. Please, read carefully how shared preferences works in android.

Chus Muñoz
  • 120
  • 8
0

By calling in DailyForecastActivity.java

SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();

and in Receiver.java

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);

You are calling for two different instances of SharedPreferences. You are saving in one, then you are trying to get from second, where you didn't save anything, so you are getting null for all values. You must unite it and use the same in first and second situation, like:

SharedPreferences sharedPref = getPreferences("MyPref", Context.MODE_PRIVATE);

in DailyForecastActivity and

SharedPreferences sharedPref = context.getPreferences("MyPref", Context.MODE_PRIVATE);

in Receiver, which will result in getting the same instance.

Also you can try using the same Context. Context get from getActivity() is not the same Context get from getApplicationContext(). So use getApplicationContext() in both situations or pass Context via parameter in constructor from activity.

Damian Kozlak
  • 7,065
  • 10
  • 45
  • 51