Android Volley: Как я могу получить ответ от сервера, каким бы он ни был? - PullRequest
0 голосов
/ 27 июня 2019

Я начинаю с разработки Android с Kotlin. Я пытаюсь использовать Volley для чтения API и обновления элементов GUI. Я заставил его работать с StringObjectRequests, использующим метод http GET, теперь моя проблема в том, когда я хочу использовать метод POST.

Вот моя основная функция:

fun volley() {
    val queue = Volley.newRequestQueue(this)
    val url   = "http://x.x.x.x/api.php"
    val json = JSONObject()

    json.put("ciudad", "Londres")
    json.put("nombre", "Luis")

    val stringRequest = JsonObjectRequest(Request.Method.POST,
      url, json,
      Response.Listener<JSONObject> { response ->
        taContenido.setText(response.toString())
      },
      Response.ErrorListener {
        taContenido.setText("No Funcionó")
      })

    queue.add(stringRequest)
  }

Код в «API» довольно прост ...

<?php
$j = array('ciudad' => $_POST["ciudad"],
   'nombre' => $_POST["nombre"]);

echo json_encode($j);

Моя проблема в том, что когда я запускаю функцию, она проходит через часть ErrorListener и показывает «Нет функции». Я понятия не имею, почему. Конечно, если я попробую свой API с Почтальоном, он выдаст ожидаемое {"ciudad":"Londres","nombre":"Luis"}

Итак, как я могу увидеть, что сервер возвращает, каким бы он ни был, при использовании JsonObjectRequest?

Если я изменю Запрос на StringRequest, конечно, я смогу увидеть ошибки PHP (поскольку не будет определено $ _POST []: |

1 Ответ

0 голосов
/ 27 июня 2019

Я пишу на Java.Пожалуйста, конвертируйте в Kotlin.Создайте синглтон-класс вот так -

public class VolleyManager {
    private static VolleyManager ourInstance;
    private final Context mContext;
    private final ImageLoader mImageLoader;
    private RequestQueue mRequestQueue;

    private VolleyManager(final Context pContext) {
        mContext = pContext;
        mImageLoader = new ImageLoader(getRequestQueue(), new ImageLoader.ImageCache() {
            private LruCache<String, Bitmap> mCache = new LruCache<>(20);

            @Override
            public Bitmap getBitmap(final String url) {
                return mCache.get(url);
            }

            @Override
            public void putBitmap(final String url, final Bitmap bitmap) {
                mCache.put(url, bitmap);
            }
        });
    }

    private RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(mContext);
        }
        return mRequestQueue;
    }

    public static synchronized VolleyManager getInstance(final Context pContext) {
        if (ourInstance == null) {
            ourInstance = new VolleyManager(pContext);
        }
        return ourInstance;
    }

    public void addRequest(final Request pRequest) {
        getRequestQueue().add(pRequest);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(tag);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

И делайте запросы вот так -

public class AccessTokenRequest extends StringRequest {
    Map<String,String> mParms = new ArrayMap<>();
    Map<String,String> mHeader = new ArrayMap<>();

    public AccessTokenRequest(String code, Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(Method.POST, WebConfig.END_POINT + WebConfig.ACCESS_TOKEN_METHOD, listener, errorListener);
        mHeader.put("Authorization","Basic MjJEUT");
        mHeader.put("Content-Type","application/x-www-form-urlencoded");
        mParms.put("clientId","63FGDF");
        mParms.put("grant_type","authorization_code");
        mParms.put("redirect_uri","https://example.com/thu");
        mParms.put("code",code);
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return mHeader;
    }

    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        return mParms;
    }
}

И в действии звоните вот так -

private void requestAccessToken(String code) {

        final ProgressDialog pDialog = new ProgressDialog(this);
        pDialog.setMessage("Loading...");
        pDialog.setCancelable(false);
        pDialog.setCanceledOnTouchOutside(false);
        pDialog.show();

        VolleyManager.getInstance(AuthorizationActivity.this).addRequest(new AccessTokenRequest(code, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject responseJsonObj = new JSONObject(response);
                    String accessToken = responseJsonObj.getString("access_token");
                    long expiresIn = responseJsonObj.getInt("expires_in") + (System.currentTimeMillis() / 1000);
                    String refreshToken = responseJsonObj.getString("refresh_token");
                    List<Scope> scopes = parseScopes(responseJsonObj.getString("scope"));
                    String tokenType = responseJsonObj.getString("token_type");
                    String userId = responseJsonObj.getString("user_id");



                } catch (JSONException e) {
                    e.printStackTrace();
                } finally {
                    pDialog.dismiss();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                pDialog.dismiss();
                Toast.makeText(AuthorizationActivity.this, "Please check internet connection", Toast.LENGTH_LONG).show();
            }
        }));
    }
...