如何在 android 中使用改装将多个图像上传到单个键

How To Upload Multiple Image to single key using retrofit in android

我是 android 的新手,我遇到了这个问题,如有任何帮助,我们将不胜感激

这是我的网络服务密钥

   @Part MultipartBody.Part image1[]

我试过这样

    Map<String,MultipartBody.Part> list = new HashMap<>();
    MultipartBody.Part[] imageParts = new MultipartBody.Part[10];
    for(int i=0;i<=mClipData.getItemCount();i++) {
        File file = new File(String.valueOf(mArrayUri.get(i)));
        final RequestBody requestBody1 = RequestBody.create(MediaType.parse("image/*"), file);
        imageParts[i] = MultipartBody.Part.createFormData("image8", file.getName(), requestBody1);
        Webservice.getClient().addProduct(RequestBody.create(okhttp3.MediaType.parse("text/plain"), mAuth.getCurrentUser().getPhoneNumber()),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), ItemName.getText().toString()),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), PriseCoin.getText().toString()),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), cat),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), ItemDescription.getText().toString()),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), ItemDetails.getText().toString()),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), di),
                RequestBody.create(okhttp3.MediaType.parse("text/plain"), ta), imageParts[i]
        ).enqueue(new Callback<addproduct>() {
            @Override
            public void onResponse(Call<addproduct> call, Response<addproduct> response) {
                
                Toast.makeText(AddProduct.this, "sucess"+response.body().getMsg(), Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onFailure(Call<addproduct> call, Throwable t) {
            }
        });
    }

How To Upload Multiple Image to single key using retrofit in android

private fun getParts(): ArrayList<MultipartBody.Part> {
        val parts = arrayListOf<MultipartBody.Part>()
        if (baseAdapter?.itemCount ?: 0 > 0) {
            for ((i, item) in baseAdapter?.list?.withIndex()!!) {
                parts.add(prepareParts("images[$i]", (Uri.parse(item?.uri) ?: "") as Uri))
            }

        }
        return parts
    }


    private fun prepareParts(name: String, fileUri: Uri): MultipartBody.Part {
        val file = File(fileUri.path)
        val requestBody = RequestBody.create(MediaType.parse("*/*"), file)
        return MultipartBody.Part.createFormData(name, file.name, requestBody)
    }

并且在使参数获取每个图像的一部分时

Map<String,MultipartBody.Part> list = new HashMap<>();
ArrayList<MultipartBody.Part> parts = getParts()// this will have all images file name "images[0]": filename... and so..on

你的 Retrofit 界面

    @Multipart
    @POST("your_file")
    fun pushMulipleImages(@QueryMap param: HashMap<String, String>,@Part parts: List<MultipartBody.Part>)

我的密钥是像这样的 multipleimage[],它在这个

中运行良好
  VolleyMultipartRequest volleyMultipartRequest = new 
   
  VolleyMultipartRequest(com.android.volley.Request.Method.POST, url,
                

  new com.android.volley.Response.Listener<NetworkResponse>() {
                    
  @Override                   
  public void onResponse(NetworkResponse response) {               
     try {                           
       Log.e("respps", "onResponse: " + response);
                           
       Toast.makeText(PostFormActivity.this,"UploadSucessfully", Toast.LENGTH_SHORT).show();

                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.e("respps", "onResponse:Exp " + e.getMessage());
                            Toast.makeText(PostFormActivity.this, "Upload Fail", Toast.LENGTH_SHORT).show();

                        }
                      
                    }
                },
                new com.android.volley.Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        
                        Log.e("ERROR", error.toString());
                        Log.e("respps", "onResponse:Err " + error);

                        Toast.makeText(PostFormActivity.this, "Upload Fail Try After Some Time", Toast.LENGTH_SHORT).show();

                    }
                }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("id", id);
                params.put("id2", id2);
                params.put("id3",id3);
                params.put("id4", id4);

                return params;
            }

            @Override
            protected Map<String, DataPart> getByteData() {
                Map<String, DataPart> params = new HashMap<>();
                long imagename = System.currentTimeMillis();
                params.put("banner", new DataPart(imagename + ".png", getFileDataFromDrawable(img)));

                for (int i = 0; i < imagesEncodedList1.size(); i++) {
                    params.put("multipleimage" + "[" + i + "]", new DataPart(imagename + ".png", getFileDataFromDrawable(imagesEncodedList1.get(i))));
                }
                return params;
            }
        };
        {
            int socketTimeout = 60000;
            RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            volleyMultipartRequest.setRetryPolicy(policy);
            RequestQueue requestQueue = Volley.newRequestQueue(PostFormActivity.this);
            requestQueue.add(volleyMultipartRequest);

        }

齐发多部分请求

    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;


public VolleyMultipartRequest(int method, String url,
                              Response.Listener<NetworkResponse> listener,
                              Response.ErrorListener errorListener) {
    super(method, url, errorListener);
    this.mListener = listener;

    this.mErrorListener = errorListener;
}

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

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

    DataPart(String name) {
        fileName = name;
        // content = data;
    }

    public DataPart(String s, byte[] fileDataFromDrawable) {
        fileName = s;
        content=fileDataFromDrawable;
    }

    String getFileName() {
        return fileName;
    }

    byte[] getContent() {
        return content;
    }

    String getType() {
        return type;
    }

}
}

从 drawable 获取文件数据

    public byte[] getFileDataFromDrawable(Bitmap bitmap) {
    ByteArrayOutputStream byteArrayOutputStream = new 
    ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 80, 
    byteArrayOutputStream);
    return byteArrayOutputStream.toByteArray();
    } 

这是我的 onActivityResult

      if (requestCode == 44 && resultCode == RESULT_OK && data != null && data.getData() != null) {
       String[] filePathColumn = { MediaStore.Images.Media.DATA };
            imagesEncodedList = new ArrayList<String>();
            imagesEncodedList1 = new ArrayList<Bitmap>();
            if(data.getClipData() != null) {
                    int count = data.getClipData().getItemCount();
                    for(int i = 0; i < count; i++) {
                        Uri imageUri = data.getClipData().getItemAt(i).getUri();
                       

                        Cursor cursor = getContentResolver().query(data.getClipData().getItemAt(i).getUri(), filePathColumn, null, null, null);
                        // Move to first row
                        cursor.moveToFirst();

                        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                        imageEncoded  = cursor.getString(columnIndex);
                        imagesEncodedList.add(imageEncoded);
                        
                        try {
                            Bitmap bitmap = MediaStore
                                    .Images
                                    .Media
                                    .getBitmap(PostFormActivity.this.getContentResolver(), data.getClipData().getItemAt(i).getUri());
                            imagesEncodedList1.add(bitmap);
                            Log.d("TAG", "onActivityResult:trybitmap "+bitmap);
                        }
                        catch (Exception e){
                            e.printStackTrace();
                          
                        }
                        cursor.close();
                        //do what do you want to do
                    }
                }
            }

Select 来自画廊的多张图片

    private void selectMultipleImage() {
    Intent intent = new Intent(Intent.ACTION_PICK, 
    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    startActivityForResult(Intent.createChooser(intent, "Select 
    images"),44);
     }