Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save custom object in shared preferences

I want to save a custom object myObject in shared preferences. Where this custom object has ArrayList<anotherCustomObj>. This anotherCustomObj has primary variables.

Both myObject and anotherCustomObj are parcelable.

I tried below code to convert it to String and save it :

String myStr = gson.toJson(myObject);
editor.putString(MY_OBJ, myStr);

But it gives RunTimeException.

EDIT : Below is logcat screen shot. enter image description here

anotherCustomObj implementation :

package com.objectlounge.ridesharebuddy.classes;

import java.io.File;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.gson.annotations.SerializedName;
import com.objectlounge.ridesharebuddy.R;

public class RS_SingleMatch implements Parcelable {

    private static final String RIDESHARE_DIRECTORY = "RideShareBuddy";
    private static final String TAG = "RS_SingleMatch";
    private static final String IMAGE_PATH = "imagePath";
    private static final String IMAGE_NAME_PREFIX = "RideShareBuddyUserImage";

    private Context context;
    @SerializedName("id")
    private int userId;
    private int tripId;
    private String imageUrl;
    @SerializedName("userName")
    private String email;
    private String realName;
    private String gender;
    private int reputation;
    private String createdAt;
    private String birthdate;
    private float fromLat, fromLon, toLat, toLon;
    private String fromPOI, toPOI;
    private String departureTime;
    private int matchStrength;

    // Constructor
    public RS_SingleMatch(Context context) {
        this.context = context;
    }

    // Constructor to use when reconstructing an object from a parcel
    public RS_SingleMatch(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    // Called to write all variables to a parcel
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeInt(userId);
        dest.writeInt(tripId);
        dest.writeString(imageUrl);
        dest.writeString(email);
        dest.writeString(realName);
        dest.writeString(gender);
        dest.writeInt(reputation);
        dest.writeString(createdAt);
        dest.writeString(birthdate);
        dest.writeFloat(fromLat);
        dest.writeFloat(fromLon);
        dest.writeFloat(toLat);
        dest.writeFloat(toLon);
        dest.writeString(fromPOI);
        dest.writeString(toPOI);
        dest.writeString(departureTime);
        dest.writeInt(matchStrength);
    }

    // Called from constructor to read object properties from parcel
    private void readFromParcel(Parcel in) {

        // Read all variables from parcel to created object
        userId = in.readInt();
        tripId = in.readInt();
        imageUrl = in.readString();
        email = in.readString();
        realName = in.readString();
        gender = in.readString();
        reputation = in.readInt();
        createdAt = in.readString();
        birthdate = in.readString();
        fromLat = in.readFloat();
        fromLon = in.readFloat();
        toLat = in.readFloat();
        toLon = in.readFloat();
        fromPOI = in.readString();
        toPOI = in.readString();
        departureTime = in.readString();
        matchStrength = in.readInt();
    }

    // This creator is used to create new object or array of objects
    public static final Parcelable.Creator<RS_SingleMatch> CREATOR = new Parcelable.Creator<RS_SingleMatch>() {

        @Override
        public RS_SingleMatch createFromParcel(Parcel in) {
            return new RS_SingleMatch(in);
        }

        @Override
        public RS_SingleMatch[] newArray(int size) {
            return new RS_SingleMatch[size];
        }
    };

    // Getters
    public int getUserId() {
        return userId;
    }

    public int getTripId() {
        return tripId;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public Bitmap getImage() {

        Bitmap image = null;

        // If imageUrl is not empty
        if (getImageUrl().length() > 0) {

            SharedPreferences prefs = PreferenceManager
                    .getDefaultSharedPreferences(this.context);
            String imagePath = prefs.getString(IMAGE_PATH + getUserId(), "");

            // Get image from cache
            if ((image = RS_FileOperationsHelper.getImageAtPath(imagePath)) == null) {

                Log.d(TAG, "Image not found on disk.");
                Thread t = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // If image not found on storage then download it
                        setImage(downloadImage(getImageUrl()));
                    }
                });
                t.start();
            }

        } else {
            // Use default image
            image = getDefaultProfileImage();
        }

        image = RS_ImageViewHelper.getRoundededImage(image, image.getWidth());
        Log.d(TAG, "Image width : " + image.getWidth());
        return image;
    }

    public String getEmail() {
        return email;
    }

    public String getRealName() {
        return realName;
    }

    public String getGender() {
        return gender;
    }

    public int getReputation() {
        return reputation;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public String getBirthdate() {
        return birthdate;
    }

    public float getFromLat() {
        return fromLat;
    }

    public float getFromLon() {
        return fromLon;
    }

    public float getToLat() {
        return toLat;
    }

    public float getToLon() {
        return toLon;
    }

    public String getFromPOI() {
        return fromPOI;
    }

    public String getToPOI() {
        return toPOI;
    }

    public String getDepartureTime() {
        return departureTime;
    }

    public int getMatchStrength() {
        return matchStrength;
    }

    // Setters
    public void setContext(Context context) {
        this.context = context;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public void setTripId(int tripId) {
        this.tripId = tripId;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public void setImage(Bitmap img) {

        if (img != null) {

            // Get cache directory's path and append RIDESHARE_DIRECTORY.
            String cacheDirStoragePath = context.getCacheDir()
                    + "/"
                    + RIDESHARE_DIRECTORY;

            // Create directory at cacheDirStoragePath if does not exist.
            if (RS_FileOperationsHelper
                    .createDirectoryAtPath(cacheDirStoragePath)) {

                String imagePath = cacheDirStoragePath + "/"
                        + IMAGE_NAME_PREFIX + this.userId + ".png";

                // Save new image to cache
                RS_FileOperationsHelper.saveImageAtPath(img, imagePath, this.context);

                SharedPreferences pref = PreferenceManager
                        .getDefaultSharedPreferences(context);
                Editor e = pref.edit();
                e.putString(IMAGE_PATH + getUserId(), imagePath);
                e.commit();
            }
        }
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setReputation(int reputation) {
        this.reputation = reputation;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }

    public void setBirthdate(String birthdate) {
        this.birthdate = birthdate;
    }

    public void setFromLat(float fromLat) {
        this.fromLat = fromLat;
    }

    public void setFromLon(float fromLon) {
        this.fromLon = fromLon;
    }

    public void setToLat(float toLat) {
        this.toLat = toLat;
    }

    public void setToLon(float toLon) {
        this.toLon = toLon;
    }

    public void setFromPOI(String fromPOI) {
        this.fromPOI = fromPOI;
    }

    public void setToPOI(String toPOI) {
        this.toPOI = toPOI;
    }

    public void setDepartureTime(String departureTime) {
        this.departureTime = departureTime;
    }

    public void setMatchStrength(int matchStrength) {
        this.matchStrength = matchStrength;
    }

    // calculates age using given date
    @SuppressLint("SimpleDateFormat")
    public int calculateAge(String date) {
        int age = 0;
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            Date bdate = formatter.parse(date);
            Calendar lCal = Calendar.getInstance();
            lCal.setTime(bdate);
            int lYear = lCal.get(Calendar.YEAR);
            int lMonth = lCal.get(Calendar.MONTH) + 1;
            int lDay = lCal.get(Calendar.DATE);

            Calendar dob = Calendar.getInstance();
            Calendar today = Calendar.getInstance();

            dob.set(lYear, lMonth, lDay);

            age = today.get(Calendar.YEAR) - dob.get(Calendar.YEAR);

            if (today.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) {
                age--;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return age;
    }

    // Download image if not available
    protected void downloadAndSaveImage() {

        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(this.context);
        String imagePath = prefs.getString(IMAGE_PATH + getUserId(), "");
        File file = new File(imagePath);

        // If image path not stored in user defaults or image does not exists
        // then
        if ((imagePath == null || !file.exists()) && this.imageUrl.length() > 0) {

            // Download on separate thread
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    setImage(downloadImage(getImageUrl()));
                }
            });
            t.start();
        }
    }

    // Download an image
    private Bitmap downloadImage(String imageUrl) {

        Log.d(TAG, "Image url : " + imageUrl);
        Bitmap image = null;

        try {

            // Download an image from url
            InputStream in = new java.net.URL(imageUrl.trim()).openStream();
            image = BitmapFactory.decodeStream(in);

        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d(TAG, "Image downloading complete. image : " + image);

        return image;
    }

    // Get default image
    protected Bitmap getDefaultProfileImage() {

        Bitmap image = BitmapFactory.decodeResource(
                this.context.getResources(), R.drawable.default_male);

        if (this.gender.toUpperCase(Locale.US).startsWith("F")) {
            image = BitmapFactory.decodeResource(this.context.getResources(),
                    R.drawable.default_female);
        }

        return image;
    }
}
like image 521
Geek Avatar asked Oct 10 '13 12:10

Geek


People also ask

Can we save object in shared preferences?

We can store fields of any Object to shared preference by serializing the object to String.

How do you save the object of the model class in preferences?

In Android, SharedPreferences class can save only these: We use the GSON library to convert the model class to JSON String and we save that JSON String into the SharedPreferences. We read back that JSON String and convert it back to the object when we want to read it.

How do you save custom objects in SharedPreferences in flutter?

SharedPreferences: Save and Read First, in order to use the SharedPreferences , we have to use Flutter's plugin for it. To do so, make sure dependencies in your pubspec. yaml file looks similar to this: To save something in SharedPreferences , we must provide a value that we want to save and a key that identifies it.


1 Answers

Link posted by damian was helpful to solve my problem. However, in my case there was no view component in custom object.

According to my observation if you find multiple JSON fields for ANY_VARIABLE_NAME, then it is likely that it is because GSON is not able to convert the object. And you can try below code to solve it.

Add below class to to tell GSON to save and/or retrieve only those variables who have Serialized name declared.

class Exclude implements ExclusionStrategy {

    @Override
    public boolean shouldSkipClass(Class<?> arg0) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean shouldSkipField(FieldAttributes field) {
        SerializedName ns = field.getAnnotation(SerializedName.class);
        if(ns != null)
            return false;
        return true;
    }
}

Below is the class whose object you need to save/retrieve. Add @SerializedName for variables that needs to saved and/or retrieved.

class myClass {
    @SerializedName("id")
    int id;
    @SerializedName("name")
    String name;
}

Code to convert myObject to jsonString :

Exclude ex = new Exclude();
    Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();
String jsonString = gson.toJson(myObject);

Code to get object from jsonString :

Exclude ex = new Exclude();
Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();
myClass myObject = gson.fromJson(jsonString, myClass.class);
like image 197
Geek Avatar answered Oct 06 '22 04:10

Geek