Android SharedPreference JSON not being accessed - android

I am using volley to send a http request to yahoo's weather API like this:
public Object requestData(String url) {
final RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest objectRequest = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener < JSONObject > () {
#Override
public void onResponse(JSONObject response) {
String responseList = response.toString();
cityList.edit().putString(String.valueOf(i), responseList);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
requestQueue.add(objectRequest);
return null;
}
As you can see, I am putting the response to this inside a sharedpreference I declared as "citylist"
:
cityList = getSharedPreferences(String.valueOf(i), MODE_PRIVATE);
I then access this response inside the sharedpreference like this:
String mResponse = cityList.getString(String.valueOf(i), "");
Log.d("log", mResponse);
try {
JSONObject jsonObj = new JSONObject(mResponse);
JSONObject response = jsonObj.getJSONObject("query");
createdCity.temperature = response.optJSONObject("results").optJSONObject("channel").optJSONObject("item").optJSONObject("condition").getInt("temp");
createdCity.conditions = response.optJSONObject("results").optJSONObject("channel").optJSONObject("item").optJSONObject("condition").getString("text");
createdCity.town = response.optJSONObject("results").optJSONObject("channel").optJSONObject("location").getString("city");
createdCity.country = response.optJSONObject("results").optJSONObject("channel").optJSONObject("location").getString("country");
createdCity.state = response.optJSONObject("results").optJSONObject("channel").optJSONObject("location").getString("region");
Log.d("log", String.valueOf(createdCity.town));
cities.add(createdCity);
addMenuItemInNavMenuDrawer();
} catch (JSONException e) {
e.printStackTrace();
}
The problem is that "log" isn't outputting anything. The only information I'm getting from the logcat is:
org.json.JSONException: End of input at character 0 of
How can I go about fixing my issue? Is there a better way of doing this?

Are you committing after editing the preference? Based on your response, you might as well use apply() as it does things asynchronously.
If you are sure that the commit won't affect the main thread, you can use cityList.commit() or safely use cityList.apply(). But you need to do either of these two or else the changes are not written to the disk which is the reason you are not able to retrieve the data.
This link should help:
https://developer.android.com/training/data-storage/shared-preferences#java

Related

Not able to fetch JSON data [using volley Library] in Android

The jason array request code goes like this:
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.GET,url, (JSONArray) null , new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
Log.d("Response:", String.valueOf(response.getJSONObject(0)));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, "Response not recieved", Toast.LENGTH_SHORT).show();
}
});
And I've used a singleton instance of a request queue, to fetch the data,
AppController.getInstance(context.getApplicationContext()).addToRequestQueue(arrayRequest);
I'm using an api service that supplies a bunch of questions (The api generates a url, which returns a collection of JSON Objects, An Array (Just try and Open the url link, the json array will be seen)
But when I run the app, the request is not even getting a response,the progam flow is going into the error listner block.
Can someone explain this behaviour? Is it because the JSON array supplied by the url, has nested arrays? Why?
I tried reading and anlyzing other questions here, which might have the same issue, But i found nothing.
You want to just change JsonArrayRequest to JsonObjectRequest:
Please copy and paste below code:
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("TAG", response.toString());
try {
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String category = jsonObject.getString("category");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("TAG", "Error: " + error.getMessage());
// hide the progress dialog
}
});
AppController.getInstance().addToRequestQueue(jsonObjReq, "TAG");
Follow this link for learn other request: Androidhive

Json Array response doesn't see value for item

I Know at first glance it's known mistake made by beginners but:
My standard response looks like this:
public ArrayList<Beer> jsonResponse(){
beerList.clear();
requestQueue = Volley.newRequestQueue(this);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
Constants.BASE_API_URL + Constants.BEER_LIST_URL_ENDPOINT,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
for (int i = 0; i < response.length(); i++) {
JSONObject beerJsonObject = response.getJSONObject(i);
System.out.println(response.toString());
Beer beer = new Beer();
if (beerJsonObject.has("yeast")) {
beer.setYeast(beerJsonObject.getString("yeast"));
}
beer.setName(beerJsonObject.getString("name"));
beer.setIbu(beerJsonObject.getString("ibu"));
beer.setAlc(beerJsonObject.getString("abv"));
beer.setImgUrl(beerJsonObject.getString("image_url"));
beer.setId(beerJsonObject.getString("id"));
beer.setDescription(beerJsonObject.getString("description"));
beer.setFoodPairing(beerJsonObject.getString("food_pairing"));
beer.setFirstBrewed(beerJsonObject.getString("first_brewed"));
System.out.println(beer.getName()+" "+beer.getIbu()+" "+beer.getImgUrl());
beerList.add(beer);
}
beerRecyclerViewAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
);
// Add JsonArrayRequest to the RequestQueue
requestQueue.add(jsonArrayRequest);
return beerList;
}
Everything works except "yeast" item:
if (beerJsonObject.has("yeast")) {
beer.setYeast(beerJsonObject.getString("yeast"));
}
without that if statement I've got standard json err. response no value for "yeast", I thought maybe not every object in response has this value and added that. But that doesn't helped, I still can't get that value, like it wouldn't exist in array, but it's not true, even in System.out.println(response.toString()) I can see a lot of "yeast" .
Here is example response from API I'm working with: https://api.punkapi.com/v2/beers
yeast is under ingredients
so should be:
if (beerJsonObject.has("ingredients")) {
JSONObject ingredients = beerJsonObject.getJSONObject("ingredients");
if (ingredients.has("yeast")) {
beer.setYeast(ingredients.getString("yeast"));
}
}

Android App Crashing While Trying To Parse Json Object Using Volley

requestQueue = Volley.newRequestQueue(Home.this);
JsonObjectRequest objectRequest = new JsonObjectRequest(com.android.volley.Request.Method.GET ,"http://www.omdbapi.com/?t=avengers",null,new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String Title = response.getString("Title");
String Year = response.getString("Year");
String Released = response.getString("Released");
String Genre = response.getString("Genre");
String Metascore = response.getString("Metascore");
String imdbRating = response.getString("imdbRating");
String Poster = response.getString("Poster");
moviesData = new String[]{Title, Year, Released, Genre, Metascore, imdbRating, Poster};
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(objectRequest);
I am trying to fetch data from the site and store its content using json parsing and volley i was doing it with HttpUrlConnection and it was working fine when i tried to do it using volley I got stuck
I don't know where I am going wrong or missing something don't know why App is crashing.
That was my own fault I was writing this code in the wrong method.

Android volley : how to check json type before parsing it

Is it possible to check the type of json beforehand? I'm somteimes getting an array and sometimes an object and I don't see how to handle these 2 cases without doing 2 different functions...
public void RequestApi( String url, final ApiResponse<ApiResult> completion )
{
Log.v("Performing request: ", url);
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.GET, hostname+url, (JSONObject) null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response)
{
Log.v("RequestApi Response", response.toString());
//Log.v("Data: ", response.toString());
try {
ApiResult res = new ApiResult();
Boolean success = response.getBoolean("success");
//here need to check type, sometimes array, sometimes object
JSONArray data = response.getJSONArray("data");
res.success = success;
res.data = data;
completion.onCompletion(res);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
ApiResult res = new ApiResult();
res.success = false;
completion.onCompletion(res);
}
}
);
AppController.getInstance().addToRequestQueue(jsonRequest);
}
Use StringRequest
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Object json = new JSONTokener(response).nextValue();
if (json instanceof JSONObject)
//you have an object
else if (json instanceof JSONArray)
//you have an array
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO something
}
});
Most simple solution - look at first string character. If it is { - object, if [ - array. But I think better to do following:
try {
JSONObject object = new JSONObject(value);
}
catch (JSONException) {
//if it throws, "value" contains not a JSONObject
JSONArray array = new JSONArray(value);
}
After going through the API I found a simple solution.
Since you are not sure of the return type, follow mentioned below steps.
First:
JSONArray arrayInstance = new JSONArray();// declare array instance to handle both the cases
Object objectInstance = rootObject.get(key); //key is the response string holding the value either jsonArray or jsonObject
Second:
if(objectInstance instanceof JSONArray){
arrayInstance = rootObject.getJSONArray(key);
}
else{
JSONObject tempObject = rootObject.getJSONObject(key);
arrayInstance.put(tempObject);
}
Third:
You can iterate though the array for the desired processing.

Android volley saving json data to string for sharing (onPostExecute method for volley?)

I am using volley library to get data from an api in JSON format, and it works like a charm. I ask for JSON file, i get a response, i parse that respons and populte the views in activity.
Now, i have a button to share the data using Intetnt.ACTION_SEND and putExtra(Intent.EXTRA_TEXT) that takes string as the 2nd parameter.
The problem is, i make a string variable and append data in that string variable inside volley on response method. but as volley makes a new thread for getting data from api the string is not updated and Intetnt.EXTRA_TEXT sends an empty string.
I want to ask, if there is anything similer to onPostExecute method for volley? where i can set the data to some variables after the thread is done processing. or any alternate methods to do the same.
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.GET, bookSearchString, null,
new Response.Listener<JSONObject>() {
public void onResponse(JSONObject response) {
try {
JSONArray bookArray = response
.getJSONArray("items");
JSONObject bookObject = bookArray.getJSONObject(0);
try {
bookSelfLink = bookObject.getString("selfLink");
JsonObjectRequest newJsObjRequest = new JsonObjectRequest(
Request.Method.GET, bookSelfLink, null,
new Response.Listener<JSONObject>() {
public void onResponse(
JSONObject response) {
try {
JSONObject newBookObject = response
.getJSONObject("volumeInfo");
try {
dBookPages.setText("Pages - "
+ newBookObject
.getString("pageCount"));
eMailText = eMailText + newBookObject
.getString("pageCount"));
} catch (JSONException jse) {
dBookPages
.setText("Pages not found");
jse.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(
VolleyError error) {
// TODO Auto-generated method
// stub
}
});
AppController.getInstance().addToRequestQueue(
newJsObjRequest, tag_json_obj);
} catch (JSONException jse) {
jse.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
AppController.getInstance().addToRequestQueue(jsObjRequest,
tag_json_obj);
from the Volley v1.0.0 Documentation:
public boolean hasHadResponseDelivered()
Returns true if this request has had a response delivered for it.
I hope that this answer would help someone with the same question.
There were 2 work around for the record.
1) make network call on button click -> wait for response -> fire intent inside onResponse with bundled data.
2) pass url as string in bundle -> call intent for new activity -> make network request pars data.

Categories

Resources