Volley java.lang.UnsupportedOperationException - android

I'm trying to convert my app to use WebAPI and token authenication. I'm also moving away from Apache http and using volley.
Below i have a class called NetworkManager that handles the volley requests.
In my main Activity there is a login button that calls a method getAuthenicationTokens from the networkManager class. I have used a customeListener to relay the response back to the calling Activity.
CustomListener:
public interface CustomListener<T>
{
public void getResult(T object);
}
.
Activity:
buttonLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NetworkManager.getInstance().getAuthenticationTokens(null, new CustomListener<JSONObject>()
{
#Override
public void getResult(JSONObject result)
{
Log.e(TAG, "Json object length = " + result.length());
}
});
.
Method in NetworkManager:
public void getAuthenticationTokens(Object param1, final CustomListener<JSONObject> listener)
{
//String url = prefixURL + "this/request/suffix";
String url = "https://lw.xxx.co.uk/connect/token";
Map<String, Object> jsonParams = new HashMap<>();
jsonParams.put("scope", "openid email phone profile offline_access roles");
jsonParams.put("resource", "window.location.origin");
jsonParams.put("grant_type", "password");
jsonParams.put("username", "support#xxx.com");
jsonParams.put("password", "tempPxxx");
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, new JSONObject(jsonParams),
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response)
{
Log.d(TAG + ": ", "somePostRequest Response : " + response.toString());
if(null != response.toString())
listener.getResult(response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
if (null != error.networkResponse)
{
Log.d(TAG + ": ", "Error Response code: " + error.networkResponse.statusCode);
listener.getResult(null);
}
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = super.getHeaders();
if(params==null)params = new HashMap<>();
params.put("Content-Type","application/x-www-form-urlencoded");
//..add other headers
return params;
}
};
requestQueue.add(request);
}
.
I have tried to add a header to the request using the following post(answer by Subhash), but i'm getting the following exception from adding the headers.
link
Exception:
NetworkDispatcher.run: Unhandled exception java.lang.UnsupportedOperationException
java.lang.UnsupportedOperationException
at java.util.AbstractMap.put(AbstractMap.java:203)
at loneworker.carefreegroup.com.loneworker.NetworkManager$3.getHeaders(NetworkManager.java:100)
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:93)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112)
.
Has anyone any ideas what what the problem is with adding the headers.
The exception is on line 100, here
params.put("Content-Type","application/x-www-form-urlencoded");

Have you tried:
Map<String, String> params = new HashMap<>(super.getHeaders());
I tested it and it worked for me.

Related

Can't access volley answer saved

I am using this method to access a post Volley request
...
responseVolley = "";
getProductFromDataBase("6130127000035");
Log.d("responseVolley", responseVolley);
...
And my getProductFromDataBase is looking like this
public void getProductFromDataBase(final String bareCode) {
mPreferences = getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
this.mEditor = mPreferences.edit();
String url = Constants.URL_SELECT_PRODUCT + "?" + Constants.PARAM_PRODUCT_CODE_BARE + bareCode;
Log.d("URL", url);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("response", response);
responseVolley = response;
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("response", "EROOR");
}
}) {
protected HashMap<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
return (HashMap<String, String>) params;
}
};
RequestHandler.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
}
When I am trying to show responseVolley it doesn't even show something in the Logcat ( I've tried many other solutions like shared preferences ) but nothing worked
Am I doing something wrong ?
Using Volley, you should verify these points :
Check and recheck the url string, if you did not deploy your web app, you should use the IP address you used start your server (http://loaclhost:port_number for example).
If your web app is not deployed on the internet yet, your server and your android app must be in the same network (try to make a hotspot from your PC and connect from your device).
In order to see a result in your response, you should return a string for example from the function that route the asked url, i.e. you should have a function in your web app that you want to send data to a function that catch your url in demande, you should return a string in that function.
You should also verify the error log, use a different tag from the response log tag.
Some times you should give some retry time (in case of weak connection):
stringRequest.setRetryPolicy(new RetryPolicy() {
#Override
public int getCurrentTimeout() {
return 50000;
}
#Override
public int getCurrentRetryCount() {
return 50000;
}
#Override
public void retry(VolleyError error) throws VolleyError {
}
}
PS: In the code you provided you are sending nothing, you should put strings you want to send like this:
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("key", "value");
return params;
}
You should use callback method to do what you expect. With help of an interface, you can achieve what you actually want. If it doesn't work, let me know.
getProductFromDataBase("6130127000035");
OnResult onResult = new OnResult() {
#override
public void result(String responseVolley) {
Log.d("responseVolley", responseVolley);
}
};
Your getProductFromDataBase() method
interface OnResult {
void result(String responseVolley);
}
public void getProductFromDataBase(final String bareCode) {
mPreferences = getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
this.mEditor = mPreferences.edit();
String url = Constants.URL_SELECT_PRODUCT + "?" + Constants.PARAM_PRODUCT_CODE_BARE + bareCode;
Log.d("URL", url);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("response", response);
onResult.result(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("response", "EROOR");
}
}) {
protected HashMap<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
return (HashMap<String, String>) params;
}
};
RequestHandler.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
}

How to set object to VolleyRequest(POST Request) in this type of API?

I have an API link to send post request for creating the order,
I tried to set Request in this way.
I want to send POST request same as request to send in my image (Postman).
I want to create order from cart using cartID and index of the cart, how to send please help me out from this.
Thank You :
public void postCreateOrderByCustomer(ArrayList<CartItem> cartItems) {
String token = sharedPreferences.getString(Constant.token, null);
String endPoint = "https://prettyyou.in/cake/pos/api/customers/create-order?token=" + token;
JSONObject jsonObject = new JSONObject();
JSONArray jsonArray = new JSONArray();
Map<String, String> payloadParams = new HashMap<String, String>();
for (int i = 0; i < cartItems.size(); i++) {
payloadParams.put("cart[" + i
+ "][id]", cartItems.get(i).getId());
}
Log.d(TAG, "postCreateOrderByCustomer: " + jsonObject);
System.out.println("endPointCartGet" + " " + endPoint.toString());
jsonObject = new JSONObject(payloadParams);
Log.d(TAG, "postCreateOrderByCustomer: " + jsonObject);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, endPoint, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, "onResponseCustomer: " + response);
if (response.getBoolean("status")) {
Constant.orderId = response.getString("order_id");
Intent intent = new Intent(DeliveryDetailsActivity.this, PaymentDetailsActivity.class);
startActivity(intent);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "onErrorResponse: " + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return payloadParams;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return super.getHeaders();
}
};
RequestQueue queue = Volley.newRequestQueue(DeliveryDetailsActivity.this);
queue.add(jsonObjectRequest);
}
You can also use Stringrequest and object request or Jsonobject requst

Nested VOLLEY GET Request Method not giving correct results

I have two nested VOLLEY GET request. The first API request gives me id field which I am using to called another Web Service. The problem is the way I am getting the sequence of id from first request its not calling the same sequence for second request which uses id field return by first request.
This is my nested VOLLEY GET request.
private void getData() {
final JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, ApiUrls.RESERVATION, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
final Entry entry = newEntry();
String Id = object.getString("id");
entry.setId(Id);
ID_url = ApiUrls.DETAILS + Id + "/";
JsonObjectRequest foodieInfo = new JsonObjectRequest(Request.Method.GET, ID_url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String firstName = response.getString("firstname");
entry.setName(firstName);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
String auth = "JWT " + myToken;
headers.put("Authorization", auth);
headers.put("Content-Type", "application/json");
return headers;
}
};
AppController.getInstance().addToRequestQueue(foodieInfo);
current.add(entry);
adapter = new ReservationAdapter(current, getActivity().getApplicationContext());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
String auth = "JWT " + myToken;
headers.put("Authorization", auth);
headers.put("Content-Type", "application/json");
return headers;
}
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
int status=response.statusCode;
if(status==200){
}
return super.parseNetworkResponse(response);
}
};
AppController.getInstance().addToRequestQueue(request);
}
The id which I get in first request same it should be only used in the Nested JSON GET request. But it take different id returned by first request and called the another request from using that sequence. How to resolve this ?

BasicNetwork.performRequest: Unexpected response code 400 for android on Load

Having trouble on VolleyRequest getting always error response when loading it onCreate. I want to do is when the fragment loads. but when I try it, the Logcat gives me an error 400. on this Java class, i have another function that has sending data to API. I just copied my code :). here is the code that getting a error response.
String url = "MYLINK.com";
try {
RequestQueue queue = Volley.newRequestQueue(getActivity());
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(getContext(), "Successful send pending data", Toast.LENGTH_SHORT).show();
String qu = ("update tickets set is_send = '1' where ticket_tick_no = '" + ticket_tick_no_delayed + "'");
sqldb.execSQL(qu);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), "Error Response here", Toast.LENGTH_SHORT).show();
Log.e("------", String.valueOf(error.networkResponse.statusCode));
}
}
) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("control_no", trip_no_delayed);
params.put("trip_no", ticket_control_no_delayed);
params.put("ticket_no", ticket_tick_no_delayed);
params.put("ticket_datetime", ticket_datetime_delayed);
params.put("ticket_kmfrom", ticket_kmfrom_delayed);
params.put("ticket_kmto", ticket_kmto_delayed);
params.put("ticket_placefrom", ticket_placefrom_delayed);
params.put("ticket_placeto", ticket_placeto_delayed);
params.put("amount", ticket_amount_delayed);
params.put("discount", ticket_discount_delayed);
params.put("trans_type", transaction_type_delayed);
params.put("passenger_type", passenger_type_delayed);
params.put("lat", ticket_lat_delayed);
params.put("long", ticket_long_delayed);
params.put("device_serial", device_serial_delayed);
return params;
}
};
queue.add(postRequest);
} catch (Exception e) {
e.printStackTrace();
}

Volley onResponse method not working

I'm using Volley to send Post request.I'm trying to send jsonObject to server.This is my source
public void sendDicieIDToServer(JSONObject jsonObject)
{
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
Log.e("response is", "Response " + jsonObject.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
NetworkResponse errorRes = volleyError.networkResponse;
String stringData = "";
if(errorRes != null && errorRes.data != null){
try {
stringData = new String(errorRes.data,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Log.e("Error",stringData);
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Authorization",uhfScannerModel.getToken());
params.put("Content-Type", "application/json");
return params;
}
};
HandsetApplication.getInstance().addToRequestQueue(jsonObjectRequest);
}
I successfully created JsonObject and when I run my app and try to debug it, onErrorResponse method has called and stringData String contains real json result. I don't know what is a wrong and why onErrorResponse method calling.
User this link for Volley
Here i made volley reusability where you can apiCall easy way..
https://github.com/sikander-kh/Volley-Reusability

Categories

Resources