简体   繁体   中英

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

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];
}

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM