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);
}
}
Related
I have some error parse Json on Android Studio,
Please if you have any idea can you share where is my error.
I want to get the current exchange rate information and print it on textview.
Json/Api Url : https://api.exchangeratesapi.io/latest?base=USD
private void jsonParse() {
String SHOP_URL = "https://api.exchangeratesapi.io/latest?base=USD&symbols=EUR,GBP";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, SHOP_URL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("rates");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject result = jsonArray.getJSONObject(i);
int xGBP=result.getInt("GBP");
usdtry.setText(String.valueOf(xGBP));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
pRequestQueue.add(request);
}
This code not erroring but not response any..I think i have some missing.
rates is a JsonObject, not an Array.
So, your code must be
JSONObject rates = response.getJSONObject("rates");
double xGBP = rates.getDouble("GBP");
usdtry.setText(String.valueOf(xGBP));
Also, for better formatting, you can use:
DecimalFormat formatter = new DecimalFormat("###,###.##", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
usdtry.setText(formatter.format(xGBP));
I need help in modifying my android studio code for converting Json object to an array. Bellow is the error in my log cat and the actual code.
This is the error message I am getting in the logcat:
04-03 12:01:16.727 19993-19993/com.errandit E/Volley: com.android.volley.ParseError: org.json.JSONException: Value {"data":[{"errand":"Shopping","charges":"500"},{"errand":"House Assistance","charges":"7000"},{"errand":"Pick - Up","charges":"2500"}],"success":1,"message":" 0 records found"} of type org.json.JSONObject cannot be converted to JSONArray
**I am trying to fetch the json array from my wamp server using the method below. **
private void getData(){
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading");
progressDialog.show();
final JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
Service service = new Service();
service.setName(jsonObject.getString("errand"));
service.setCharges(jsonObject.getInt("charges"));
serviceList.add(service);
} catch (JSONException e) {
e.printStackTrace();
progressDialog.dismiss();
}
}
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley",error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
Change like below as You are getting JSONObject and inside it there is JSONArray named "data".
JsonObjectRequest jsonObjRequest = new JsonObjectRequest
(Request.Method.POST, url, jsonObj, new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject mResponse)
{
JSONArray response=mResponse.optJSONArray("data")
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
Service service = new Service();
service.setName(jsonObject.getString("errand"));
service.setCharges(jsonObject.getInt("charges"));
serviceList.add(service);
} catch (JSONException e) {
e.printStackTrace();
}
}
adapter.notifyDataSetChanged();
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
});
// Add the request to the RequestQueue.
queue.add(jsonObjRequest);
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);
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);
}