POST Request Json file passing String and wait for the response Volley
Asked Answered
S

1

0

I am new to Android and Volley, and I need your help. I need to post a String, have a json to response to it and, if it doesn't raise a bad request, start a new intent with some values coming from my request.

This is a simple schema of what I want to do: Press Login button -> star request -> check if it is ok -> start a new intent with response values.

I have seen that Volley uses asynchronous method to query. Here's my code:

boolean temp=false;
     login.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                boolean temp=false;
                     if (!id.getText().toString().isEmpty() && !pw.getText().toString().isEmpty()) {
                        temp = verifyCredentials(v.getContext()); //Doesn't work because Volley is asynchronous.

                     if(temp==true)
                     {
                         Intent intentMain = new Intent(v.getContext(), MainActivity.class);//MainActivity.class);
                         intentMain.putExtra("username", id.getText().toString());
                         startActivityForResult(intentMain, 0);
                     }
                } else {//strighe vuote
                    //toast
                    Toast.makeText(v.getContext(), "Compila i campi", Toast.LENGTH_SHORT).show();
                }


            }
        });

public boolean verifyCredentials(Context context) {
        final boolean[] tempToReturn = {false};
        mTextView = (TextView) findViewById(R.id.textView2);
        RequestQueue queue = Volley.newRequestQueue(context);

        StringRequest stringRequest = new StringRequest(Request.Method.POST, apiURL,
                new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                mTextView.setText("Response is:" + response.substring(500));
                tempToReturn[0] =true;
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                String json = null;
                NetworkResponse response = error.networkResponse;
                if(response != null && response.data != null){
                    switch(response.statusCode){
                        case 400:
                            json = new String(response.data);
                            json = trimMessage(json, "message");
                            if(json != null) displayMessage(json);
                            break;
                    }
                    //Additional cases
                }
                mTextView.setText("Error bad request");
            }
            public String trimMessage(String json, String key){
                String trimmedString = null;

                try{
                    JSONObject obj = new JSONObject(json);
                    trimmedString = obj.getString(key);
                } catch(JSONException e){
                    e.printStackTrace();
                    return null;
                }

                return trimmedString;
            }

            //Somewhere that has access to a context
            public void displayMessage(String toastString){
                mTextView.setText("Response is:" +toastString);
            }
        }){
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                AuthenticationUserName = id.getText().toString();
                AuthenticationPassword = pw.getText().toString();
                params.put("grant_type", Authenticationgrant_type);
                params.put("username", AuthenticationUserName);
                params.put("password", AuthenticationPassword);
                return params;
            }
        };
        queue.add(stringRequest);
        return  tempToReturn[0];
    }

I am using Volley because my gradle's is the 23 and my APi level too so I can't use the apache package.

EDIT: NEW CODE:

 public void onClick(View v) {
                boolean temp = true;
                if (!id.getText().toString().isEmpty() && !pw.getText().toString().isEmpty()) {

                    myContext = v.getContext();
                    VolleyResponseListener listener = new VolleyResponseListener() {
                        @Override
                        public void onError(VolleyError error) {
                            String json = null;
                            NetworkResponse response = error.networkResponse;
                            if(response != null && response.data != null){
                                switch(response.statusCode){
                                    case 400:
                                        json = new String(response.data);
                                        json = trimMessage(json, "message");
                                        if(json != null) displayMessage(json);
                                        break;
                                }
                                //Additional cases
                            }
                            mTextView.setText("Error bad request");
                        }
                        @Override
                        public void onResponse(JSONObject  response) {
                            try {
                                fullName = response.getString("fullName");
                                token= response.getString("access_token");
                                expirationDate=response.getString(".expires");
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            mTextView.setText("Response is:" + fullName+token+expirationDate);
                            Intent intentMain = new Intent(myContext, MainActivity.class);//MainActivity.class);
                            intentMain.putExtra("username", id.getText().toString());
                            startActivityForResult(intentMain, 0);
                        }

                        public String trimMessage(String json, String key){
                            String trimmedString = null;
                            try{
                                JSONObject obj = new JSONObject(json);
                                trimmedString = obj.getString(key);
                            } catch(JSONException e){
                                e.printStackTrace();
                                return null;
                            }

                            return trimmedString;
                        }

                        //Somewhere that has access to a context
                        public void displayMessage(String toastString){
                            //Toast.makeText(MainActivity.this, toastString, Toast.LENGTH_LONG).show();
                            mTextView.setText("Response is:" +toastString);
                        }
                    };

                    verifyCredentials(myContext,listener);

and I have create this interface:

public interface VolleyResponseListener {
    void onError(VolleyError error);
    void onResponse(JSONObject  response);
}

And here is the new code of my verifycredential:

   public boolean verifyCredentials(Context context,final VolleyResponseListener listener) {
        final boolean[] tempToReturn = {false};
        mTextView = (TextView) findViewById(R.id.textView2);
        Map<String,String> params = new HashMap<String, String>();
        AuthenticationUserName = id.getText().toString();
        AuthenticationPassword = pw.getText().toString();
                    //key value
        params.put("grant_type", Authenticationgrant_type);
        params.put("username",  AuthenticationUserName);
    params.put("password", AuthenticationPassword);

    RequestQueue queue = Volley.newRequestQueue(context);

    SimpleRequest jsObjRequest  = new SimpleRequest(Request.Method.POST, apiURL,
            params,new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject  response) {
                    listener.onResponse(response);
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            listener.onError(error);
        }
        }
    });
    queue.add(jsObjRequest);
    return  tempToReturn[0];
}
Swim answered 17/9, 2015 at 9:38 Comment(4)
just show a progress dialog before, and when request finish volley will auto call callback response or errorHedi
@MamataGelanee the url is my personalApi, I don't wont to share it.... sorrySwim
@Hedi can you post me some example code?thank youSwim
look on @BNK answer below, it should help you :)Hedi
S
1

I have answered some questions that look like your issue, such as:

Android: How to return async JSONObject from method using Volley?

You should not wait for that boolean return value. Instead, you can try the following way (of course, you can replace JSONArray request by JSONObject or String request):

VolleyResponseListener listener = new VolleyResponseListener() {
            @Override
            public void onError(String message) {
                // do something...
            }

            @Override
            public void onResponse(Object response) {
                // do something...
            }
        };

makeJsonArrayRequest(context, Request.Method.POST, url, requestBody, listener);

Body of makeJsonArrayRequest can be as the following:

    public void makeJsonArrayRequest(Context context, int method, String url, String requestBody, final VolleyResponseListener listener) {
        JSONObject jsonRequest = null;        
        try {
            ...
            if (requestBody != null) {
                jsonRequest = new JSONObject(requestBody);
            }
            ...
        } catch (JSONException e) {
            e.printStackTrace();
        }

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(method, url, jsonRequest, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray jsonArray) {
                listener.onResponse(jsonArray);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onError(error.toString());
            }
        });

        // Access the RequestQueue through singleton class.
        MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
    }

VolleyResponseListener interface as the following:

public interface VolleyResponseListener {
    void onError(String message);

    void onResponse(Object response);
}

For your comments below:

first of all is: the "order" of the method, for example in my case, After pressing button, which method I have to call?

Let's assume we are inside onCreate: You can create VolleyResponseListener listener first, then call verifyCredentials(..., listener); when pressing the button.

And where I can call the intent?

This will be called inside onResponse of the above VolleyResponseListener listener (of course, inside that you can check more conditions depend on your requirements)

Second: I have to send a String but I want a jsonArrayRespond, there is a method to do this? Or it work only with 2 kind of parameter such string request/string sent and json request/json sent?

According to Google's training documentation:

  • StringRequest: Specify a URL and receive a raw string in response.
  • ImageRequest: Specify a URL and receive an image in response.
  • JsonObjectRequest and JsonArrayRequest (both subclasses of JsonRequest): Specify a URL and get a JSON object or array (respectively) in response.

And of course you can implement your own custom request types, for types that don't have out-of-the-box Volley support. Take a look at Implementing a Custom Request.

Hope this helps!

Simplify answered 17/9, 2015 at 9:47 Comment(14)
Thank you for your answer. I don't understand many "stupid" things, first of all is: the "order" of the method, for example in my case, After pressing button, which method I have to call?And where I can call the intent? Second: I have to send a String but I want a jsonArrayRespond, there is a method to do this? Or it work only with 2 kind of parameter such string request/string sent and json request/json sent? Thank youSwim
thank you for the reply;I tried to do what you have wrote but It doesn't work....... The application crash after I pressed the button, with debugging's mode I have saw that the problem is after It executes the function verycredential, because It does nothing else. I have modified the code. What I have to change/do now? thank youSwim
java.lang.NullPointerException: at myproject.LoginActivity$1$1.onError(LoginActivity.java:112)->mTextView.setText("Error bad request"); at myproject.LoginActivity$3.onErrorResponse(LoginActivity.java:220)-> listener.onError(error); at com.android.volley.Request.deliverError(Request.java:563) at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:101) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:103) ....Swim
Check if your mTextView is null or notSimplify
Normally, mTextView inititialization at the beginning of onCreate, like this protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.textView);Simplify
It is inizialied.... =( but one time the error is on the mTextView.setText("‌​Error bad request"); and other time it is on the mTextView.setText("Response is:" + fullName+token+expirationDate);Swim
NullPointerException perhaps something null, I think you should check more when debug. Moreover, you should post the screenshot having mTextView value when debugging so that I can check moreSimplify
I have saw on my degub that mtextView is null.. but I really don't understand, because I have set them on oncreate and onstart too. Now I try to remove them and look if it worksSwim
Have you declared textView2 in the layout XML file?Simplify
Yes... It is declared in my layout_login and It exist.. I really don't understandSwim
Post your layout file content and onCreate's content pls. If textView init already inside onCreate, no need onStart. Another way, put the pointer at R.id.textView2 inside verifyCredentials, then press Ctrl-B to check if it jumps to the correct layout file or notSimplify
I have put mTextView = (TextView) findViewById(R.id.textView2); before mTextView.setText and now it works. Very thank you for your help! =)Swim
Glad my answer could help!Simplify
You can read my new answer here to see another way (order) of using listener interface.Simplify

© 2022 - 2024 — McMap. All rights reserved.