http - ternario - voley android publicando cuerpo binario
que es ser binario (2)
Escenario: cargue datos binarios en el cuerpo de una publicación, maneje un cuerpo de respuesta que contenga JSON.
¿Cómo hacer lo siguiente con Volley?
curl -X POST -H "X-Application-Id: 3KxPB" -H "X-REST-API-Key: jkuI9" -H "Content-Type: audio/3gp" --data-binary ''@test.3gp'' https://host/1/files/audio
OMI: hay una brecha en Volley que maneja tipos de cuerpo POST binarios que apache maneja httpclient en subclases de abstracthttpentity . Si los datos binarios almacenados en el búfer generados en el teléfono por cámara, micrófono u otros sensores de salida binarios necesitan un mecanismo para ser envueltos y escritos en el cuerpo de un POST, ¿cómo hacerlo en voley?
Miré PoolingByteArrayOutputStream y me gustaría hacer algo como llenar el búfer y obtener el PBAOutStrm, escribir en PBAOutStrm desde el búfer y luego pasar OutStrm a InputStream y luego envolverlo en el cuerpo de una solicitud POST como algo así como ByteArrayEntity. No puedo ver cómo hacer eso en volea.
Para enviar datos binarios puede hacer algo como lo que hice en esta respuesta Cómo enviar un POST "multipart / form-data" en Android con Volley .
Pude resolver esto usando un Volley GsonRequest:
la clase pública MainActivity extiende AppCompatActivity {
String url = "https://arcane-anchorage-34204.herokuapp.com/handleCode";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JSONObject jsonBody = null;
try {
jsonBody = new JSONObject ("{/"code/":/"NZ4UBUB/"}");
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error e = " + e, Toast.LENGTH_SHORT).show();
}
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
RequestQueue queue = Volley.newRequestQueue(this);
GsonRequest<Routine[]> gsonRequest = new GsonRequest<Routine[]>(Request.Method.POST, url, Routine[].class, headers, new Response.Listener<Routine[]>() {
@Override
public void onResponse(Routine[] routineData) {
TextView serverData = (TextView)findViewById(R.id.serverData);
String complete = "";
String repeat = "";
String hold = "";
String perform = "";
String txtData = "";
for (int i = 0; i < routineData.length; i++) {
complete = (routineData[i].instructions.complete != null) ? "Complete: " + routineData[i].instructions.complete : "";
repeat = (routineData[i].instructions.repeat != null) ? "Repeat: " + routineData[i].instructions.repeat : "";
hold = (routineData[i].instructions.hold != null) ? "Hold: " + routineData[i].instructions.hold : "";
perform = (routineData[i].instructions.perform != null) ? "Perform: " + routineData[i].instructions.perform : "";
txtData += "DESCRIPTION: " + routineData[i].description[0] + ": " + routineData[i].description[1] + ", " + complete + ", " + repeat + ", " + hold + ", " + perform + " ";
}
serverData.setText("Response: " + txtData);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
TextView serverData = (TextView)findViewById(R.id.serverData);
serverData.setText("Response: " + volleyError.toString());
}
}, jsonBody);
queue.add(gsonRequest);
}
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Response.Listener<T> listener;
private JSONObject parameters = null;
/**
* Make a GET request and return a parsed object from JSON.
*
* @param url URL of the request to make
* @param clazz Relevant class object, for Gson''s reflection
* @param headers Map of request headers
*/
public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers,
Response.Listener<T> listener, Response.ErrorListener errorListener, JSONObject parameters) {
this(method, url, clazz, headers, listener, errorListener);
this.parameters = parameters;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
public String getBodyContentType() {
return "application/json";
}
@Override
public byte[] getBody() throws AuthFailureError {
try {
return parameters.toString().getBytes(getParamsEncoding());
} catch (UnsupportedEncodingException e) {
}
return null;
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data, HttpHeaderParser.parseCharset(response.headers));
Log.i("RESPONSE", json);
return Response.success(
gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
}