I have a String declared at a class level.
String eta;
I am passing a url to a method in that same class that will use volley to retrieve distance from one of Google apis. I then assign the response String to my global variable eta. It has the needed value within the method but the global value is null when it is returned. I can't understand this behavior. What am I doing wrong here?
public String getDuration(String url){
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String j = response.getString("rows");
JSONArray rowa = new JSONArray(j);
JSONObject rowobj = rowa.getJSONObject(0);
JSONArray elementsa = rowobj.getJSONArray("elements");
for (int i = 0; i < elementsa.length(); i++) {
JSONObject currentObject = elementsa.getJSONObject(i);
String duration = currentObject.getString("duration_in_traffic");
JSONObject timeObject = new JSONObject(duration);
**eta = timeObject.getString("text"); //eta has the needed value**
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsObjRequest);
**return eta; //here eta is null**
}
onResponse(JSONObject response) is asynchronous.
You are calling getDuration(String url) and setting a listener that will be called when the network operation ends.
Instead of waiting the listener to be called you are returning the value (that it is not set at the moment) and that's why you get a null value.
Inside onResponse(JSONObject response) you should call the method that needs eta value.
public void getDuration(String url){
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String j = response.getString("rows");
JSONArray rowa = new JSONArray(j);
JSONObject rowobj = rowa.getJSONObject(0);
JSONArray elementsa = rowobj.getJSONArray("elements");
for (int i = 0; i < elementsa.length(); i++) {
JSONObject currentObject = elementsa.getJSONObject(i);
String duration = currentObject.getString("duration_in_traffic");
JSONObject timeObject = new JSONObject(duration);
eta = timeObject.getString("text"); //eta has the needed value**
methodThatUsesValue(eta);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsObjRequest);
}
Related
Below is the response what i am getting i want to get the data from "SourceJson" m not ble to understnd why i am getting "" in source json please help me
{
"incomingOrder": [
{
"Namw": 8510,
"Surname": "00",
"mob": "00",
"phone": "000",
"SourceJson": "{\"cart_gst\":30.21,\"instructions\":\"\",\"order_packing_charges\":30,\"cart_igst_percent\":0,\"cart_sgst\":15.1038,}",
"test": "NotSynced",
"test": "DPA",
}]}
Try this code :
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest obreq = new JsonObjectRequest(Request.Method.GET, JsonURL,
// The third parameter Listener overrides the method onResponse() and passes
//JSONObject as a parameter
new Response.Listener<JSONObject>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("incomingOrder");
JSONObject jsonObject = jsonArray.getJSONObject(0);
JSONObject objSourceJson=jsonObject.getJSONObject("SourceJson");
Log.i("IvaSourceJson",objSourceJson.toString());
String cart_gst=objSourceJson.getString("cart_gst");
String instructions=objSourceJson.getString("instructions");
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error");
}
}
);
// Adds the JSON object request "obreq" to the request queue
requestQueue.add(obreq);
As it is JSONArray data is of list type, better not to use jsonArray.getJSONObject(0);.
Use this code for multiple results,
StringRequest request = new StringRequest(Request.Method.GET, "", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response", response);
try {
JSONObject object = new JSONObject(response);
JSONArray array = object.getJSONArray("incomingOrder");
for (int i = 0; i < array.length(); i++){
JSONObject object1 = array.getJSONObject(i);
String name = object1.getString("Namw");
String surname = object1.getString("Surname");
String mob = object1.getString("mob");
String phone = object1.getString("phone");
String sourceJson = object1.getString("SourceJson");
String test = object1.getString("test");
String test1 = object1.getString("test");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error", error.getMessage());
}
});
Context context;
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(request);
Code this in any method and call the method where the action needed.
I have using volley library for fetching data. I used a HashMap to store response data. When I fetch the data out of the volley request it is showing empty. I knew I should use this Hashmap inside the response method. But I need to get that in a global variable. Any suggestions?
String liveURL = BASE_URL + "livescores?api_token=" + API_KEY;
HashMap<String, String> hashMap = new HashMap<>();
JsonObjectRequest livescoresRequest = new JsonObjectRequest(Request.Method.GET,
liveURL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
final JSONArray liveArray = response.getJSONArray("data");
for (int i = 0; i < liveArray.length(); i++) {
JSONObject data = liveArray.getJSONObject(i);
String liveID = data.getString("id");
final String league_id = data.getString("league_id");
hashMap.put(league_id, liveID);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error", error.toString());
}
});
Volley.newRequestQueue(getContext()).add(livescoresRequest);
Log.i("HASHMAP", hashMap.toString());
I am trying to parse some information from a json file in android studio. I have followed a tutorial on how to do so, however I have run into a null pointer exception error while trying to fetch some information from the json file.
This is my parseJson function:
private void parseJson() {
String url = "https://api.myjson.com/bins/108hcz";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject person = jsonArray.getJSONObject(i);
String name = person.getString("gender");
Log.e ("NAME:", name);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mQueue.add(request);
}
This is the error I receive:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.pogolemotoproektce/com.example.pogolemotoproektce.Activities.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.android.volley.Request com.android.volley.RequestQueue.add(com.android.volley.Request)' on a null object reference
cause from this line:
mQueue.add(request);
My JSON file:
http://myjson.com/108hcz
What happens to be the problem here?
mQueue is not initialized that's why you getting null pointer exception so initialize mQueue before use.
mQueue = Volley.newRequestQueue(your_context);
or you can directly call add with
Volley.newRequestQueue(your_context).add(request);
I have used like below
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "https://api.myjson.com/bins/108hcz";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject person = jsonArray.getJSONObject(i);
String name = person.getString("gender");
Log.e("NAME:", name);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
Volley.newRequestQueue(this).add(request);
}
}
I am working on an android app.
I want to retrieve json data into an ArrayList of my data model called Expert.
Here is the code on the onCreate() method
mExpertsList = new ArrayList<Expert>();
loadData();
Log.v("RESPONSE", Integer.toString(mExpertsList.size()));
Here is the code in the function retrieving json data.
private void loadData(){
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jarray = response.getJSONArray("actors");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Expert expert = new Expert();
expert.setImageUrl(object.getString("image"));
expert.setName(object.getString("name"));
expert.setTopic(object.getString("country"));
expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
expert.setDescription(object.getString("description"));
mExpertsList.add(expert);
}
}
catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsonObjectRequest);
}
Inside loadData() method the mExpertsList shows size of 6 at end of for loop. Checked this using log messages.
But a Log statement immediately after loadData() shows that mExpertsList has size of zero.
What am I missing here?
JsonObjectRequest is an Asynchronous request so your list will be update on other thread . And you logged the size synchronously so it will print 0 always .
Access the List inside onResponse(JSONObject response);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jarray = response.getJSONArray("actors");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Expert expert = new Expert();
expert.setImageUrl(object.getString("image"));
expert.setName(object.getString("name"));
expert.setTopic(object.getString("country"));
expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
expert.setDescription(object.getString("description"));
mExpertsList.add(expert);
}
Log.v("RESPONSE", mExpertsList.size());
}
catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
mExpertsList = new ArrayList<Expert>(); // You are initializing your list with size 0
loadData(); // Calling the API which will run in background
So whenever you are calling
Log.v("RESPONSE", Integer.toString(mExpertsList.size()));just after loadData() method your mExpertsList is still of size 0.
Size will change only after you get your API response.
This is an Asynchronous operation, Volley will not wait for your response and execute your next code.
If you want to print Arraylist size then print it just after for loop,
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jarray = response.getJSONArray("actors");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Expert expert = new Expert();
expert.setImageUrl(object.getString("image"));
expert.setName(object.getString("name"));
expert.setTopic(object.getString("country"));
expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
expert.setDescription(object.getString("description"));
mExpertsList.add(expert);
}
Log.v("RESPONSE", mExpertsList.size());
}
catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
It will print the exxact size of your list.
It looks like you are making some kind of asynchronous call when you call loadData():
mExpertsList = new ArrayList<Expert>();
loadData();
Log.v("RESPONSE", Integer.toString(mExpertsList.size()));
When you check the size, it is possible that onResponse(), the handler for the web call, has not yet been called. If so, then the size would still appear to be zero.
You should only be relying on the contents of mExpertsList being there if onResponse has been successfully called with actual content.
Do this change in part 1:
mExpertsList = new ArrayList<Expert>();
loadData();
//Log.v("RESPONSE", Integer.toString(mExpertsList.size()));----Comment it out
Change in part 2:
private void loadData(){
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "http://microblogging.wingnity.com/JSONParsingTutorial/jsonActors",
null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jarray = response.getJSONArray("actors");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Expert expert = new Expert();
expert.setImageUrl(object.getString("image"));
expert.setName(object.getString("name"));
expert.setTopic(object.getString("country"));
expert.setRating(random.nextFloat() * ((maxRating - minRating) + minRating));
expert.setDescription(object.getString("description"));
mExpertsList.add(expert);
Log.v("RESPONSE", Integer.toString(mExpertsList.size())); //-----New ADDED
}
}
catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsonObjectRequest);
}
I have a JSON that retrieves all the users of a database. To simplify, I will show the first two users:
[
{
"id":"1",
"name":"Peter",
"age":"25"
},
{
"id":"2",
"name":"Andrew",
"age":"32"
},
...
]
As you can see, it is an array without name that contains some JSONObjects so I have tried to retrieve these data from Android with Volley library going through the whole array but without success.
Here is the code that I have by the moment:
RequestQueue queue = Volley.newRequestQueue(getContext());
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try{
if (response != null) {
for(int i = 0; i < response.length(); i++){
JSONObject obj = response.getJSONObject(i);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("LOG", error.toString());
}
});
queue.add(jsonArrayRequest);
It always gives to me the following error:
Unhandled exception: org.json.JSONException
I also tried to retrieve the JSONArray before trying to retrieve the JSONObject but it does not allowed me because the method
JSONArray json = response.getJSONArray(0);
also gave to me the same error that I have pointed before.
I looked for a lot of examples and I cannot see where my problem is.
What am I doing wrong?
Thanks in advance!
You are not handling JSONException.
Give this a try.
StringRequest request = new StringRequest(Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response)
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Cannot resolve constructor 'JsonArrayRequest(int, java.lang.String, anonymous com.android.volley.Response.Listener<org.json.JSONArray>, anonymous com.android.volley.Response.ErrorListener)'
Error doesn't lie. That request doesn't accept a Method type.
JsonArrayRequest(
String url,
Response.Listener<JSONArray> listener,
Response.ErrorListener errorListener)
StringRequest, on the other hand, does.
StringRequest(
int method,
String url,
Response.Listener<String> listener,
Response.ErrorListener errorListener)
Regarding,
Unhandled exception: org.json.JSONException
response.getJSONObject will throw that exception, so you must use a try-catch.
if (response != null) {
try {
for (int i = 0; ...) {
JSONObject jo = response.getJSONObject(i);
// use 'jo'
}
} catch (JSONException e) {
e.printStackTrace();
}
}
You should add final in final JsonArrayRequest
GOOD LUCK !!
final JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url,null, new Response.Listener() {
#Override
public void onResponse(JSONArray response) {
try{
if (response != null) {
for(int i = 0; i < response.length(); i++){
JSONObject obj = response.getJSONObject(i);
String tieude = obj.getString("tieudetin");
Toast.makeText(test.this,tieude,Toast.LENGTH_SHORT).show();
//txt.setText(tieude+"");
}
}
}catch(Exception e){
e.getMessage();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mQueue.add(jsonArrayRequest);