gpt4 book ai didi

android - 如何在 Android Volley 库中使用 MultiPart 上传图像文件数组

转载 作者:行者123 更新时间:2023-11-29 19:03:34 25 4
gpt4 key购买 nike

我只是 Android 应用程序开发的初学者。

我想使用 Android Volley 库上传图像文件。

我使用了在某个博客某处找到的这个辅助类。:

    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;

SharedPreferencesManager sharedPreferencesManager =null;

public VolleyMultiPartRequest(int method, String url,
Response.Listener<NetworkResponse> listener,
Response.ErrorListener errorListener, Context context) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
this.sharedPreferencesManager = new SharedPreferencesManager(context);
}


@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer " + sharedPreferencesManager.retreiveString(AppText.ACCESS_TOKEN));
headers.put("Content-Type", "multipart/form-data");
return headers;
}
@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;
}


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


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


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());
}
}


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(lineEnd);
dataOutputStream.writeBytes(parameterValue + lineEnd);
}

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);

while (bytesRead > 0) {
dataOutputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}

dataOutputStream.writeBytes(lineEnd);
}

public class DataPart {
private String fileName;
private byte[] content;
private String type;

public DataPart() {
}

public DataPart(String name, byte[] data) {
fileName = name;
content = data;
}

String getFileName() {
return fileName;
}

byte[] getContent() {
return content;
}

String getType() {
return type;
}

}
}

然后这样调用这个助手:

 VolleyMultiPartRequest volleyMultipartRequest = new VolleyMultiPartRequest(Request.Method.POST, Api.UPLOAD_FILE,
new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
try {
JSONObject obj = new JSONObject(new String(response.data));
Toast.makeText(context, obj.getString("message"), Toast.LENGTH_SHORT).show();
successCallBack.onSuccess(obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, error.getMessage(), Toast.LENGTH_SHORT).show();
try {
errorCallBack.onError(new JSONObject(""));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, context) {

/*
* If you want to add more parameters with the image
* you can do it here
* here we have only one parameter with the image
* which is tags
* */
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("file_for", "post");
params.put("file_type", "image");
return params;
}

/*
* Here we are passing image by renaming it with a unique name
* */
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
long imagename = System.currentTimeMillis();
params.put("images[]", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap)));
return params;
}


};

我收到服务器错误作为响应。

我尝试了不同的教程,但没有找到确切的方法和简单的解决方案。

在postman中,headers和params是这样的,里面有一个图片数组,可以看附件中的照片(8张)。我想使用 volley 库进行完全相同的 API 调用。

enter image description here enter image description here

最佳答案

试试这段代码:

我有类似的问题,我用这个解决了

使用 multipart 上传数组中的多个文件

  1. 添加依赖

    compile 'org.apache.httpcomponents:httpcore:4.2.4'
    compile 'org.apache.httpcomponents:httpmime:4.2'
    compile 'com.mcxiaoke.volley:library:1.0.19'

2.在gradle中添加

    defaultConfig {
useLibrary 'org.apache.http.legacy'

}
  1. 辅助类 AndroidMultiPartEntity.java

    public class AndroidMultiPartEntity extends MultipartEntity

    {

    private final ProgressListener listener;

    public AndroidMultiPartEntity(final ProgressListener listener) {
    super();
    this.listener = listener;
    }

    public AndroidMultiPartEntity(final HttpMultipartMode mode, final ProgressListener listener) {
    super(mode);
    this.listener = listener;
    }

    public AndroidMultiPartEntity(HttpMultipartMode mode, final String boundary,
    final Charset charset, final ProgressListener listener) {
    super(mode, boundary, charset);
    this.listener = listener;
    }

    @Override
    public void writeTo(final OutputStream outstream) throws IOException {
    super.writeTo(new CountingOutputStream(outstream, this.listener));
    }

    public interface ProgressListener {
    void transferred(long num);
    }

    public static class CountingOutputStream extends FilterOutputStream {

    private final ProgressListener listener;
    private long transferred;

    public CountingOutputStream(final OutputStream out,
    final ProgressListener listener) {
    super(out);
    this.listener = listener;
    this.transferred = 0;
    }

    public void write(byte[] b, int off, int len) throws IOException {
    out.write(b, off, len);
    this.transferred += len;
    this.listener.transferred(this.transferred);
    }

    public void write(int b) throws IOException {
    out.write(b);
    this.transferred++;
    this.listener.transferred(this.transferred);
    }
    }
    }
  2. API调用方法

    private class registerCall extends AsyncTask<Void, Integer, String> {
    @Override
    protected void onPreExecute() {
    super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
    }

    @Override
    protected String doInBackground(Void... params) {
    return registerMultipartCall();
    }

    private String registerMultipartCall() {
    String responseString = null;
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("URL"); //UPLOAD URL
    try {
    AndroidMultiPartEntity entity = new AndroidMultiPartEntity(new AndroidMultiPartEntity.ProgressListener() {
    @Override
    public void transferred(long num) {
    }
    });

    File sourceFile = new File(filePath);
    File sourceFile2 = new File(filePath);

    entity.addPart("images[0]", new FileBody(sourceFile));
    entity.addPart("images[1]", new FileBody(sourceFile2));
    //Do your stuff multiple files

    entity.addPart("file_type", new StringBody("image");
    entity.addPart("file_form", new StringBody("post");

    httppost.addHeader("Accept","application/json");
    httppost.addHeader("Content-Type", "multipart/form-data");
    httppost.addHeader("Authorization", "Bearer " + sharedPreferencesManager.retreiveString(AppText.ACCESS_TOKEN));


    httppost.setEntity(entity);

    // Making server call
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity r_entity = response.getEntity();

    int statusCode = response.getStatusLine().getStatusCode();
    if (statusCode == 200) {
    // Server response
    statusCode = 200;
    responseString = EntityUtils.toString(r_entity);
    } else {
    statusCode = 200;
    responseString = "Error occurred! Http Status Code: " + statusCode;
    }

    } catch (ClientProtocolException e) {
    responseString = e.toString();
    } catch (IOException e) {
    responseString = e.toString();
    }

    return responseString;

    }

    @Override
    protected void onPostExecute(String result) {
    hideProgressDialog();

    }

5.调用异步

  new registerCall().execute();

关于android - 如何在 Android Volley 库中使用 MultiPart 上传图像文件数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47994118/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com