Gson Reader can be readed only once? - android

I'm doing some tests with Gson parser to Json objects and object model.
There is one thing that I can't understand, why Reader can read once?
Code example:
Reader targetReader = new StringReader(jdb);
String targetString = "";
try {
int intValueOfChar;
while ((intValueOfChar = reader.read()) != -1) {
targetString += (char) intValueOfChar;
}
} catch (IOException e) {
e.printStackTrace();
}
JsonParser jp = new JsonParser();
JsonObject jason = jp.parse(reader).getAsJsonObject();
JsonArray votes_a = jason.getAsJsonArray("votesA");
JsonArray votes_b = jason.getAsJsonArray("votesB");
In this code the first while goes perfect, reads and writes to String but then I want to read it and parset to Object but the reader is empty!!
is there a way to keep the information, and recycle it?
Do I have to clone it before? how?

Because when you read from the reader, it moves a pointer along what you're reading. So after reading through it once, you're already at the end of what you're reading. Take a look at the reset() method of StringReader.

Related

Android device incomplete JSON?

From my Android application I write a JSON string to a JSON-file located on an Android tablet in /sdcard/subdirectory, in the onStop()-method. This function executes succesfully.
If I copy this resulting .json-file from the Android device to my computer and I open this JSON-file in Notepad++, the JSON is not valid: it is incomplete.
This is the content of said JSON-file:
{... there are about 20 of these elements, I won't list them all for readability...},
{"name":"Marker7","long":2.924128,"lat":51.204594,"warning":"Sharp turn"},
{"name":"Marker8","long":2.9260479999999998,"lat":51.203364,"warning":"Dead end"},
{"name":"Marker9","long":2.926252,"lat":51.203209,"warning":"
As you can see, the JSON is cut off at the warning part of Marker9, making this invalid JSON.
What is weird is the following: my application also reads from this file in the onCreate()-method, and if I print this JSON, it does show the correct and complete JSON! So within my Android app I don't experience any issues, and I assume my writing method and the resulting JSON-file is working as intended since the correct data is retrieved from the reading-function. However if I want to copy this JSON and use it elsewhere I won't have a valid JSON-file.
Why is this? Does this have something to do with the ext4-filesystem that my Android device is using?
I also noticed that this seems to happen when the file reaches the 1.18kB size mark (as shown in my explorer view, but again: the correct and complete IS retrieved within the Android app...), because each time I copy the file and it appears to be cut off, the size is always exactly 1.18kB.
Update
The code for reading the JSON:
public String loadJSON() {
String json = null;
try {
//InputStream is = getAssets().open("markers.json");
File jsonFile = new File(Environment.getExternalStorageDirectory(), "osmdroid/markers.json");
FileInputStream is = new FileInputStream(jsonFile);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
private void readJsonMarkers() throws JSONException {
JSONObject obj = new JSONObject(loadJSON());
JSONArray jsonArray = obj.getJSONArray("markers");
System.out.println("JSON LOAD: " + jsonArray); // this shows the correct, full list of markers
}
The code for writing the JSON:
private void writeJsonMarkers() throws JSONException {
JSONArray data = new JSONArray();
for(OverlayItem oi: waypointMarkers){
JSONObject obj = new JSONObject();
try {
obj.put("name", oi.getTitle());
obj.put("long", oi.getPoint().getLongitude());
obj.put("lat", oi.getPoint().getLatitude());
obj.put("warning", oi.getSnippet());
data.put(obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
JSONObject rootObj = new JSONObject(loadJSON());
rootObj.remove("markers");
rootObj.put("markers",data);
// this method is used to remove the existing markers-list from the JSON, and add an updated markers-list to it
File jsonFile = new File(Environment.getExternalStorageDirectory(), "osmdroid/markers.json");
try {
FileWriter jsonWriter = new FileWriter(jsonFile);
jsonWriter.write(rootObj.toString());
jsonWriter.flush();
jsonWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Create JSON Object from Local JSON File

How do I create a "JSONObject" from a local JSON file inside my "raw" folder.
I have the following JSON file under the "raw" folder of my android app project. The file is called "app_currencies.json". I need the information contained on this file as an object in my class. Below are the file contents:
{
"EUR": { "currencyname":"Euro", "symbol":"EUR=X", "asset":"_European Union.png"},
"HTG": { "currencyname":"Haitian Gourde", "symbol":"HTG=X", "asset":"ht.png"},
"WST": { "currencyname":"Samoan Tala", "symbol":"WST=X", "asset":"ws.png"},
"GBP": { "currencyname":"British Pound", "symbol":"GBP=X", "asset":"gb.png"}
}
I think what I need is to use the following:
//Get data from Json file and make it available through a JSONObject
InputStream inputStream = getResources().openRawResource(R.raw.app_currencies.json);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JSONObject jObject = new JSONObject;
jObject is what I need. I think I need an InputStream, ByteArrayOutputStream so that I can store it into JSONObject... the problem is that I'm not sure how to implement this code properly so that I can access the data? If any of you could give detailed instructions on how to do this, I would really appreciate it.
The following code reads a json file into a Json Array. See if it helps. Note, the file is stored in Assets instead
BufferedReader reader = null;
try {
// open and read the file into a StringBuilder
InputStream in =mContext.getAssets().open(mFilename);
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder jsonString = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
// line breaks are omitted and irrelevant
jsonString.append(line);
}
// parse the JSON using JSONTokener
JSONArray array = (JSONArray) new JSONTokener(jsonString.toString()).nextValue();
// do something here if needed from JSONObjects
for (int i = 0; i < array.length(); i++) {
}
} catch (FileNotFoundException e) {
// we will ignore this one, since it happens when we start fresh
} finally {
if (reader != null)
reader.close();
}

Adding static JSON to an Android Studio project

I'd like to add static JSON to an Android Studio project which can then be referenced throughout the project. Does anyone know the best method of doing this?
In more detail what I'm trying to do is this:
1) Pull data out of the Google Places API
2) Find Google places that match with places in a static JSON object
3) Place markers on a map based on the matches
I have numbers 1 and 3 working, but would like to know the best way of creating a static (constant) JSON object in my project and using it for step 2.
The answer posted above is indeed what I'm looking for, but I thought I'd add some of the code I implemented to help others take this problem further:
1) Define JSON object in a txt file in the assets folder
2) Implement a method to extract that object in string form:
private String getJSONString(Context context)
{
String str = "";
try
{
AssetManager assetManager = context.getAssets();
InputStream in = assetManager.open("json.txt");
InputStreamReader isr = new InputStreamReader(in);
char [] inputBuffer = new char[100];
int charRead;
while((charRead = isr.read(inputBuffer))>0)
{
String readString = String.copyValueOf(inputBuffer,0,charRead);
str += readString;
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
return str;
}
3) Parse the object in any way you see fit. My method was similar to this:
public void parseJSON(View view)
{
JSONObject json = new JSONObject();
try {
json = new JSONObject(getJSONString(getApplicationContext()));
} catch (JSONException e) {
e.printStackTrace();
}
//implement logic with JSON here
}
You can just place your JSON file into assets folder. Later on you'll be able to read the file, parse it and use values.
You should replace the String datatype to StringBuilder in the while loop for the properly optimized solution.
So in the while loop instead of concatenating you would append the readString to the str StringBuilder.
str.append(readString);

Retrieve value from JSON responce

I am writing an android application and currently i am getting a JSON reply:
{"Error":"User already exists"}
this is an example of the messages that i get returned
the part that i am after is : "User already exists" and i need to parse it.
The message is currently stored in a string so i would need to convert this to a JSONArray to then convert it to a JSONOject to then be able to call the getString().
what would be the best way to do this?
this may Helps You
String Respones= "{\"Error\":\"User already exists\"}";
try {
JSONObject jobj = new JSONObject(Respones);
String strError = jobj.getString("Error");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I think you can do it directly with JSONTokener and JSONObject if you want ot use default andoid tools.
If you want better, look into the Jackson lib, it's very powerful, open source, kind of standard:
Android JSON Jackson Tutorial
Try this code
JSONArray jsonArray = new JSONArray(ResponseString);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String result = jsonObject.getString("Error").toString().trim();
}

Android parse json from url and store it

Hi there i'm creating my first android app and i'm wanting to know what is the best and most efficient way of parsing a JSON Feed from a URL.Also Ideally i want to store it somewhere so i can keep going back to it in different parts of the app. I have looked everywhere and found lots of different ways of doing it and i'm not sure which to go for. In your opinion whats the best way of parsing json efficiently and easily?
I'd side with whatsthebeef on this one, grab the data and then serialize to disk.
The code below shows the first stage, grabbing and parsing your JSON into a JSON Object and saving to disk
// Create a new HTTP Client
DefaultHttpClient defaultClient = new DefaultHttpClient();
// Setup the get request
HttpGet httpGetRequest = new HttpGet("http://example.json");
// Execute the request in the client
HttpResponse httpResponse = defaultClient.execute(httpGetRequest);
// Grab the response
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
// Instantiate a JSON object from the request response
JSONObject jsonObject = new JSONObject(json);
// Save the JSONOvject
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(getCacheDir(),"")+"cacheFile.srl"));
out.writeObject( jsonObject );
out.close();
Once you have the JSONObject serialized and save to disk, you can load it back in any time using:
// Load in an object
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File(new File(getCacheDir(),"")+"cacheFile.srl")));
JSONObject jsonObject = (JSONObject) in.readObject();
in.close();
Your best bet is probably GSON
It's simple, very fast, easy to serialize and deserialize between json objects and POJO, customizable, although generally it's not necessary and it is set to appear in the ADK soon. In the meantime you can just import it into your app. There are other libraries out there but this is almost certainly the best place to start for someone new to android and json processing and for that matter just about everyone else.
If you want to persist you data so you don't have to download it every time you need it, you can deserialize your json into a java object (using GSON) and use ORMLite to simply push your objects into a sqlite database. Alternatively you can save your json objects to a file (perhaps in the cache directory)and then use GSON as the ORM.
This is pretty straightforward example using a listview to display the data. I use very similar code to display data but I have a custom adapter. If you are just using text and data it would work fine. If you want something more robust you can use lazy loader/image manager for images.
Since an http request is time consuming, using an async task will be the best idea. Otherwise the main thread may throw errors. The class shown below can do the download asynchronously
private class jsonLoad extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
// Instantiate a JSON object from the request response
try {
JSONObject jsonObject = new JSONObject(result);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File file = new File(getApplicationContext().getFilesDir(),"nowList.cache");
try {
file.createNewFile();
FileOutputStream writer = openFileOutput(file.getName(), Context.MODE_PRIVATE);
writer.write(result);
writer.flush();
writer.close();
}
catch (IOException e) { e.printStackTrace(); return false; }
}
}
Unlike the other answer, here the downloaded json string itself is saved in file. So Serialization is not necessary
Now loading the json from url can be done by calling
jsonLoad jtask=new jsonLoad ();
jtask.doInBackground("http:www.json.com/urJsonFile.json");
this will save the contents to the file.
To open the saved json string
File file = new File(getApplicationContext().getFilesDir(),"nowList.cache");
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {
//print log
}
JSONObject jsonObject = new JSONObject(text);

Categories

Resources