Android 如何从凌空库发送字节数据

Android 如何从凌空库发送字节数据,android,performance,android-layout,android-fragments,android-volley,Android,Performance,Android Layout,Android Fragments,Android Volley,我有字节数组中的数据,我需要从Volley库将其发送到服务。这是我尝试过的,但在getBody()方法上没有达到,并在读取body之前返回响应 StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() { @Override public void onResponse(

我有字节数组中的数据,我需要从
Volley库
将其发送到服务。这是我尝试过的,但在
getBody()
方法上没有达到,并在读取body之前返回响应

StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d("Success", response.toString());

            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        Log.d("Error", error.toString());
    }
}){

    @Override
    public byte[] getBody() throws AuthFailureError {
        return bytesObject;
    }

        @Override
        public String getBodyContentType() {
            return "application/json; charset=utf-8";
        }

};

RequestQueue requestQueue = Volley.newRequestQueue(AnalyticsApplication.getAppContext());
requestQueue.add(stringRequest);
StringRequest StringRequest=新的StringRequest(Request.Method.GET,URL,
新的Response.Listener(){
@凌驾
公共void onResponse(字符串响应){
Log.d(“Success”,response.toString());
}
},new Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
Log.d(“Error”,Error.toString());
}
}){
@凌驾
公共字节[]getBody()抛出AuthFailureError{
返回bytesObject;
}
@凌驾
公共字符串getBodyContentType(){
返回“application/json;charset=utf-8”;
}
};
RequestQueue RequestQueue=Volley.newRequestQueue(AnalyticsApplication.getAppContext());
添加(stringRequest);
可能我遗漏了什么,请指导我如何从
Volley
库发送
字节数组。

试试这个

public void actionCallWebServiceWithFiles(String url, final HashMap<String, String> params, final Map<String, VolleyMultipartRequest.DataPart> file) {

        VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, url, new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {
                String resultResponse = new String(response.data);
                try {
                    JSONObject result = new JSONObject(resultResponse);
                    /*String status = result.getString("status");
                    String message = result.getString("message");

                    if (status.equals(Constants.SUCCESS)) {
                        // tell everybody you have succed upload image and post strings
                        Log.i("Messsage", message);
                    } else {
                        Log.i("Unexpected", message);
                    }*/
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                NetworkResponse networkResponse = error.networkResponse;
                String errorMessage = "Unknown error";
                if (networkResponse == null) {
                    if (error.getClass().equals(TimeoutError.class)) {
                        errorMessage = "Request timeout";
                    } else if (error.getClass().equals(NoConnectionError.class)) {
                        errorMessage = "Failed to connect server";
                    }
                } else {
                    String result = new String(networkResponse.data);
                    try {
                        JSONObject response = new JSONObject(result);
                        String status = response.getString("status");
                        String message = response.getString("message");

                        Log.e("Error Status", status);
                        Log.e("Error Message", message);

                        if (networkResponse.statusCode == 404) {
                            errorMessage = "Resource not found";
                        } else if (networkResponse.statusCode == 401) {
                            errorMessage = message + " Please login again";
                        } else if (networkResponse.statusCode == 400) {
                            errorMessage = message + " Check your inputs";
                        } else if (networkResponse.statusCode == 500) {
                            errorMessage = message + " Something is getting wrong";
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                Log.i("Error", errorMessage);
                error.printStackTrace();
            }
        }, onProgressUpdate) {
            @Override
            protected Map<String, String> getParams() {

                return params;
            }


            @Override
            protected Map<String, DataPart> getByteData() {
                Map<String, DataPart> params = new HashMap<>();
                // file name could found file base or direct access from real path
                // for now just get bitmap data from ImageView
//                params.put("doc_file", new DataPart("file_avatar.jpg", Common.getFileDataFromDrawable(context, context.getDrawable(R.drawable.ic_app_icon)), "image/png"));
//                params.put("upload_file", new DataPart("screens.zip",file,"application/zip"));


                return file;
            }
        };

        MyApplication.getInstance().addToRequestQueue(multipartRequest);
    }
public void actionCallWebServiceWithFiles(字符串url、最终HashMap参数、最终映射文件){
VolleyMultipartRequest multipartRequest=新的VolleyMultipartRequest(Request.Method.POST,url,new Response.Listener()){
@凌驾
public void onResponse(NetworkResponse){
String resultResponse=新字符串(response.data);
试一试{
JSONObject结果=新JSONObject(resultResponse);
/*字符串状态=result.getString(“状态”);
字符串消息=result.getString(“消息”);
if(status.equals(Constants.SUCCESS)){
//告诉大家你成功上传了图片和帖子字符串
Log.i(“消息”,消息);
}否则{
Log.i(“意外”,消息);
}*/
}捕获(JSONException e){
e、 printStackTrace();
}
}
},new Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
NetworkResponse NetworkResponse=error.NetworkResponse;
String errorMessage=“未知错误”;
if(networkResponse==null){
if(error.getClass().equals(TimeoutError.class)){
errorMessage=“请求超时”;
}else if(error.getClass().equals(NoConnectionError.class)){
errorMessage=“无法连接服务器”;
}
}否则{
字符串结果=新字符串(networkResponse.data);
试一试{
JSONObject响应=新JSONObject(结果);
字符串状态=response.getString(“状态”);
字符串消息=response.getString(“消息”);
Log.e(“错误状态”,状态);
Log.e(“错误消息”,消息);
if(networkResponse.statusCode==404){
errorMessage=“未找到资源”;
}else if(networkResponse.statusCode==401){
errorMessage=消息+“请再次登录”;
}else if(networkResponse.statusCode==400){
errorMessage=消息+“检查您的输入”;
}else if(networkResponse.statusCode==500){
errorMessage=消息+“出现了问题”;
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
Log.i(“错误”,errorMessage);
错误。printStackTrace();
}
},onProgressUpdate){
@凌驾
受保护的映射getParams(){
返回参数;
}
@凌驾
受保护的映射getByteData(){
Map params=新的HashMap();
//文件名无法从实际路径找到文件基或直接访问
//现在只需从ImageView获取位图数据
//参数put(“doc_file”,新数据部分(“file_avatar.jpg”,Common.getFileDataFromDrawable(context,context.getDrawable(R.drawable.ic_app_icon)),“image/png”);
//参数put(“upload_file”,new DataPart(“screens.zip”,file,“application/zip”);
返回文件;
}
};
MyApplication.getInstance().addToRequestQueue(multipartRequest);
}
VolleyMultiPartRequest.java

public class VolleyMultipartRequest extends Request<NetworkResponse> {
    private final String twoHyphens = "--";
    private final String lineEnd = "\r\n";
    private final String boundary = "apiclient-" + System.currentTimeMillis();

    private Response.Listener<NetworkResponse> mListener;
    private Response.ErrorListener mErrorListener;
    private Map<String, String> mHeaders;
    private OnProgressUpdate onProgressUpdate;
    private int transferred = 0;

    /**
     * Default constructor with predefined header and post method.
     *
     * @param url           request destination
     * @param headers       predefined custom header
     * @param listener      on success achieved 200 code from request
     * @param errorListener on error http or library timeout
     */
    public VolleyMultipartRequest(String url, Map<String, String> headers,
                                  Response.Listener<NetworkResponse> listener,
                                  Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.mHeaders = headers;
    }

    /**
     * Constructor with option method and default header configuration.
     *
     * @param method        method for now accept POST and GET only
     * @param url           request destination
     * @param listener      on success event handler
     * @param errorListener on error event handler
     */
    public VolleyMultipartRequest(int method, String url,
                                  Response.Listener<NetworkResponse> listener,
                                  Response.ErrorListener errorListener, OnProgressUpdate onProgressUpdate) {
        super(method, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.onProgressUpdate = onProgressUpdate;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return (mHeaders != null) ? mHeaders : super.getHeaders();
    }

    @Override
    public String getBodyContentType() {
        return "multipart/form-data;boundary=" + boundary;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);

        try {
            // populate text payload
            Map<String, String> params = getParams();
            if (params != null && params.size() > 0) {
                textParse(dos, params, getParamsEncoding());
            }

            // populate data byte payload
            Map<String, DataPart> data = getByteData();
            if (data != null && data.size() > 0) {
                dataParse(dos, data);
            }

            // close multipart form data after text and file data
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Custom method handle data payload.
     *
     * @return Map data part label with data byte
     * @throws AuthFailureError
     */
    protected Map<String, DataPart> getByteData() throws AuthFailureError {
        return null;
    }

    @Override
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
        try {
            return Response.success(
                    response,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (Exception e) {
            return Response.error(new ParseError(e));
        }
    }

    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

    @Override
    public void deliverError(VolleyError error) {
        mErrorListener.onErrorResponse(error);
    }

    /**
     * Parse string map into data output stream by key and value.
     *
     * @param dataOutputStream data output stream handle string parsing
     * @param params           string inputs collection
     * @param encoding         encode the inputs, default UTF-8
     * @throws IOException
     */
    private void textParse(DataOutputStream dataOutputStream, Map<String, String> params, String encoding) throws IOException {
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                buildTextPart(dataOutputStream, entry.getKey(), entry.getValue());
            }
        } catch (UnsupportedEncodingException uee) {
            throw new RuntimeException("Encoding not supported: " + encoding, uee);
        }
    }

    /**
     * Parse data into data output stream.
     *
     * @param dataOutputStream data output stream handle file attachment
     * @param data             loop through data
     * @throws IOException
     */
    private void dataParse(DataOutputStream dataOutputStream, Map<String, DataPart> data) throws IOException {
        for (Map.Entry<String, DataPart> entry : data.entrySet()) {
            buildDataPart(dataOutputStream, entry.getValue(), entry.getKey());
        }
    }

    /**
     * Write string data into header and data output stream.
     *
     * @param dataOutputStream data output stream handle string parsing
     * @param parameterName    name of input
     * @param parameterValue   value of input
     * @throws IOException
     */
    private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException {
        dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd);
        //dataOutputStream.writeBytes("Content-Type: text/plain; charset=UTF-8" + lineEnd);
        dataOutputStream.writeBytes(lineEnd);
        dataOutputStream.writeBytes(parameterValue + lineEnd);
    }

    /**
     * Write data file into header and data output stream.
     *
     * @param dataOutputStream data output stream handle data parsing
     * @param dataFile         data byte as DataPart from collection
     * @param inputName        name of data input
     * @throws IOException
     */
    private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException {
        dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +
                inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd);
        if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) {
            dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd);
        }
        dataOutputStream.writeBytes(lineEnd);

        ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent());
        int bytesAvailable = fileInputStream.available();

        int maxBufferSize = 1024 * 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        long total = 0;

        while (bytesRead > 0) {
            dataOutputStream.write(buffer, 0, bufferSize);
            total = dataOutputStream.size();
            transferred = (int) (total * 100 / dataFile.getContent().length) ;
            onProgressUpdate.onTransferred(transferred);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        dataOutputStream.writeBytes(lineEnd);

    }

    /**
     * Simple data container use for passing byte file
     */
    public static class DataPart {
        private String fileName;
        private byte[] content;
        private String type;

        /**
         * Default data part
         */
        public DataPart() {
        }

        /**
         * Constructor with data.
         *
         * @param name label of data
         * @param data byte data
         */
        public DataPart(String name, byte[] data) {
            fileName = name;
            content = data;
        }

        /**
         * Constructor with mime data type.
         *
         * @param name     label of data
         * @param data     byte data
         * @param mimeType mime data like "image/jpeg"
         */
        public DataPart(String name, byte[] data, String mimeType) {
            fileName = name;
            content = data;
            type = mimeType;
        }

        /**
         * Getter file name.
         *
         * @return file name
         */
        public String getFileName() {
            return fileName;
        }

        /**
         * Setter file name.
         *
         * @param fileName string file name
         */
        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        /**
         * Getter content.
         *
         * @return byte file data
         */
        public byte[] getContent() {
            return content;
        }

        /**
         * Setter content.
         *
         * @param content byte file data
         */
        public void setContent(byte[] content) {
            this.content = content;
        }

        /**
         * Getter mime type.
         *
         * @return mime type
         */
        public String getType() {
            return type;
        }

        /**
         * Setter mime type.
         *
         * @param type mime type
         */
        public void setType(String type) {
            this.type = type;
        }
    }
}
public类截击multipartrequest扩展请求{
专用最终字符串双连字符=“--”;
专用最终字符串lineEnd=“\r\n”;
private final String boundary=“apiclient-”+System.currentTimeMillis();
私人回应。倾听者;
private Response.ErrorListener-mErrorListener;
私人地图管理员;
私有OnProgressUpdate-OnProgressUpdate;
私有整数=0;
/**
*具有预定义标头和post方法的默认构造函数。
*
*@param url请求目的地
*@param头预定义自定义头
*@param listener成功从请求中获得200个代码
*@param errorListener出现错误http或库超时
*/
公共截击多部分请求(字符串url、映射头、,
回应,听众,
Response.ErrorListener(错误监听器){
super(Method.POST、url、errorListener);
this.mListener=侦听器;
this.mErrorListener=err