Save custom arraylist to Shared Prefrences with gson - java

I am trying to save the state of my app to shared prefrences. The information that I want to save is an arraylist of custom objects where each object (PatientInfo) contains a few string and 2 more custom arraylist (SkinPhotoInfo, TreatmentsInfo). I was able to save and load an array list of custom objects, but I was'nt able to save the arraylist that has arraylists in it.
Anyone got an idea of what is the easiest way to do it? The object itself is allready parcable if it helps in any way.
P. S. When is the best time to save to shared prefrences - onPause or onDelete?
Thank you for your help!!
PatientInfo:
public class PatientInfo implements Parcelable {
String name;
String skinType;
String notes;
String image;
ArrayList<SkinPhotoInfo> skinPhotos;
ArrayList<TreatmentsInfo> treatments;
Boolean showDeleteButton;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(skinType);
dest.writeString(notes);
dest.writeValue(image);
dest.writeValue(skinPhotos);
dest.writeValue(treatments);
}
public static final Creator<PatientInfo> CREATOR = new Creator<PatientInfo>()
{
#Override
public PatientInfo createFromParcel(Parcel source) {
PatientInfo ret = new PatientInfo();
ret.name = source.readString();
ret.skinType = source.readString();
ret.notes = source.readString();
ret.image = (String)source.readString();
ret.skinPhotos = source.readArrayList(null);
ret.treatments = source.readArrayList(null);
return ret;
}
#Override
public PatientInfo[] newArray(int size) {
return new PatientInfo[size];
}
};
public PatientInfo() {
this.name = "";
this.skinType = "";
this.image = "";
this.skinPhotos = new ArrayList<SkinPhotoInfo>();
this.showDeleteButton = false;
this.treatments = new ArrayList<TreatmentsInfo>();
}}
SkinPhotoInfo:
public class SkinPhotoInfo implements Parcelable {
String photoDate;
Boolean showDeleteButton;
Uri imageUri;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(photoDate);
dest.writeByte((byte)(showDeleteButton ? 1 : 0)); // If showDeleteButton == true, byte == 1
dest.writeValue(imageUri);
}
public static final Creator<SkinPhotoInfo> CREATOR = new Creator<SkinPhotoInfo>()
{
#Override
public SkinPhotoInfo createFromParcel(Parcel source) {
SkinPhotoInfo ret = new SkinPhotoInfo();
ret.skinImageThumnail = (Bitmap)source.readValue(Bitmap.class.getClassLoader());
ret.photoDate = source.readString();
ret.showDeleteButton = source.readByte() != 1;
ret.imageUri = (Uri) source.readValue(Uri.class.getClassLoader());
return ret;
}
#Override
public SkinPhotoInfo[] newArray(int size) {
return new SkinPhotoInfo[size];
}
};
public SkinPhotoInfo(Uri imageUri, String photoDate) {
this.imageUri = imageUri;
this.photoDate = photoDate;
showDeleteButton = false;
}}
TreatmentsInfo:
public class TreatmentsInfo implements Parcelable {
String treatmentDate;
String treatmentName;
String pattern = "MM-dd-yy";
Boolean showDeleteButton;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(treatmentDate);
dest.writeString(treatmentName);
dest.writeString(pattern);
dest.writeByte((byte)(showDeleteButton ? 1 : 0)); // If showDeleteButton == true, byte == 1
}
public static final Creator<TreatmentsInfo> CREATOR = new Creator<TreatmentsInfo>()
{
#Override
public TreatmentsInfo createFromParcel(Parcel source) {
TreatmentsInfo ret = new TreatmentsInfo();
ret.treatmentDate = source.readString();
ret.treatmentName = source.readString();
ret.pattern = source.readString();
ret.showDeleteButton = source.readByte() != 1;
return ret;
}
#Override
public TreatmentsInfo[] newArray(int size) {
return new TreatmentsInfo[size];
}
};
public TreatmentsInfo(){
this.treatmentDate = "";
this.treatmentName = "";
this.showDeleteButton = false;
this.pattern = "";
}
public TreatmentsInfo(String treatmentDate, String treatmentName) {
this.treatmentDate = treatmentDate;
this.treatmentName = treatmentName;
this.showDeleteButton = false;
}}

Use Gson library and save the arraylist as string.
Snippet below is save as file but you can use it in sharedpreference as well:
public static void saveGroupChatFile(File file, List<GCRoom> list) throws IOException {
String data = new Gson().toJson(list);
FileOutputStream fout = new FileOutputStream(file, false);
OutputStreamWriter osw = new OutputStreamWriter(fout);
osw.write(data);
osw.close();
}
public static List<GCRoom> readGroupChatFile(File file) throws IOException {
Type listType = new TypeToken<List<GCRoom>>() {
}.getType();
JsonReader reader = new JsonReader(new FileReader(file));
return new Gson().fromJson(reader, listType);
}
As for the library:
implementation 'com.google.code.gson:gson:2.8.5'

You can do something like:
String json = new Gson().toJson(YourObject);
To save in the Shared Preferences.
To retrieve the json and transform it to YourObejct, just do:
String json = myPrefsObject.getString(TAG, "");
return new Gson().fromJson(json, YourObject.class);
As for the PS question, the answer is onPause.
Let me know if you need something else

GSON provides method to convert objects to string and vice versa.
Use toJson() to convert object to string
PatientInfo patientInfo = new PatientInfo();
Gson gson = new Gson();
String objectAsString = gson.toJson(patientInfo);
Use fromJson() to convert string to object
Gson gson = new Gson();
PatientInfo patientinfo = gson.fromJson(data, PatientInfo.class);
//data is object that that you saved in shared preference after converting to string

Convert response to gson and use it as list and thus simply convert list setvalue and use putArray() to that set
public class staticpref{
private static SharedPreferences prefs;
private static SharedPreferences.Editor editor;
public static void putArray(String key, Set<String> arrayList){
editor.putStringSet(key, arrayList);
editor.commit();
}
public static Set getArray(String key,Set<String> defvalue){
return prefs.getStringSet(key,defvalue);
}
}
or you can make static class for getting and array you have to convert gson to arraylist and like this
String strResponse = anyjsonResponse;
Modelclass model= new Gson().fromJson(strResponse, Modelclass .class);
List<String> datalist= model.anyvalue();
Putandgetarray.addArrayList(datalist);
static methods for achieving this
public class Putandgetarray{
public static void addArrayList(List<data> dataList){
String strputdata = new Gson().toJson(dataList, new TypeToken<List<MutedChat>>() {}.getType());
SharedPreferenceUtils.putString("key", strputdata);
}
public static List<data> getArrayList(){
Type type = new TypeToken<List<data>>(){}.getType();
String strreturndata=SharedPreferenceUtils.getString("key","");
return new Gson().fromJson(strreturndata, type);
}
}

In sharedPreferece you can put only putStringSet(String key, #Nullable Set values); in sharedpreference

Related

Can't find a codec for my class (CodecConfigurationException)

I need to save a java object in mongodb database. This object has an other object into it. When I try to save, I receive the error message on console:
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class Item.
The problem is that I created the codec for class Item, but, it can't work even registering it. See the classes for best understanding.
Models
public class Card(){
public Card(){
itens = new ArrayList<Item>()
}
String id;
String description;
List<Item> itens;
.
.
.
}
public class Item(){
String id;
String name;
.
.
.
}
CardCodec
public class CardCodec implements CollectibleCodec<Card>{
private final Codec<Document> documentCodec;
public CardCodec() {
this.documentCodec = new DocumentCodec();
}
#Override
public void encode(BsonWriter writer, Card card, EncoderContext encoderContext) {
Document cardDoc = new Document();
String id = card.getId();
String description = card.getDescription();
List<Item> itens = card.getItens();
if(id != null) {
cardDoc.put("_id", new ObjectId(id));
}
if(description != null){
cardDoc.put("description", card.getDescription);
}
if(Itens != null){
cardDoc.put("itens", card.getItens());
}
this.documentCodec.encode(writer, cardDoc, encoderContext);
}
#Override
public Class<Card> getEncoderClass() {
return Card.class;
}
#Override
public Card decode(BsonReader reader, DecoderContext decoderContext) {
Document cardDoc = this.documentCodec.decode(reader, decoderContext);
Card card= new Card();
card.setId(cardDoc .getObjectId("_id").toHexString());
card.setDescription(cardDoc .getString("description"));
List<Document> itensDoc = cardDoc.getList("itens", Document.class);
List<Item> itens = new ItemConverter().convertToListItem(itensDoc);
card.setItens(itens);
return card;
}
#Override
public Card generateIdIfAbsentFromDocument(Card card) {
if( !documentHasId(card) ) {
card.setId(new ObjectId().toHexString());
}
return card;
}
#Override
public boolean documentHasId(Card card) {
return null != card.getId();
}
#Override
public BsonValue getDocumentId(Card card) {
if(!documentHasId(card)) {
throw new IllegalStateException("Esse documento não tem um _id");
}
return new BsonString(card.getId());
}
}
Converter
public class ItemConverter {
public Item convert(Document doc) {
Item item = new Item();
String id = doc.getObjectId("_id").toHexString();
String description = doc.getString("description");
item.setId(id);
item.setName(description);
return item;
}
public List<Item> convertToListItem(List<Document> ItensDocs){
List<Item> itens = new ArrayList<Item>();
if(ItensDocs== null) {
return Collections.emptyList();
}
for(Document doc: ItensDocs) {
itens.add( this.convert(doc) );
}
return itens;
}
}
ItemCodec
public class ItemCodec implements CollectibleCodec<Item>{
private final Codec<Document> documentCodec;
public ItemCodec() {
this.documentCodec = new DocumentCodec();
}
#Override
public void encode(BsonWriter writer, Item value, EncoderContext encoderContext) {
Document itemDoc = new Document();
String id = value.getId();
String name = value.getName();
if(id != null) {
itemDoc.put("_id", new ObjectId(id));
}
if(name != null) {
itemDoc.put("name", value.getName());
}
documentCodec.encode(writer, itemDoc, encoderContext);
}
#Override
public Class<Item> getEncoderClass() {
return Item.class;
}
#Override
public Item decode(BsonReader reader, DecoderContext decoderContext) {
Document document = documentCodec.decode(reader, decoderContext);
return new ItemConverter().convert(document);
}
#Override
public Item generateIdIfAbsentFromDocument(Item item) {
if(!this.documentHasId(item)) {
item.setId(new ObjectId().toHexString());
}
return item;
}
#Override
public boolean documentHasId(Item item) {
return null != item.getId();
}
#Override
public BsonValue getDocumentId(Item item) {
if(!documentHasId(item)) {
throw new IllegalStateException("Esse documento não tem um _id");
}
return new BsonString(item.getId());
}
}
Now, how I registry the codecs
...
CardCodec cardCodec = new CardCodec();
ItemCodec itemCodec = new ItemCodec();
this.codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromCodecs(cardCodec, itemCodec)
);
this.cardCollection = this.mongoDatabase.getCollection("cards", Card.class).withCodecRegistry(this.codecRegistry);
...
When I try to execute an insert:
this.cardCollection.insertOne(card);
I receive:
org.bson.codecs.configuration.CodecConfigurationException
It's tricky to write correct and efficient POJO Codec implementations by hand. In this case the problem is that the DocumentCodec that you instantiate within the CardCodec is not configured with a CodecRegistry that contains the ItemCodec, so it is unable to find the ItemCodec.
There are ways that you can fix your Codec implementations, but I'm not clear why you want to roll your own when the driver has a general solution for this. See POJO Support for details.
Simply create your CodecRegistry like this:
CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);

Building a Json String in java?

I am trying to build a json string in java but I am a bit confused as how I should go about it. This is what I tried so far.
String jsonString = new JSONObject()
.put("JSON1", "Hello World!")
.put("JSON2", "Hello my World!")
.put("JSON3", new JSONObject()
.put("key1", "value1")).toString();
System.out.println(jsonString);
The output is :
{"JSON2":"Hello my World!","JSON3":{"key1":"value1"},"JSON1":"Hello World!"}
The Json I want is as follows :-
{
"data":{
"nightclub":["abcbc","ahdjdjd","djjdjdd"],
"restaurants":["fjjfjf","kfkfkfk","fjfjjfjf"],
"response":"sucess"
}
}
How should I go about it?
You will need to use JSONArray and JsonArrayBuilder to map these json arrays.
This is the code you need to use:
String jsonString = new JSONObject()
.put("data", new JSONObject()
.put("nightclub", Json.createArrayBuilder()
.add("abcbc")
.add("ahdjdjdj")
.add("djdjdj").build())
.put("restaurants", Json.createArrayBuilder()
.add("abcbc")
.add("ahdjdjdj")
.add("djdjdj").build())
.put("response", "success"))
.toString();
You can use gson lib.
First create pojo object:
public class JsonReponse {
private Data data;
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public class Data {
private String reponse;
private List<String> nightclub;
private List<String> restaurants;
public String getReponse() {
return reponse;
}
public void setReponse(String reponse) {
this.reponse = reponse;
}
public List<String> getNightclub() {
return nightclub;
}
public void setNightclub(List<String> nightclub) {
this.nightclub = nightclub;
}
public List<String> getRestaurants() {
return restaurants;
}
public void setRestaurants(List<String> restaurants) {
this.restaurants = restaurants;
}
}
}
and next complite data and generate json:
JsonReponse jsonReponse = new JsonReponse();
JsonReponse.Data data = jsonReponse.new Data();
data.setReponse("sucess");
data.setNightclub(Arrays.asList("abcbc","ahdjdjd","djjdjdd"));
data.setRestaurants(Arrays.asList("fjjfjf","kfkfkfk","fjfjjfjf"));
jsonReponse.setData(data);
Gson gson = new Gson();
System.out.println(gson.toJson(jsonReponse));

Jackson no suitable constructor found for android.graphics.Bitmap

I'm trying to serialize my Character object with the use of Jackson. The mapper.writeValue method invocation is successful it seems, but when I try to read the value with the use of mapper.readValue I get the following error message:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of android.graphics.Bitmap: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: java.io.FileReader#9ab6557; line: 1, column: 199] (through reference chain: java.lang.Object[][0]->com.myproj.character.Character["compositeClothes"]->com.myproj.character.clothing.CompositeClothing["clothes"]->java.util.ArrayList[0]->com.myproj.character.clothing.concrete.Hat["bitmap"])
These are my classes:
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#class")
#JsonSubTypes({
#JsonSubTypes.Type(value = Hat.class, name = "hat"),
#JsonSubTypes.Type(value = Necklace.class, name = "necklace"),
#JsonSubTypes.Type(value = Shirt.class, name = "shirt")
})
public interface Clothing {
int getCoolness();
int getrId();
Bitmap getBitmap();
}
My hat class:
public class Hat implements Clothing {
private int rId;
private int coolness;
private Bitmap bitmap;
#JsonCreator
public Hat(#JsonProperty("coolness") int coolness, #JsonProperty("bitmap") Bitmap bitmap) {
rId = R.id.hat_image;
this.coolness = coolness;
this.bitmap = bitmap;
}
public int getrId() {
return rId;
}
#Override
public int getCoolness() {
return coolness;
}
public Bitmap getBitmap() {
return bitmap;
}
}
My composite clothing class:
public class CompositeClothing implements Clothing, Iterable<Clothing> {
#JsonProperty("coolness")
private int coolness = 0;
private List<Clothing> clothes = new ArrayList<>();
public void add(Clothing clothing) {
clothes.add(clothing);
}
public void remove(Clothing clothing) {
clothes.remove(clothing);
}
public Clothing getChild(int index) {
if (index >= 0 && index < clothes.size()) {
return clothes.get(index);
} else {
return null;
}
}
#Override
public Iterator<Clothing> iterator() {
return clothes.iterator();
}
#Override
public int getCoolness() {
return coolness;
}
#Override
public int getrId() {
return 0;
}
#Override
public Bitmap getBitmap() {
return null;
}
}
And my character class:
public class Character implements Observable {
private static final transient Character instance = new Character();
#JsonProperty("compositeClothes")
private CompositeClothing clothes = new CompositeClothing();
#JsonProperty("compositeHeadFeatures")
private CompositeHeadFeature headFeatures = new CompositeHeadFeature();
private transient List<Observer> observers = new ArrayList<>();
#JsonProperty("skin")
private Skin skin;
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void setSkin(Skin skin) {
this.skin = skin;
notifyAllObservers();
}
public Skin.Color getSkinColor() {
return skin.getColor();
}
public Bitmap getSkinBitmap() {
return skin.getBitmap();
}
public boolean hasSkin() {
return skin != null;
}
public void addClothing(Clothing clothing) {
Clothing oldClothing = (Clothing) getSameTypeObjectAlreadyWorn(clothing);
if (oldClothing != null) {
clothes.remove(oldClothing);
}
clothes.add(clothing);
notifyAllObservers();
}
public CompositeClothing getClothes() {
return clothes;
}
private Object getSameTypeObjectAlreadyWorn(Object newClothing) {
Class<?> newClass = newClothing.getClass();
for (Object clothing : clothes) {
if (clothing.getClass().equals(newClass)) {
return clothing;
}
}
return null;
}
public void removeClothing(Clothing clothing) {
clothes.remove(clothing);
}
public void addHeadFeature(HeadFeature headFeature) {
HeadFeature oldHeadFeature = (HeadFeature) getSameTypeObjectAlreadyWorn(headFeature);
if (oldHeadFeature != null) {
headFeatures.remove(oldHeadFeature);
}
headFeatures.add(headFeature);
notifyAllObservers();
}
public void removeHeadFeature(HeadFeature headFeature) {
headFeatures.remove(headFeature);
}
public CompositeHeadFeature getHeadFeatures() {
return headFeatures;
}
public static Character getInstance() {
return instance;
}
}
The code that I'm using to persist and then read the data:
File charactersFile = new File(getFilesDir() + File.separator + "characters.ser");
ObjectMapper mapper = new ObjectMapper()
.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
try (FileWriter fileOut = new FileWriter(charactersFile, false)) {
List<Character> characters = Arrays.asList(character);
mapper.writeValue(fileOut, characters);
} catch (IOException e) {
e.printStackTrace();
}
Character[] characters = null;
try (FileReader fileIn = new FileReader(charactersFile)) {
characters = mapper.readValue(fileIn, Character[].class);
} catch (IOException e) {
e.printStackTrace();
}
Thanks!
If your bitmaps come from assets or resources, there is no point on saving the bitmaps to JSON. That would be a waste of CPU time and disk space. Instead, store a value in the JSON that will allow you to identify the asset or resource to display. However, bear in mind that resource IDs (e.g., R.drawable.foo) can vary between app releases, so that is not a good durable identifier for the image.
I have similar requirement in my app where I need to store drawable data in JSON. I solved it by storing only its string name. For example, if I have resource R.drawable.testBmp then I store it in JSON like :
{
...
"mydrawable" : "testBmp"
}
Then at run time, I will read it and convert is as drawable like following code:
JSONObject jsonObj;
...
String bmpName = jsonObj.getString("mydrawable");
int resId = context.getResources().getIdentifier(bmpName,
"drawable",
context.getPackageName());
Drawable bmp = ContextCompat.getDrawable(context,resId);

Json parsing with nested array using Gson

I have not seen an (answered) example on the web which discusses this kind of nested-json-array.
JSON to be parsed:
{
"Field": {
"ObjectsList": [
{
"type": "Num",
"priority": "Low",
"size": 3.43
},
{
"type": "Str",
"priority": "Med",
"size": 2.61
}
]
}
}
I created a class for each 'level' of nested json block. I want to be able to parse the contents of the "ObjectList" array.
Can anyone help me to parse this JSON using Gson in Java?
Any hints or code-snippets would be greatly appreciated.
My approach is the following:
public static void main (String... args) throws Exception
{
URL jsonUrl = new URL("http://jsonUrl.com") // cannot share the url
try (InputStream input = jsonUrl.openStream();
BufferedReader buffReader = new BufferedReader (new InputStreamReader (input, "UTF-8")))
{
Gson gson = new GsonBuilder().create();
ClassA classA = gson.fromJson(buffReader, ClassA.class);
System.out.println(classA);
}
}
}
class ClassA
{
private String field;
// getter & setter //
}
class ClassB
{
private List<ClassC> objList;
// getter & setter //
}
clas ClassC
{
private String type;
private String priority;
private double size;
// getters & setters //
public String printStr()
{
return String.format(type, priority, size);
}
}
The following snippet and source file would help you:
https://github.com/matpalm/common-crawl-quick-hacks/blob/master/links_in_metadata/src/com/matpalm/MetaDataToTldLinks.java#L17
private static ParseResult NO_LINKS = new ParseResult(new HashSet<String>(), 0);
private JsonParser parser;
public static void main(String[] s) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(s[0]));
MetaDataToTldLinks metaDataToTldLinks = new MetaDataToTldLinks();
while (reader.ready()) {
String[] fields = reader.readLine().split("\t");
ParseResult outboundLinks = metaDataToTldLinks.outboundLinks(fields[1]);
System.out.println(tldOf(fields[0]) + " " + outboundLinks.links);
}
}
public MetaDataToTldLinks() {
this.parser = new JsonParser();
}
public ParseResult outboundLinks(String jsonMetaData) {
JsonObject metaData = parser.parse(jsonMetaData.toString()).getAsJsonObject();
if (!"SUCCESS".equals(metaData.get("disposition").getAsString()))
return NO_LINKS;
JsonElement content = metaData.get("content");
if (content == null)
return NO_LINKS;
JsonArray links = content.getAsJsonObject().getAsJsonArray("links");
if (links == null)
return NO_LINKS;
Set<String> outboundLinks = new HashSet<String>();
int numNull = 0;
for (JsonElement linke : links) {
JsonObject link = linke.getAsJsonObject();
if ("a".equals(link.get("type").getAsString())) { // anchor
String tld = tldOf(link.get("href").getAsString());
if (tld == null)
++numNull;
else
outboundLinks.add(tld);
}
}
return new ParseResult(outboundLinks, numNull);
}
public static String tldOf(String url) {
try {
String tld = new URI(url).getHost();
if (tld==null)
return null;
if (tld.startsWith("www."))
tld = tld.substring(4);
tld = tld.trim();
return tld.length()==0 ? null : tld;
}
catch (URISyntaxException e) {
return null;
}
}
public static class ParseResult {
public final Set<String> links;
public final int numNull;
public ParseResult(Set<String> links, int numNull) {
this.links = links;
this.numNull = numNull;
}
}
How about this snippet?:
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
List<Object> out = Lists.newArrayListWithCapacity(array.size());
for (JsonElement item : array) {
out.add(toRawTypes(item));
}
}

read and write data with GSON

I am struggling to find a good example on how to read and write data in my android app using GSON. Could someone please show me or point me to a good example? I am using this for data persistence between activities.
My professor gave this example to for writing:
Vector v = new Vector(10.0f, 20.0f);
Gson gson = new Gson();
String s = gson.toJson(v);
How would I go about saving that to a file?
How to save your JSON into a file on internal storage:
String filename = "myfile.txt";
Vector v = new Vector(10.0f, 20.0f);
Gson gson = new Gson();
String s = gson.toJson(v);
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(s.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
How to read it back:
FileInputStream fis = context.openFileInput("myfile.txt", Context.MODE_PRIVATE);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
String json = sb.toString();
Gson gson = new Gson();
Vector v = gson.fromJson(json, Vector.class);
Simple Gson example:
public class Main {
public class Power {
private String name;
private Long damage;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getDamage() {
return damage;
}
public void setDamage(Long damage) {
this.damage = damage;
}
public Power() {
super();
}
public Power(String name, Long damage) {
super();
this.name = name;
this.damage = damage;
}
#Override
public String toString() {
return "Power [name=" + name + ", damage=" + damage + "]";
}
}
public class Warrior {
private String name;
private Power power;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Power getPower() {
return power;
}
public void setPower(Power power) {
this.power = power;
}
public Warrior() {
super();
}
public Warrior(String name, Power power) {
super();
this.name = name;
this.power = power;
}
#Override
public String toString() {
return "Warrior [name=" + name + ", power=" + power.toString() + "]";
}
}
public static void main(String[] args) {
Main m = new Main();
m.run();
}
private void run() {
Warrior jake = new Warrior("Jake the dog", new Power("Rubber hand", 123l));
String jsonJake = new Gson().toJson(jake);
System.out.println("Json:"+jsonJake);
Warrior returnToWarrior = new Gson().fromJson(jsonJake, Warrior.class);
System.out.println("Object:"+returnToWarrior.toString());
}
}
Anyways checkout the documentation.
And to persist something in your application you can start with something simple like ORMlite.
Hope this help! :]
UPDATE:
If you really want write the json in a file:
File myFile = new File("/sdcard/myjsonstuff.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =new OutputStreamWriter(fOut);
myOutWriter.append(myJsonString);
myOutWriter.close();
fOut.close();
And if you want to read:
File myFile = new File("/sdcard/myjsonstuff.txt");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(fIn));
String aDataRow = "";
String aBuffer = ""; //Holds the text
while ((aDataRow = myReader.readLine()) != null)
{
aBuffer += aDataRow ;
}
myReader.close();
Also add: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
to your manifest.
But, seriously is so much better use a ORM and store the records in the db. I don't know why you need save the json data in a file, but if I was you, I will use the ORM way.
Maybe in more recent version, but toJson accepts writer that directly writes to file.
ex.:
Vector v = new Vector(10.0f, 20.0f);
Gson gson = new GsonBuilder().create();
Writer writerJ = new FileWriter("keep.json");
gson.toJson(v,writerJ);
Save your class in SharedPrefrences using
public static void saveYourClassInSharedPref(ClassToSave ClassToSave) {
try{
String json = "";
if(ClassToSave != null){
json = new Gson().toJson(ClassToSave);
}
SharedPref.save(KeysSharedPrefs.ClassToSave, json);
}catch (Exception ex){
ex.printStackTrace();
}
}
public static ClassToSave readYourClassFromSharedPref() {
ClassToSave ClassToSave;
try{
String json = SharedPref.read(KeysSharedPrefs.ClassToSave, "");
if(!json.isEmpty()){
ClassToSave = new Gson().fromJson(json, ClassToSave.class);
return ClassToSave;
}
}catch (Exception ex){
ex.printStackTrace();
}
return null;
}
where SharedPref.java
public class SharedPref {
public static String read(String valueKey, String valueDefault) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(App.context);
return prefs.getString(valueKey, valueDefault);
}
public static void save(String valueKey, String value) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(App.context);
SharedPreferences.Editor edit = prefs.edit();
edit.putString(valueKey, value);
edit.commit();
}
}
You can also do this entirely with streams and avoid an intermediate object:
Vector v;
// This should be reused, so private static final
Gson gson = new GsonBuilder().create();
// Read from file:
try (InputStream fileIn = context.openFileInput("myfile.txt", Context.MODE_PRIVATE);
BufferedInputStream bufferedIn = new BufferedInputStream(fileIn, 65536);
Reader reader = new InputStreamReader(bufferedIn, StandardCharsets.UTF_8)) {
gson.fromJson(reader, Vector.class);
}
v = new Vector(10.0f, 20.0f);
// Write to file
try (OutputStream fileOut = context.openFileOutput(filename, Context.MODE_PRIVATE);
OutputStream bufferedOut = new BufferedOutputStream(fileOut, 65536);
Writer writer = new OutputStreamWriter(bufferedOut)) {
gson.toJson(v, writer);
}
Choose buffer sizes appropriately. 64k is flash-friendly, but silly if you only have 1k of data. try-with-resources might also not be supported by some versions of Android.

Categories