Volley not sending the params while using JsonArrayRequest - android

The Android code is not sending the parameters when using JsonArrayRequest.
If I use StringRequest instead of JsonArrayRequest how do I convert the response from String to JSONObject to display it in a RecyclerView?
Intent intent = getIntent();
final String userID = intent.getExtras().getString("userID");
recyclerView = (RecyclerView)findViewById(R.id.display_expenses_recycler_view_id);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, expensesDisplay_url, (String) null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
int count = 0;
Log.i("Response", String.valueOf(response));
while (count < response.length()) {
try {
JSONObject jsonObject = response.getJSONObject(count);
ExpensesDetails expensesDetails = new ExpensesDetails(jsonObject.getString("Expenses"),
jsonObject.getString("Description"), jsonObject.getString("datetime"));
arrayList.add(expensesDetails);
count++;
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(DisplayExpenses.this, "Error", Toast.LENGTH_LONG).show();
error.printStackTrace();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("userID", userID);
return params;
}
};
Log.i("Array", String.valueOf(arrayList));
MySingleton.getMyInstance(DisplayExpenses.this).addToRequestQueue(jsonArrayRequest);
adapter = new RecyclerAdapterExpenses(arrayList);
recyclerView.setAdapter(adapter);View.setAdapter(adapter);
This is the result sent from the server:
[
{
"Expenses":"0",
"Description":"car",
"datetime":"2016-10-25 21:10:57"
},
{
"Expenses":"2000",
"Description":"Car",
"datetime":"2016-10-25 21:46:05"
},
{
"Expenses":"5000",
"Description":"House payment",
"datetime":"2016-10-25 21:47:11"
},
{
"Expenses":"200",
"Description":"",
"datetime":"2016-10-26 20:51:42"
},
{
"Expenses":"500",
"Description":"",
"datetime":"2016-10-26 23:55:21"
}
]

Are you sure the user ID isn't being given? You have an empty RecyclerView until the Volley request finishes. And your Log.i statement happens before Volley completes, so you'll see an empty list...
You need an adapter.notifyDataSetChanged() within the onResponse call after the while loop to tell the adapter to display the data you added.
Not too sure what View is here... but you likely don't need the same adapter on two views.
recyclerView.setAdapter(adapter);View.setAdapter(adapter);
if i tried to use StringRequest instead of JsonArrayRequest how will i convert the string response from String to JSONObject to display them in a RecyclerView
You have a String response from onResponse, so use the constructor for JSONArray that takes a String.
JSONArray array = new JSONArray(response);
Note: that requires a try-catch.

Related

How to send JSON Array of objects using Volley in android

I want to send some bulk data to my php server so I constructed JSON Array. But how to send it using volley in Android. Could you anybody help. I already tried many ways but didnt work.
Below is my code for the dataset
JSONArray jsData = new JSONArray();
JSONObject others = new JSONObject();
while(crsrallansr.isAfterLast() == false) {
JSONObject Inner = new JSONObject();
try {
Inner.put("qid",crsrallansr.getString(crsrallansr.getColumnIndex("qid")));
Inner.put("qstn",crsrallansr.getString(crsrallansr.getColumnIndex("qid")));
Inner.put("result",crsrallansr.getString(crsrallansr.getColumnIndex("qid")));
} catch (JSONException e) {
e.printStackTrace();
}
jsData.put(Inner);
crsrallansr.moveToNext();
xx++;
}
Fixed the problem using StringRequest like :
reqPostanswers = new StringRequest(Request.Method.POST, url,new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("posting info :",response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Log.i("posting error :",error.toString());
}
}){
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("user", thisuser);
params.put("answers",jsData.toString());
params.put("lickey","1761");
return params;
}
};
answerpostQueue = Volley.newRequestQueue(getApplicationContext());
answerpostQueue.add(reqPostanswers);
At the server side ( php ); the code is as follows :
$answers=json_decode($_POST['answers']);
foreach ($answers as $answer) {
$answer=json_encode($answer);
echo $answer;
$answer=json_decode($answer);
$uname=$_POST['user'];
$qid=$answer->qid;
$result=$answer->result;
$qstn=$answer->qstn;

Is there anyaway to debug volley JSONArray request is not working?

I'm new to android development and I could not debug this error.
From volley java code
private void loadPending() {
RequestQueue queue= Volley.newRequestQueue(getApplicationContext());
int type = Request.Method.POST;
String url = "http://budgetcalc.tk/api/dailybudget/pending_list.php";
JsonArrayRequest request = new JsonArrayRequest(type, url,null,
new Response.Listener<JSONArray>(){
#Override
public void onResponse(JSONArray response) {
setPendingList(response);
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Toast.makeText(getApplicationContext(), "Error "+error.getMessage(), Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("userName",userName);
return params;
}
};
queue.add(request);
}
private void setPendingList(JSONArray response) {
List<HashMap<String,String>> list=new ArrayList<>();
Toast.makeText(this, "came to setPending", Toast.LENGTH_SHORT).show();
for (int i=0;i<response.length();i++){
try {
JSONObject obj=response.getJSONObject(i);
HashMap<String,String> map= new HashMap<String,String>();
map.put("id",obj.getString("id"));
map.put("item_name",obj.getString("item_name"));
map.put("item_amount",obj.getString("item_amount"));
map.put("item_type",obj.getString("itme_type"));
list.add(map);
} catch (JSONException e) {
e.printStackTrace();
}
}
//1. Layout File
int layout = R.layout.today_done_list_layout;
//2. View List
int[] views = {R.id.today_pending_list_item_name, R.id.today_pending_list_item_amount,R.id.today_pending_list_item_type,R.id.id };
//3. Column List
String[] cols = {"item_name", "item_amount","item_type","id"};
//4. Create Simple Adapter
SimpleAdapter adapter = new SimpleAdapter(this, list, layout, cols, views);
ListView lv = findViewById(R.id.today_pending_list);
lv.setAdapter(adapter);
}
From server side use post userName value and return JSONarray,when I checked the url with my userName using POSTMAN it gives
[{"id":"9","item_name":"pen","item_amount":"1","itme_type":"Income"},{"id":"11","item_name":"pen\n\n","item_amount":"1","itme_type":"Income"}]
But I get a error from logcat
org.json.jsonexception end of input at character 0 of volley
I think userName parameter is not going to the server when I use this volley request

Store JSONArrayRequest response in Android Studio

Good morning! I've been a lot of days searching for an answer similar to this but I couldn't find it, so here I am.
In Android Studio, I've did a function which has a jsonArrayRequest request, which looks like this:
private String requestCoursesInfo() {
RequestQueue requestQueue = Volley.newRequestQueue(this.context);
JsonArrayRequest jsonArrayRequest= new JsonArrayRequest(
Request.Method.GET,
COURSES_URL,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray coursesJsonArray) {
String name;
ArrayList<HashMap> coursesBasicInfoList = new ArrayList<>();
try {
for (int i=0; i < coursesJsonArray.length(); i++){
JSONObject courseInfo = coursesJsonArray.getJSONObject(i);
name = courseInfo.getString("name");
//ArrayList to group all the info
HashMap<String, String> currentCourseInfoList = new HashMap<>();
currentCourseInfoList.put("name", name);
coursesBasicInfoList.add(currentCourseInfoList);
}
} catch (JSONException e) {
//Do something with error
}
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error){
// Do something when error occurred
}
}
){
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/json");
return params;
}
};
// Add JsonObjectRequest to the RequestQueue
requestQueue.add(jsonArrayRequest);
return "courses";
}
The thing is, as you can see, once I have the response I build a HashMap with the key name and value of the name from the response and I put it all in coursesBasicInfoList ArrayList.
The thing is, this variable (coursesBasicInfoList) is never accessible from outside the request and what I want is to be able to put this arraylist in the "return" that you can see at the end of the function.
I know the request is asynchronous but I suppose it has to be some way to store this data from the response to use it in other methods, isn't it?
Thank you!
You can use LiveData to solve synchronization problem in asynchronous call like volley.
private MutableLiveData<ArrayList<HashMap>> requestCoursesInfo() {
MutableLiveData<ArrayList<HashMap>> mutableCoursesBasicInfoList = new MutableLiveData<>();
RequestQueue requestQueue = Volley.newRequestQueue(this.context);
JsonArrayRequest jsonArrayRequest= new JsonArrayRequest(
Request.Method.GET,
COURSES_URL,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray coursesJsonArray) {
String name;
ArrayList<HashMap> coursesBasicInfoList = new ArrayList<>();
try {
for (int i=0; i < coursesJsonArray.length(); i++){
JSONObject courseInfo = coursesJsonArray.getJSONObject(i);
name = courseInfo.getString("name");
//ArrayList to group all the info
HashMap<String, String> currentCourseInfoList = new HashMap<>();
currentCourseInfoList.put("name", name);
coursesBasicInfoList.add(currentCourseInfoList);
}
} catch (JSONException e) {
//Do something with error
}
//post your result in LiveData
mutableCoursesBasicInfoList.postValue(coursesBasicInfoList);
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error){
// Do something when error occurred
}
}
){
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/json");
return params;
}
};
// Add JsonObjectRequest to the RequestQueue
requestQueue.add(jsonArrayRequest);
//Return MutableLiveData<ArrayList<HashMap>>
return mutableCoursesBasicInfoList;
}
And the observe the LiveData from your Activity/Fragment like below:
requestCoursesInfo().observe(this, new Observer<ArrayList<HashMap>>() {
#Override
public void onChanged(ArrayList<HashMap> hashMaps) {
//Do your operation here with ArrayList<HashMap>
}
});

android jsonarray cannot be converted to jsonobject error

I am working on android project and my web service successfully giving response in postman as I mention response below. I am getting below error after getting response from my API. I am not doing this types of web service call first time but don't know why this happening. How can I achieve this ?
web service response in postman -
[
{
"emp_id": 43065,
"emp_name": "Rahul Bhandari",
"username": "43065",
"password": null
}
]
Error -
org.json.JSONException: Value [{"emp_id":43065,"emp_name":"Rahul Bhandari","username":"43065","password":null}] of type org.json.JSONArray cannot be converted to JSONObject
Volley Code -
public void apiCall(final String email, final String password) {
processArray = new ArrayList<String>();
HashMap<String, String> params = new HashMap<String, String>();
params.put("username", email);
params.put("password", password);
JsonObjectRequest request_json = new JsonObjectRequest(AppConfig.login, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (mStatusCode == 200) {
try {
loginResult = new JSONArray(response.toString());
try {
if (loginResult != null) {
for (int i = 0; i < loginResult.length(); i++) {
JSONObject obj = loginResult.getJSONObject(i);
// SQLite database handler
db = new SQLiteHandler(LoginActivity.this);
// Session manager
session = new SessionManager(LoginActivity.this);
session.setLogin(true);
// Inserting row in users table
db.addUser(obj.getString("username"), obj.getString("emp_name"), obj.getString("emp_id"), obj.getString("emp_designation"), obj.getString("emp_location"));
Intent intent = new Intent(LoginActivity.this, SelectAuditActivity.class);
startActivity(intent);
finish();
Toast.makeText(LoginActivity.this, "Successfull login...", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(LoginActivity.this, "Invalid login credential...", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
//Process os success response
} else {
Toast.makeText(LoginActivity.this, "Oops sorry something went wrong...", Toast.LENGTH_SHORT).show();
}
//Process os success response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
}) {
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
mStatusCode = response.statusCode;
return super.parseNetworkResponse(response);
}
};
;
// add the request object to the queue to be executed
AppController.getInstance().addToRequestQueue(request_json);
}
JsonArrayRequest request_json = new JsonArrayRequest(AppConfig.login, new JSONArray(params),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
I think you have to replace JsonObjectRequest with JsonArrayRequest once try replacing them like above i did not tried this but hope it helps you.
Your response is a json array
[
{
"emp_id": 43065,
"emp_name": "Rahul Bhandari",
"username": "43065",
"password": null
}
]
but you are making JsonObjectRequest , do a JsonArrayRequest instead
EDIT:
I see you post body is a Json object and you cannot directly send a Json object in JsonArrayRequest , so you have to send the body using getBody() method
example request
JsonArrayRequest jsObjRequest = new JsonArrayRequest
(requestMethod, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
//do some thing with response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// handelErrorResponse
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return setHeaders();
}
#Override
public byte[] getBody() {
String body;
// convert your json object to string and send it
body= yourJsonobject.toString();
return body.getBytes();
}
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
getHeader(response);
return super.parseNetworkResponse(response);
}
};
addToRequestQueue(jsObjRequest);
These square brackets [ {...}, {...},.. ] represent for a JSONArray. So if your array have only one items, Change JsonObjectRequest to JsonArrayRequest which will return an JSONArray then get the first item from this array.
JsonArrayRequest req = new JsonArrayRequest(urlJsonArry,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSONObject result = response.get(0);
}
}
You're making a request using the object JsonObjectRequest, this mean that your request are expecting a json in the object format like:
{ a: "a", b: "b" }
but your service is responding with a json array that look like:
[{a:"a", b:"b"} , {a:"a1", b:"b1"}]
so, in order to get rid of your error change the way you make your request using JsonArrayRequest
Use this code
if (loginResult != null) {
//for (int i = 0; i < loginResult.length(); i++) {
JSONObject obj = loginResult.getJSONObject(0);
//JSONObject obj = loginResult.getJSONObject(i);
// SQLite database handler
db = new SQLiteHandler(LoginActivity.this);
// Session manager
session = new SessionManager(LoginActivity.this);
session.setLogin(true);
// Inserting row in users table
/*db.addUser(obj.getString("username"), obj.getString("emp_name"), obj.getString("emp_id"), obj.getString("emp_designation"), obj.getString("emp_location"));*/
db.addUser(obj.getString("username"), obj.getString("emp_name"), obj.getString("emp_id"),"","");
Intent intent = new Intent(LoginActivity.this, SelectAuditActivity.class);
startActivity(intent);
finish();
Toast.makeText(LoginActivity.this, "Successfull login...",
Toast.LENGTH_SHORT).show();
//}
} else {
Toast.makeText(LoginActivity.this, "Invalid login credential...", Toast.LENGTH_SHORT).show();
}
return this only from web services
{
"emp_id": 43065,
"emp_name": "Rahul Bhandari",
"username": "43065",
"password": null
}

Android Volley POST Parameters

I need to call an api that expects a string array as a POST parameter. So for an example of an API definition:
POST api/names
POST parameter expected is an array of names and some other attributes like below:
{ names: [ "John", "Bill" ], department: "Engineering" }
I am currently using a custom Volley framework as described in the Android documentation but it seems like the parameters from Volley can only be passed as a Map of (String, String as key and value). I already have the array from my Android app, ready to be passed as a post parameter but this Volley expects a String.
I tried to convert my array using Arrays.toString(myStringArray) and passed it like below but it does not work.
String[] namesArray = new String[1];
namesArray[0] = "Bill";
Map<String, String> mapParams = new HashMap<String, String>();
mapParams.put("department", "Computer Science");
mapParams.put("names", Arrays.toString(namesArray));
// Then call the Volley here passing the mapParams.
How can I call the api that expects a String of array when I can only use a String from Volley?
I will give you full code to post JsonObject on volley, through POST method.
JSONObject js = new JSONObject();
try {
js.put("genderType", "MALE");
}
} catch (JSONException e) {
e.printStackTrace();
}
String url = "LINK TO POST/";
// Make request for JSONObject
JsonObjectRequest jsonObjReq = new JsonObjectRequest(
Request.Method.POST, url, js,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e(TAG, "Response_Code from Volley" + "\n" + response.toString() + " i am king");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e(TAG, "Error: " + error.getMessage());
NetworkResponse response = error.networkResponse;
if (error instanceof ServerError && response != null) {
try {
String res = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, "utf-8"));
// Now you can use any deserializer to make sense of data
Log.e(TAG, "onErrorResponse: of uploadUser" + res);
// JSONObject obj = new JSONObject(res);
} catch (UnsupportedEncodingException e1) {
// Couldn't properly decode data to string
e1.printStackTrace();
}
}
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
return headers;
}
};
Log.e(TAG, "uploadUser: near volley new request ");
// Adding request to request queue
Volley.newRequestQueue(this).add(jsonObjReq);
}
Put anything you need in the js object with key and its values
Use JsonObjectRequest and simply pass a JSONObject. There's a full example here
public void makePostRequest(final Map<String,String> myMap,String MEDIA_URL,final VolleyResponse callback)
{
VolleySingleton VS;
Log.e("URL",MEDIA_URL);
VS=VS.getInstance();
RequestQueue rq=VS.getRequestQueue();
StringRequest stringRequest = new StringRequest(Request.Method.POST,MEDIA_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
callback.onSuccess(s);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
callback.onError();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new Hashtable<String, String>();
Iterator<Map.Entry<String, String>> iterator = myMap.entrySet().iterator();
while(iterator.hasNext()) {
Map.Entry<String,String> pairs = (Map.Entry<String,String>)iterator.next();
String value = pairs.getValue();
String key = pairs.getKey();
params.put(key,value);
Log.e("Key","Value"+value);
}
return params;
}
};
//Creating a Request Queue
// RequestQueue requestQueue = Volley.newRequestQueue(this);
DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(retryPolicy);
//Adding request to the queue
rq.add(stringRequest);
}
Where the VolleyResponse is a simple custom interface like this
public interface VolleyResponse {
void onSuccess(String resp);
void onError();
}

Categories

Resources