0

I am new to Android and app getting terminated when it access to SharedPreferences from a non activity class. Giving my code below, In Debug mode the code running up to sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); after this line the app got terminated.

package org.traccar.client;

import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.preference.PreferenceManager;

import java.util.Date;

import static android.content.Context.MODE_PRIVATE;

public class Position {
   private static SharedPreferences sharedPreferences;


    private Context context;
    public Position() {
    }
    public Position(Context context) {
        this.context=context;
    }

    public Position(String deviceId, Location location, double battery) {
        this.deviceId = deviceId;
        time = new Date(location.getTime());
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        altitude = location.getAltitude();
        speed = location.getSpeed() * 1.943844; // speed in knots
        course = location.getBearing();
        if (location.getProvider() != null && !location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
            accuracy = location.getAccuracy();
        }
        sharedPreferences  = PreferenceManager.getDefaultSharedPreferences(context);
        boolean ccflag =  sharedPreferences.getBoolean("CheckIn", false);
        sharedPreferences.edit().putBoolean("CheckIn", true).apply();


        if (ccflag == true){
            mock = ccflag;
        }
        this.battery=battery;



    }

    private long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    private String deviceId;

    public String getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    private Date time;

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    private double latitude;

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    private double longitude;

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    private double altitude;

    public double getAltitude() {
        return altitude;
    }

    public void setAltitude(double altitude) {
        this.altitude = altitude;
    }

    private double speed;

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    private double course;

    public double getCourse() {
        return course;
    }

    public void setCourse(double course) {
        this.course = course;
    }

    private double accuracy;

    public double getAccuracy() {
        return accuracy;
    }

    public void setAccuracy(double accuracy) {
        this.accuracy = accuracy;
    }

    private double battery;

    public double getBattery() {
        return battery;
    }

    public void setBattery(double battery) {
        this.battery = battery;
    }

    private boolean mock;

    public boolean getMock() {
        return mock;
    }

    public void setMock(boolean mock) {
        this.mock = mock;
    }

}

The error on Android Studio

Adding the screenshot of the debug mode here

When i tried first time i couldn't put context there. after googling i found a way to add context in a non activity class

private Context context;
public Position(Context context) {
        this.context=context;
    }

after adding this code i am able to remove all error. After removing the error also my application getting terminated. Any help is appreciated.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • It looks like `context` is null on that line. Just adding that `Context` field and a constructor to set it doesn't automatically make a `Context` instance available there. You actually have to use the appropriate constructor. Given that you have a zero-parameter constructor in that class as well, I would bet that you're using the wrong one. Please [edit] your question to provide [the stack trace from the crash](https://stackoverflow.com/questions/23353173), and the code where you create your `Position` object. – Mike M. Dec 08 '18 at 07:24
  • Oh, wait, I'm blind. You're definitely using the wrong constructor; at least, one that doesn't pass in a `Context`. The `PreferenceManager...` call is in a third constructor I hadn't noticed. Add a `Context` parameter to that one, and pass a valid `Context` to it when creating your `Position` object. – Mike M. Dec 08 '18 at 07:41
  • i am new to android, please help me by adding the code snippet or other way – mohammed shefeeq Dec 08 '18 at 07:50
  • Well, you probably don't really want to be handling that preference setting there, but you'll likely find that out as you go. The quick fix is to add a `Context` parameter to that constructor – i.e., `public Position(Context context, String deviceId, Location location, double battery)` – and pass one in when you create the `Position`. You could pass an `Activity` or `Service` for that, depending on where you're using it, as they are both `Context`s. – Mike M. Dec 08 '18 at 07:55
  • 1
    i will try to do that, thank you :) – mohammed shefeeq Dec 08 '18 at 09:23
  • I assume your position class is being instantiated with default constructor hence keeping the context null. One best practice is to make default contructor private to detect the issue. Please chage defaults constructor to private Potision(){} – Sazzad Hissain Khan Dec 09 '18 at 14:25

2 Answers2

0

Try replacing context in

sharedPreferences  = PreferenceManager.getDefaultSharedPreferences(context);

with "Position.this" that is

sharedPreferences  = PreferenceManager.getDefaultSharedPreferences(Position.this);
Shivansh Khare
  • 65
  • 1
  • 10
0

When it comes to using context, many android developers are still confused to choose Activity context or Application context.

Well,choosing appropriate context may be not so trivial,but this is how I make my mind. If using shared preference, I check whether the information which I am saving has to be used just for current views life-cycle or even after it is destroyed.

If it is needed for just view's current life-cycle pass it (Activity) context , else pass it the Application Context.

1.For Activity Context ,pass --> this

2.For Application Context,pass -->getApplicationContext()

I personally prefer Application Context while using sharedPreference. So to solve your issue, sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

iCantC
  • 2,852
  • 1
  • 19
  • 34